Compare commits

..
Author SHA1 Message Date
Vanessa ea0b88f1b2 fix maints chapel access 2026-06-24 19:59:52 -05:00
93 changed files with 218 additions and 1534 deletions
-9
View File
@@ -12,21 +12,12 @@ jobs:
- name: Setup submodule
run: |
git submodule update --init --recursive
pushd RobustToolbox/Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Pull engine updates
uses: space-wizards/submodule-dependency@v0.1.5
- name: Update Engine Submodules
run: |
cd RobustToolbox/
git submodule update --init --recursive
pushd Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
with:
+1 -9
View File
@@ -24,11 +24,7 @@ jobs:
- name: Setup Submodule
run: |
git submodule update --init --recursive
pushd RobustToolbox/Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Pull engine updates
uses: space-wizards/submodule-dependency@v0.1.5
@@ -36,10 +32,6 @@ jobs:
run: |
cd RobustToolbox/
git submodule update --init --recursive
pushd Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
-8
View File
@@ -24,10 +24,6 @@ jobs:
- name: Setup Submodule
run: |
git submodule update --init --recursive
pushd RobustToolbox/Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Pull engine updates
uses: space-wizards/submodule-dependency@v0.1.5
@@ -36,10 +32,6 @@ jobs:
run: |
cd RobustToolbox/
git submodule update --init --recursive
pushd Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
-7
View File
@@ -20,7 +20,6 @@ jobs:
- uses: actions/checkout@v4.2.2
with:
submodules: 'recursive'
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
with:
@@ -31,12 +30,6 @@ jobs:
cd RobustToolbox
git fetch --depth=1
- name: Get Engine Tag
run: |
cd RobustToolbox/Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
- name: Install dependencies
run: dotnet restore
-8
View File
@@ -39,10 +39,6 @@ jobs:
- name: Setup Submodule
run: |
git submodule update --init --recursive
pushd RobustToolbox/Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Pull engine updates
uses: space-wizards/submodule-dependency@v0.1.5
@@ -51,10 +47,6 @@ jobs:
run: |
cd RobustToolbox/
git submodule update --init --recursive
pushd Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
-8
View File
@@ -17,20 +17,12 @@ jobs:
- name: Setup submodule
run: |
git submodule update --init --recursive
pushd RobustToolbox/Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Pull engine updates
uses: space-wizards/submodule-dependency@v0.1.5
- name: Update Engine Submodules
run: |
cd RobustToolbox/
git submodule update --init --recursive
pushd Lidgren.Network/Lidgren.Network
git fetch
git checkout 726dd552a4b104fb2b701848705f1250a073f060
popd
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
with:
@@ -1,16 +1,13 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.Medical.CrewMonitoring"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:crewMonitoring="clr-namespace:Content.Client._DV.CrewMonitoring"
Title="{Loc crew-monitoring-ui-title}"
Resizable="False"
SetSize="1210 700"
MinSize="1210 700">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal" VerticalExpand="True" HorizontalExpand="True">
<ui:CrewMonitoringNavMapControl Name="NavMap" HorizontalExpand="True" VerticalExpand="True" Margin="5 20" Visible="False" />
<crewMonitoring:CrewMonitoringShuttleControl Name="ShuttleMap" HorizontalExpand="True" VerticalExpand="True" Margin="5 20" Visible="False" />
<ui:CrewMonitoringNavMapControl Name="NavMap" HorizontalExpand="True" VerticalExpand="True" Margin="5 20"/>
<BoxContainer Orientation="Vertical" Margin="0 0 10 0">
<controls:StripeBack>
<PanelContainer>
@@ -5,7 +5,6 @@ using Content.Client.Pinpointer.UI;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Shared.Medical.SuitSensor;
using Content.Shared.Station; // DeltaV - crew monitoring radar
using Content.Shared.StatusIcon;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
@@ -28,7 +27,6 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly SharedTransformSystem _transformSystem;
private readonly SpriteSystem _spriteSystem;
private readonly SharedStationSystem _station; // DeltaV - crew monitoring radar
private NetEntity? _trackedEntity;
private bool _tryToScrollToListFocus;
@@ -41,10 +39,8 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
_transformSystem = _entManager.System<SharedTransformSystem>();
_spriteSystem = _entManager.System<SpriteSystem>();
_station = _entManager.System<SharedStationSystem>(); // DeltaV - crew monitoring radar
NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap;
ShuttleMap.NavMap = NavMap; // DeltaV - crew monitoring radar
}
public void Set(string stationName, EntityUid? mapUid)
@@ -54,10 +50,8 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
if (_entManager.TryGetComponent<TransformComponent>(mapUid, out var xform))
NavMap.MapUid = xform.GridUid;
// Begin DeltaV - handle navmap visibility based on current position
// else
// NavMap.Visible = false;
// End DeltaV - handle navmap visibility based on current position
else
NavMap.Visible = false;
StationName.AddStyleClass("LabelBig");
StationName.Text = stationName;
@@ -68,19 +62,6 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
{
base.FrameUpdate(args);
// Begin DeltaV - handle navmap visibility based on current position
if (_station.GetOwningStation(ShuttleMap.Owner) is not null)
{
NavMap.Visible = true;
ShuttleMap.Visible = false;
}
else
{
NavMap.Visible = false;
ShuttleMap.Visible = true;
}
// End DeltaV - handle navmap visibility based on current position
if (_tryToScrollToListFocus)
TryToScrollToFocus();
}
@@ -88,7 +69,6 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
public void ShowSensors(List<SuitSensorStatus> sensors, EntityUid monitor, EntityCoordinates? monitorCoords)
{
ClearOutDatedData();
ShuttleMap.Owner = monitor; // DeltaV - crew monitoring radar
// No server label
if (sensors.Count == 0)
@@ -324,7 +304,7 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
jobContainer.AddChild(jobLabel);
// Add user coordinates to the navmap
if (coordinates != null && _blipTexture != null) // DeltaV - don't filter the navmap visibility
if (coordinates != null && NavMap.Visible && _blipTexture != null)
{
NavMap.TrackedEntities.TryAdd(sensor.SuitSensorUid,
new NavMapBlip
@@ -56,8 +56,8 @@ public partial class NavMapControl : MapGridControl
// Constants
protected float UpdateTime = 1.0f;
public float MaxSelectableDistance = 10f; // DeltaV - accessible to CrewMonitoringShuttleControl
public float MinDragDistance = 5f; // DeltaV - accessible to CrewMonitoringShuttleControl
protected float MaxSelectableDistance = 10f;
protected float MinDragDistance = 5f;
protected static float MinDisplayedRange = 8f;
protected static float MaxDisplayedRange = 128f;
protected static float DefaultDisplayedRange = 48f;
@@ -193,13 +193,6 @@ public partial class NavMapControl : MapGridControl
_recenter.Disabled = false;
}
// Begin DeltaV - we need access to that from outside
public void TrackEntity(NetEntity? entity)
{
TrackedEntitySelectedAction?.Invoke(entity);
}
// End DeltaV - we need access to that from outside
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
@@ -1,180 +0,0 @@
using System.Numerics;
using Content.Client.Pinpointer.UI;
using Content.Client.Shuttles.UI;
using Content.Shared.Shuttles.Components;
using Content.Shared.Shuttles.Systems;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Shared.Input;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
namespace Content.Client._DV.CrewMonitoring;
public sealed class CrewMonitoringShuttleControl : BaseShuttleControl
{
[Dependency] private readonly IMapManager _mapManager = default!;
private readonly SharedShuttleSystem _shuttles;
private readonly SharedTransformSystem _transform;
public EntityUid? Owner;
public NavMapControl? NavMap;
private List<Entity<MapGridComponent>> _grids = new();
public CrewMonitoringShuttleControl() : base(64f, 256f, 256f)
{
_shuttles = EntManager.System<SharedShuttleSystem>();
_transform = EntManager.System<SharedTransformSystem>();
}
protected override void Draw(DrawingHandleScreen handle)
{
base.Draw(handle);
DrawBacking(handle);
DrawCircles(handle);
if (Owner is not { } owner || NavMap is not { } navMap)
return;
var xformQuery = EntManager.GetEntityQuery<TransformComponent>();
var fixturesQuery = EntManager.GetEntityQuery<FixturesComponent>();
var bodyQuery = EntManager.GetEntityQuery<PhysicsComponent>();
var iffQuery = EntManager.GetEntityQuery<IFFComponent>();
if (!xformQuery.TryGetComponent(owner, out var xform)
|| xform.MapID == MapId.Nullspace)
{
return;
}
var coordinates = new EntityCoordinates(owner, Vector2.Zero);
var mapPos = _transform.ToMapCoordinates(coordinates);
var ourEntRot = Angle.Zero;
var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot);
Matrix3x2.Invert(ourEntMatrix, out var worldToShuttle);
var shuttleToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
var worldToView = worldToShuttle * shuttleToView;
var viewBounds = new Box2Rotated(new Box2(-WorldRange, -WorldRange, WorldRange, WorldRange).Translated(mapPos.Position), ourEntRot, mapPos.Position);
var viewAABB = viewBounds.CalcBoundingBox();
_grids.Clear();
_mapManager.FindGridsIntersecting(xform.MapID, new Box2(mapPos.Position - MaxRadarRangeVector, mapPos.Position + MaxRadarRangeVector), ref _grids, approx: true, includeMap: false);
foreach (var grid in _grids)
{
if (!fixturesQuery.HasComponent(grid))
continue;
var body = bodyQuery.GetComponent(grid);
iffQuery.TryComp(grid, out var iff);
if (!_shuttles.CanDraw(grid, body, iff))
continue;
var curGridToWorld = _transform.GetWorldMatrix(grid);
var curGridToView = curGridToWorld * worldToShuttle * shuttleToView;
var gridAABB = curGridToWorld.TransformBox(grid.Comp.LocalAABB);
if (!gridAABB.Intersects(viewAABB))
continue;
var labelColor = _shuttles.GetIFFColor(grid, self: false, iff);
DrawGrid(handle, curGridToView, grid, labelColor);
}
var curTime = Timing.RealTime;
var blinkFrequency = 1f / 1f;
var lit = curTime.TotalSeconds % blinkFrequency > blinkFrequency / 2f;
var box = SizeBox;
foreach (var (coord, value) in navMap.TrackedCoordinates)
{
if (!lit || !value.Visible)
continue;
var blipPos = _transform.ToMapCoordinates(coord);
if (mapPos.MapId == MapId.Nullspace)
continue;
handle.DrawCircle(Vector2.Clamp(Vector2.Transform(blipPos.Position, worldToView), box.TopLeft, box.BottomRight), float.Sqrt(MinimapScale) * 2f, value.Color);
}
foreach (var blip in navMap.TrackedEntities.Values)
{
if (blip.Blinks && !lit)
continue;
var blipPos = _transform.ToMapCoordinates(blip.Coordinates);
if (mapPos.MapId == MapId.Nullspace)
continue;
handle.DrawCircle(Vector2.Clamp(Vector2.Transform(blipPos.Position, worldToView), box.TopLeft, box.BottomRight), float.Sqrt(MinimapScale) * 2f, blip.Color);
}
}
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
if (Owner is not { } owner || NavMap is null)
return;
if (!EntManager.TryGetComponent<TransformComponent>(owner, out var xform) || xform.MapID == MapId.Nullspace)
{
return;
}
var ourEntRot = Angle.Zero;
var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot);
Matrix3x2.Invert(ourEntMatrix, out var worldToShuttle);
var shuttleToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
var worldToView = worldToShuttle * shuttleToView;
Matrix3x2.Invert(worldToView, out var viewToWorld);
if (args.Function == EngineKeyFunctions.UIClick)
{
if (NavMap.TrackedEntities.Count == 0)
return;
if ((StartDragPosition - args.PointerLocation.Position).Length() > NavMap.MinDragDistance)
return;
var localPosition = args.PointerLocation.Position - GlobalPixelPosition;
var worldPosition = Vector2.Transform(localPosition, viewToWorld);
var closestEntity = NetEntity.Invalid;
var closestDistance = float.PositiveInfinity;
foreach (var (currentEntity, blip) in NavMap.TrackedEntities)
{
if (!blip.Selectable)
continue;
var currentDistance = (_transform.ToMapCoordinates(blip.Coordinates).Position - worldPosition).Length();
if (closestDistance < currentDistance || currentDistance * MinimapScale > NavMap.MaxSelectableDistance)
continue;
closestEntity = currentEntity;
closestDistance = currentDistance;
}
if (closestDistance > NavMap.MaxSelectableDistance || !closestEntity.IsValid())
return;
NavMap.TrackEntity(closestEntity);
}
else if (args.Function == EngineKeyFunctions.UIRightClick)
{
NavMap.TrackEntity(null);
}
}
}
@@ -1,17 +0,0 @@
using Content.Shared.Labels.Components;
namespace Content.Client._DV.Silicons;
public static class NameHelpers
{
extension(IEntityManager self)
{
public string PaperName(EntityUid paper)
{
if (self.TryGetComponent<LabelComponent>(paper, out var label) && label.CurrentLabel is { } labelText)
return labelText;
return self.GetComponent<MetaDataComponent>(paper).EntityName;
}
}
}
@@ -1,144 +0,0 @@
using System.IO;
using Content.Shared._DV.Silicons;
using Content.Shared.Fax;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
using Robust.Shared.Containers;
namespace Content.Client._DV.Silicons;
[UsedImplicitly]
public sealed class StationAiFaxBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
[Dependency] private readonly IFileDialogManager _fileDialogManager = default!;
private StationAiFaxWindow? _window;
private List<StationAiFaxPageWindow> _windows = new();
private bool _dialogIsOpen;
protected override void Open()
{
base.Open();
_window = this.CreateWindow<StationAiFaxWindow>();
_window.FileButtonPressed += OnFileButtonPressed;
_window.BlankButtonPressed += OnBlankButtonPressed;
_window.OpenSendWindowPressed += OnOpenSendWindowPressed;
_window.ExaminePressed += OnExaminePressed;
_window.ShredPressed += OnShredPressed;
_window.DuplicatePressed += OnDuplicatePressed;
UpdateFaxes(EntMan.System<SharedContainerSystem>().EnsureContainer<Container>(Owner, StationAiFaxComponent.Container, out _));
}
private async void OnFileButtonPressed()
{
if (_dialogIsOpen)
return;
_dialogIsOpen = true;
var filters = new FileDialogFilters(new FileDialogFilters.Group("txt"));
await using var file = await _fileDialogManager.OpenFile(filters, FileAccess.Read);
_dialogIsOpen = false;
if (_window == null || _window.Disposed || file == null)
{
return;
}
using var reader = new StreamReader(file);
var firstLine = await reader.ReadLineAsync();
string? label = null;
var content = await reader.ReadToEndAsync();
if (firstLine is { })
{
if (firstLine.StartsWith('#'))
{
label = firstLine[1..].Trim();
}
else
{
content = firstLine + "\n" + content;
}
}
SendMessage(new FaxFileMessage(
label?[..Math.Min(label.Length, FaxFileMessageValidation.MaxLabelSize)],
content[..Math.Min(content.Length, FaxFileMessageValidation.MaxContentSize)],
false));
}
private void OnBlankButtonPressed()
{
SendMessage(new FaxFileMessage(null, string.Empty, false));
}
private void OnOpenSendWindowPressed(EntityUid entity)
{
var window = new StationAiFaxPageWindow(entity, EntMan);
_windows.Add(window);
window.RefreshButtonPressed += OnRefreshButtonPressed;
window.PeerSelected += OnPeerSelected;
window.SendButtonPressed += OnSendDocument;
if (UiSystem.TryGetUiState<FaxUiState>(Owner, UiKey, out var state))
{
window.UpdateState(state);
}
window.OpenCentered();
}
private void OnSendDocument(EntityUid entity)
{
SendMessage(new StationAiFaxSendMessage(EntMan.GetNetEntity(entity)));
}
private void OnExaminePressed(EntityUid entity)
{
SendPredictedMessage(new StationAiFaxExamineMessage(EntMan.GetNetEntity(entity)));
}
private void OnShredPressed(EntityUid entity)
{
SendPredictedMessage(new StationAiFaxShredMessage(EntMan.GetNetEntity(entity)));
}
private void OnDuplicatePressed(EntityUid entity)
{
SendPredictedMessage(new StationAiFaxDuplicateMessage(EntMan.GetNetEntity(entity)));
}
private void OnRefreshButtonPressed()
{
SendMessage(new FaxRefreshMessage());
}
private void OnPeerSelected(string address)
{
SendMessage(new FaxDestinationMessage(address));
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not FaxUiState cast)
return;
_window?.UpdateState(cast);
foreach (var window in _windows)
{
window.UpdateState(cast);
}
}
public void UpdateFaxes(Container container)
{
_window?.UpdateFaxes(container);
}
}
@@ -1,14 +0,0 @@
<PanelContainer xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client._DV.UserInterfaces"
xmlns:xe="clr-namespace:Content.Client.UserInterface.XamlExtensions"
StyleClasses="PanelLight"
HorizontalExpand="True">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8">
<Label Name="PaperName" HorizontalExpand="True" />
<ui:IconButton Name="Shred" StyleClasses="OpenRight" Icon="{xe:Tex '/Textures/Interface/shredder.svg.192dpi.png'}" />
<ui:IconButton Name="Duplicate" StyleClasses="OpenBoth" Icon="{xe:Tex '/Textures/Interface/files.svg.192dpi.png'}" />
<ui:IconButton Name="Examine" StyleClasses="OpenBoth" Icon="{xe:Tex '/Textures/Interface/eye.svg.192dpi.png'}" />
<ui:IconButton Name="Send" StyleClasses="OpenLeft" Icon="{xe:Tex '/Textures/Interface/send.svg.192dpi.png'}" />
</BoxContainer>
</PanelContainer>
@@ -1,27 +0,0 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._DV.Silicons;
[GenerateTypedNameReferences]
public sealed partial class StationAiFaxItem : PanelContainer
{
public string? Text { get => PaperName.Text; set => PaperName.Text = value; }
public bool CanSend { get => !Duplicate.Disabled; set => Duplicate.Disabled = !value; }
public event Action? ShredPressed;
public event Action? DuplicatePressed;
public event Action? ExaminePressed;
public event Action? SendPressed;
public StationAiFaxItem()
{
RobustXamlLoader.Load(this);
Shred.OnPressed += _ => ShredPressed?.Invoke();
Duplicate.OnPressed += _ => DuplicatePressed?.Invoke();
Examine.OnPressed += _ => ExaminePressed?.Invoke();
Send.OnPressed += _ => SendPressed?.Invoke();
}
}
@@ -1,64 +0,0 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'fax-machine-ui-page-window'}"
MinSize="380 220">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Orientation="Vertical" Margin="8">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'fax-machine-ui-sending'}"
VerticalAlignment="Bottom"
HorizontalExpand="True" />
<Label Name="SendingLabel"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Align="Right"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'fax-machine-ui-from'}"
VerticalAlignment="Bottom"
HorizontalExpand="True" />
<Label Name="FromLabel"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Align="Right"/>
</BoxContainer>
<BoxContainer
Orientation="Horizontal">
<Label Text="{Loc 'fax-machine-ui-to'}"
VerticalAlignment="Bottom"
HorizontalExpand="True"/>
<BoxContainer Orientation="Horizontal">
<OptionButton Name="PeerSelector"
StyleClasses="OpenRight" />
<Button StyleClasses="OpenLeft"
Name="RefreshButton"
ToolTip="{Loc 'fax-machine-ui-refresh-button'}">
<TextureButton
MouseFilter="Ignore"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Scale="0.9 0.9"
StyleClasses="RefreshButton" />
</Button>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</PanelContainer>
<BoxContainer Orientation="Horizontal" SeparationOverride="8" Margin="8">
<Button Name="SendButton"
Text="{Loc 'fax-machine-ui-send-button'}"
HorizontalExpand="True"
Disabled="True" />
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
@@ -1,70 +0,0 @@
using System.Linq;
using Content.Client.UserInterface.Controls;
using Content.Shared.Fax;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._DV.Silicons;
[GenerateTypedNameReferences]
public sealed partial class StationAiFaxPageWindow : FancyWindow
{
public event Action? RefreshButtonPressed;
public event Action<string>? PeerSelected;
public event Action<EntityUid>? SendButtonPressed;
public StationAiFaxPageWindow(EntityUid uid, IEntityManager entityManager)
{
RobustXamlLoader.Load(this);
SendingLabel.Text = entityManager.PaperName(uid);
RefreshButton.OnPressed += _ => RefreshButtonPressed?.Invoke();
SendButton.OnPressed += _ => SendButtonPressed?.Invoke(uid);
PeerSelector.OnItemSelected += args =>
PeerSelected?.Invoke((string) args.Button.GetItemMetadata(args.Id)!);
}
public void UpdateState(FaxUiState state)
{
SendButton.Disabled = !state.CanSendCooldown;
FromLabel.Text = state.DeviceName;
if (state.AvailablePeers.Count == 0)
{
PeerSelector.AddItem(Loc.GetString("fax-machine-ui-no-peers"));
PeerSelector.Disabled = true;
}
if (PeerSelector.Disabled && state.AvailablePeers.Count != 0)
{
PeerSelector.Clear();
PeerSelector.Disabled = false;
}
// always must be selected destination
if (string.IsNullOrEmpty(state.DestinationAddress) && state.AvailablePeers.Count != 0)
{
PeerSelected?.Invoke(state.AvailablePeers.First().Key);
return;
}
if (state.AvailablePeers.Count != 0)
{
PeerSelector.Clear();
foreach (var (address, name) in state.AvailablePeers)
{
var id = AddPeerSelect(name, address);
if (address == state.DestinationAddress)
PeerSelector.Select(id);
}
}
}
private int AddPeerSelect(string name, string address)
{
PeerSelector.AddItem(name);
PeerSelector.SetItemMetadata(PeerSelector.ItemCount - 1, address);
return PeerSelector.ItemCount - 1;
}
}
@@ -1,37 +0,0 @@
using Content.Shared._DV.Silicons;
using Content.Shared.Fax;
using Robust.Client.GameObjects;
using Robust.Shared.Containers;
namespace Content.Client._DV.Silicons;
public sealed class StationAiFaxSystem : SharedStationAiFaxSystem
{
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StationAiFaxComponent, EntRemovedFromContainerMessage>(OnRemoved);
}
protected override void OnInserted(Entity<StationAiFaxComponent> ent, ref EntInsertedIntoContainerMessage args)
{
base.OnInserted(ent, ref args);
if (!_userInterface.TryGetOpenUi<StationAiFaxBoundUserInterface>(ent.Owner, FaxUiKey.Key, out var bui))
return;
bui.UpdateFaxes(_container.EnsureContainer<Container>(ent, StationAiFaxComponent.Container, out _));
}
private void OnRemoved(Entity<StationAiFaxComponent> ent, ref EntRemovedFromContainerMessage args)
{
if (!_userInterface.TryGetOpenUi<StationAiFaxBoundUserInterface>(ent.Owner, FaxUiKey.Key, out var bui))
return;
bui.UpdateFaxes(_container.EnsureContainer<Container>(ent, StationAiFaxComponent.Container, out _));
}
}
@@ -1,29 +0,0 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'fax-machine-ui-window'}"
MinSize="500 600">
<BoxContainer Orientation="Vertical" Name="NoFaxes" HorizontalAlignment="Center" VerticalAlignment="Center" SeparationOverride="8">
<Label StyleClasses="PlaceholderText" Text="{Loc 'fax-machine-ui-no-faxes'}" Align="Center" />
<BoxContainer Orientation="Vertical" HorizontalAlignment="Center">
<Button Name="NoFaxesBlank" Text="{Loc 'fax-machine-ui-add-blank-file'}" HorizontalExpand="True" StyleClasses="OpenLeft" />
<Button Name="NoFaxesUpload" Text="{Loc 'fax-machine-ui-upload-file'}" HorizontalExpand="True" StyleClasses="OpenRight" />
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Vertical" Name="YesFaxes" HorizontalExpand="True" VerticalExpand="True">
<PanelContainer StyleClasses="PanelDark" VerticalExpand="True" HorizontalExpand="True">
<ScrollContainer VerticalExpand="True" HorizontalExpand="True">
<BoxContainer Name="FaxList" Margin="8" VerticalAlignment="Top" HorizontalExpand="True" SeparationOverride="8" Orientation="Vertical" />
</ScrollContainer>
</PanelContainer>
<BoxContainer Orientation="Horizontal" SeparationOverride="8" Margin="8">
<Button Name="YesFaxesBlank" Text="{Loc 'fax-machine-ui-add-blank-file'}" HorizontalAlignment="Center" />
<Button Name="YesFaxesUpload" Text="{Loc 'fax-machine-ui-upload-file'}" HorizontalAlignment="Center" />
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
@@ -1,92 +0,0 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Fax;
using Content.Shared.Labels.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._DV.Silicons;
[GenerateTypedNameReferences]
public sealed partial class StationAiFaxWindow : FancyWindow
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public event Action? BlankButtonPressed;
public event Action? FileButtonPressed;
public event Action<EntityUid>? OpenSendWindowPressed;
public event Action<EntityUid>? ExaminePressed;
public event Action<EntityUid>? ShredPressed;
public event Action<EntityUid>? DuplicatePressed;
public bool CanSend
{
get;
set
{
if (field == value)
return;
field = value;
foreach (var item in FaxList.Children)
{
var castItem = (StationAiFaxItem)item;
castItem.CanSend = value;
}
NoFaxesBlank.Disabled = !value;
NoFaxesUpload.Disabled = !value;
YesFaxesBlank.Disabled = !value;
YesFaxesUpload.Disabled = !value;
}
}
public StationAiFaxWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
NoFaxesBlank.OnPressed += _ => BlankButtonPressed?.Invoke();
NoFaxesUpload.OnPressed += _ => FileButtonPressed?.Invoke();
YesFaxesBlank.OnPressed += _ => BlankButtonPressed?.Invoke();
YesFaxesUpload.OnPressed += _ => FileButtonPressed?.Invoke();
}
public void UpdateFaxes(Robust.Shared.Containers.Container container)
{
FaxList.RemoveAllChildren();
foreach (var item in container.ContainedEntities)
{
var page = new StationAiFaxItem
{
Text = _entityManager.TryGetComponent<LabelComponent>(item, out var label) &&
label.CurrentLabel is { } labelText
? labelText
: _entityManager.GetComponent<MetaDataComponent>(item).EntityName,
CanSend = CanSend,
};
FaxList.AddChild(page);
page.ExaminePressed += () => ExaminePressed?.Invoke(item);
page.ShredPressed += () => ShredPressed?.Invoke(item);
page.DuplicatePressed += () => DuplicatePressed?.Invoke(item);
page.SendPressed += () => OpenSendWindowPressed?.Invoke(item);
}
if (container.ContainedEntities.Count == 0)
{
YesFaxes.Visible = false;
NoFaxes.Visible = true;
}
else
{
YesFaxes.Visible = true;
NoFaxes.Visible = false;
}
}
public void UpdateState(FaxUiState state)
{
CanSend = state.CanSendCooldown;
}
}
@@ -1,7 +0,0 @@
<Button xmlns="https://spacestation14.io">
<TextureRect Name="TextureRect"
TextureScale="0.5 0.5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="KeepCentered"/>
</Button>
@@ -1,17 +0,0 @@
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._DV.UserInterfaces;
[GenerateTypedNameReferences]
public sealed partial class IconButton : Button
{
public Texture? Icon { get => TextureRect.Texture; set => TextureRect.Texture = value; }
public IconButton()
{
RobustXamlLoader.Load(this);
}
}
@@ -24,7 +24,7 @@ public sealed class WizdenContentFreeze
var protoMan = server.ProtoMan;
var recipesCount = protoMan.Count<FoodRecipePrototype>();
var recipesLimit = 266; // DeltaV - was 218
var recipesLimit = 269; // DeltaV - was 218
if (recipesCount > recipesLimit)
{
@@ -184,11 +184,6 @@ public sealed class MetabolizerSystem : SharedMetabolizerSystem
var rate = entry.MetabolismRate * group.MetabolismRateModifier;
// BEGIN DeltaV - fix FixedPoint2 truncation flooring low rateModifiers to zero
if (rate == FixedPoint2.Zero && entry.MetabolismRate > FixedPoint2.Zero && group.MetabolismRateModifier > 0f)
rate = FixedPoint2.Epsilon;
// END DeltaV
// Remove $rate, as long as there's enough reagent there to actually remove that much
mostToRemove = FixedPoint2.Clamp(rate, 0, quantity);
+8 -13
View File
@@ -5,7 +5,6 @@ using Content.Server.DeviceNetwork.Systems;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.Tools;
using Content.Shared._DV.Fax; // DeltaV - fax
using Content.Shared._DV.Pager; // DeltaV - pagers
using Content.Shared.Administration.Logs;
using Content.Shared.Containers.ItemSlots;
@@ -91,10 +90,10 @@ public sealed class FaxSystem : EntitySystem
{
base.Update(frameTime);
var query = EntityQueryEnumerator<FaxMachineComponent>();
while (query.MoveNext(out var uid, out var fax)) // DeltaV - faxes aren't necessarily powered
var query = EntityQueryEnumerator<FaxMachineComponent, ApcPowerReceiverComponent>();
while (query.MoveNext(out var uid, out var fax, out var receiver))
{
if (TryComp<ApcPowerReceiverComponent>(uid, out var receiver) && !receiver.Powered) // DeltaV - faxes aren't necessarily powered
if (!receiver.Powered)
continue;
ProcessPrintingAnimation(uid, frameTime, fax);
@@ -393,7 +392,7 @@ public sealed class FaxSystem : EntitySystem
var canCopy = isPaperInserted &&
component.SendTimeoutRemaining <= 0 &&
component.InsertingTimeRemaining <= 0;
var state = new FaxUiState(component.FaxName, component.KnownFaxes, canSend, canCopy, isPaperInserted, component.DestinationFaxAddress, component.SendTimeoutRemaining <= 0); // DeltaV - AI fax
var state = new FaxUiState(component.FaxName, component.KnownFaxes, canSend, canCopy, isPaperInserted, component.DestinationFaxAddress);
_userInterface.SetUiState(uid, FaxUiKey.Key, state);
}
@@ -462,7 +461,7 @@ public sealed class FaxSystem : EntitySystem
/// Copies the paper in the fax. A timeout is set after copying,
/// which is shared by the send button.
/// </summary>
public void Copy(EntityUid uid, FaxMachineComponent? component, BoundUserInterfaceMessage args, EntityUid? item = null) // DeltaV - station AI fax
public void Copy(EntityUid uid, FaxMachineComponent? component, FaxCopyMessage args)
{
if (!Resolve(uid, ref component))
return;
@@ -470,7 +469,7 @@ public sealed class FaxSystem : EntitySystem
if (component.SendTimeoutRemaining > 0)
return;
var sendEntity = item ?? component.PaperSlot.Item; // DeltaV - station AI fax
var sendEntity = component.PaperSlot.Item;
if (sendEntity == null)
return;
@@ -512,7 +511,7 @@ public sealed class FaxSystem : EntitySystem
/// Sends message to addressee if paper is set and a known fax is selected
/// A timeout is set after sending, which is shared by the copy button.
/// </summary>
public void Send(EntityUid uid, FaxMachineComponent? component, BoundUserInterfaceMessage args, EntityUid? item = null) // DeltaV - station AI fax
public void Send(EntityUid uid, FaxMachineComponent? component, FaxSendMessage args)
{
if (!Resolve(uid, ref component))
return;
@@ -520,7 +519,7 @@ public sealed class FaxSystem : EntitySystem
if (component.SendTimeoutRemaining > 0)
return;
var sendEntity = item ?? component.PaperSlot.Item; // DeltaV - station AI fax
var sendEntity = component.PaperSlot.Item;
if (sendEntity == null)
return;
@@ -636,10 +635,6 @@ public sealed class FaxSystem : EntitySystem
}
_adminLogger.Add(LogType.Action, LogImpact.Low, $"\"{component.FaxName}\" {ToPrettyString(uid):tool} printed {ToPrettyString(printed):subject}: {printout.Content}");
// Begin DeltaV - notify on fax printing
var evt = new FaxPrintedEvent(printed);
RaiseLocalEvent(uid, ref evt);
// End DeltaV - notify on fax printing
}
private void NotifyAdmins(string faxName)
@@ -1,4 +1,3 @@
using Content.Server.RoundEnd; // DeltaV
using Content.Shared.Roles;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
@@ -26,29 +25,4 @@ public sealed partial class ZombieRuleComponent : Component
/// </summary>
[DataField]
public float ZombieShuttleCallPercentage = 0.7f;
/// <summary>
/// DeltaV - The behavior of the round if all zombies are defeated.
/// </summary>
public RoundEndBehavior ZombieRoundEndBehavior = RoundEndBehavior.ShuttleCall;
/// <summary>
/// DeltaV - The amount of time before the evac shuttle will arrive if the ZombieRoundEndBehavior is set to ShuttleCall.
/// </summary>
public TimeSpan EvacShuttleTime = TimeSpan.FromMinutes(5);
/// <summary>
/// DeltaV - The announcement sender when calling the shuttle.
/// </summary>
public LocId RoundEndTextSender = "comms-console-announcement-title-centcom";
/// <summary>
/// DeltaV - The announcement text when calling a shuttle.
/// </summary>
public LocId RoundEndTextShuttleCall = "zombie-no-more-threat-announcement-shuttle-call";
/// <summary>
/// DeltaV - The announcement text when a shuttle is already called.
/// </summary>
public LocId RoundEndTextAnnouncement = "zombie-no-more-threat-announcement";
}
@@ -30,7 +30,6 @@ using System.Linq;
using Content.Shared.Station.Components;
using Content.Shared.Store.Components;
using Robust.Shared.Prototypes;
using Content.Shared.Cuffs.Components; // DeltaV
namespace Content.Server.GameTicking.Rules;
@@ -501,23 +500,12 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
// Check if there are nuke operatives still alive on the same map as the shuttle,
// or on the same map as the station.
// If there are, the round can continue.
// BEGIN DeltaV - End Rounds Better
// We need to use a EntityQueryEnumerator instead of a EntityQuery, because we need the uid to check for cuffs
var operatives = new List<Entity<NukeOperativeComponent, MobStateComponent, TransformComponent>>();
var operativesEnumerator = EntityQueryEnumerator<NukeOperativeComponent, MobStateComponent, TransformComponent>();
while (operativesEnumerator.MoveNext(out var uid, out var nukeOp, out var mobState, out var transform))
{
operatives.Add((uid, nukeOp, mobState, transform));
}
var operatives = EntityQuery<NukeOperativeComponent, MobStateComponent, TransformComponent>(true);
var operativesAlive = operatives
.Where(op =>
op.Comp3.MapID == shuttleMapId
|| op.Comp3.MapID == targetStationMap)
.Any(op => op.Comp2.CurrentState == MobState.Alive && op.Comp1.Running &&
!TryComp<CuffableComponent>(op, out _)); // in the case the crew keeps one alive
// END DeltaV
op.Item3.MapID == shuttleMapId
|| op.Item3.MapID == targetStationMap)
.Any(op => op.Item2.CurrentState == MobState.Alive && op.Item1.Running);
if (operativesAlive)
return; // There are living operatives than can access the shuttle, or are still on the station's map.
@@ -3,7 +3,7 @@ using Content.Server.Chat.Systems;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Popups;
using Content.Server.Roles;
using Content.Server.RoundEnd; // DeltaV
using Content.Server.RoundEnd;
using Content.Server.Station.Systems;
using Content.Server.Zombies;
using Content.Shared.GameTicking.Components;
@@ -114,31 +114,11 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
/// </summary>
private void CheckRoundEnd(ZombieRuleComponent zombieRuleComponent)
{
// BEGIN DeltaV - End Rounds Better
// Zombies have failed, time to go home
if (zombieRuleComponent.ZombieRoundEndBehavior == RoundEndBehavior.Nothing)
return;
// END DeltaV
var healthy = GetHealthyHumans();
if (healthy.Count == 1) // Only one human left. spooky
_popup.PopupEntity(Loc.GetString("zombie-alone"), healthy[0], healthy[0]);
// BEGIN DeltaV - End Rounds Better
var infectedPercent = GetInfectedFraction(false);
if (Math.Round(infectedPercent, 0) == 0) // All zombies defeated
{
_roundEnd.DoRoundEndBehavior(zombieRuleComponent.ZombieRoundEndBehavior,
zombieRuleComponent.EvacShuttleTime,
zombieRuleComponent.RoundEndTextSender,
zombieRuleComponent.RoundEndTextShuttleCall,
zombieRuleComponent.RoundEndTextAnnouncement);
zombieRuleComponent.ZombieRoundEndBehavior = RoundEndBehavior.Nothing; // stop this check in the future
}
// END DeltaV
if (infectedPercent > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested()) // DeltaV - Move GetInfectedFraction to var
if (GetInfectedFraction(false) > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested())
{
foreach (var station in _station.GetStations())
{
+1 -1
View File
@@ -351,7 +351,7 @@ namespace Content.Server.RoundEnd
else
{
RequestRoundEnd(time, null, false, textCall,
Loc.GetString(sender), cantRecall: true);
Loc.GetString(sender));
}
break;
}
@@ -6,41 +6,4 @@ namespace Content.Server.StationEvents.Components;
[RegisterComponent]
public sealed partial class IonStormRuleComponent : Component
{
// DV start - Synthetic tweaks
/// <summary>
/// The chance that a synth gets electrocuted by the ion storm.
/// </summary>
[DataField]
public float SynthElectrocutionChance = 0.6f;
/// <summary>
/// The minimum delay before a synth affected by the ion storm gets electrocuted. (in seconds)
/// </summary>
[DataField]
public int SynthElectrocutionDelayMin = 3;
/// <summary>
/// The maximum delay before a synth affected by the ion storm gets electrocuted. (in seconds)
/// </summary>
[DataField]
public int SynthElectrocutionDelayMax = 10;
/// <summary>
/// The minimum damage dealt by the synth electrocution. (shock damage)
/// </summary>
[DataField]
public int SynthElectrocutionDamageMin = 5;
/// <summary>
/// The maximum damage dealt by the synth electrocution. (shock damage)
/// </summary>8
[DataField]
public int SynthElectrocutionDamageMax = 10;
/// <summary>
/// How long the synth is stunned for by the electrocution. (in seconds)
/// </summary>
[DataField]
public int SynthElectrocutionStunDuration = 3;
// DV end - synthetic tweaks
}
@@ -6,12 +6,9 @@ using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Station.Components;
// CD - start synth trait
using Content.Server.Chat.Managers;
using Content.Server.Electrocution; // DV - added for synth trait
using Content.Shared.Chat;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Content.Shared._ES.Sparks; // Delta-V change - added for synth trait (where they get affected by ion storms)
using Timer = Robust.Shared.Timing.Timer; // DV - used for synth trait delayed damage
// CD - end synth trait
namespace Content.Server.StationEvents.Events;
@@ -20,8 +17,6 @@ public sealed class IonStormRule : StationEventSystem<IonStormRuleComponent>
{
[Dependency] private readonly IonStormSystem _ionStorm = default!;
[Dependency] private readonly IChatManager _chatManager = default!; // CD - Used for synth trait
[Dependency] private readonly ElectrocutionSystem _electrocution = default!; // DV - used for synth trait
[Dependency] private readonly ESSparksSystem _esSparks = default!; // DV - used for synth trait
protected override void Started(EntityUid uid, IonStormRuleComponent comp, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
@@ -31,32 +26,18 @@ public sealed class IonStormRule : StationEventSystem<IonStormRuleComponent>
return;
// CD - Go through everyone with the SynthComponent and inform them a storm is happening.
// DV - buuuuuut only if IonStormAffected is present so that not all synthetics are affected by this
// but they are still notified about incoming ion storms regardless.
var synthQuery = EntityQueryEnumerator<SynthComponent>();
while (synthQuery.MoveNext(out var ent, out var synthComp))
{
if (RobustRandom.Prob(synthComp.AlertChance))
continue;
if (!TryComp<ActorComponent>(ent, out var actor))
continue;
if (RobustRandom.Prob(synthComp.AlertChance))
{
var msg = Loc.GetString("station-event-ion-storm-synth");
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.Channel, colorOverride: Color.Yellow);
}
// DV start - super duper fucked up thing for synths
if (synthComp.IonStormAffected && RobustRandom.Prob(comp.SynthElectrocutionChance))
{
var delay = RobustRandom.Next(TimeSpan.FromSeconds(comp.SynthElectrocutionDelayMin), TimeSpan.FromSeconds(comp.SynthElectrocutionDelayMax)); // they'll never know when it'll hit them
Timer.Spawn(delay, () =>
{
_electrocution.TryDoElectrocution(ent, null, RobustRandom.Next(comp.SynthElectrocutionDamageMin, comp.SynthElectrocutionDamageMax), TimeSpan.FromSeconds(comp.SynthElectrocutionStunDuration), true, ignoreInsulation: true);
_esSparks.DoSparks(ent);
});
}
// DV end
var msg = Loc.GetString("station-event-ion-storm-synth");
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.Channel, colorOverride: Color.Yellow);
}
// CD - End of synth trait
+1 -10
View File
@@ -7,16 +7,7 @@ namespace Content.Server._CD.Traits;
public sealed partial class SynthComponent : Component
{
/// <summary>
/// Whether this synthetic is affected by ion storms (electrocution/sparks and
/// alerts when one occurs). False by default. set true by the
/// "Susceptible to Ion Storms" meta trait.
/// </summary>
[DataField]
public bool IonStormAffected;
/// <summary>
/// The chance that the synth is alerted of an ion storm. Only relevant if
/// <see cref="IonStormAffected"/> is true.
/// The chance that the synth is alerted of an ion storm
/// </summary>
[DataField]
public float AlertChance = 0.3f;
+1 -24
View File
@@ -1,11 +1,8 @@
using Content.Server.Body.Systems;
using Content.Server.Database;
using Content.Shared.Body.Components;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Chat.TypingIndicator;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Speech.Components;
using Content.Shared.Tag;
using Robust.Shared.Prototypes;
namespace Content.Server._CD.Traits;
@@ -15,13 +12,9 @@ public sealed class SynthSystem : EntitySystem
// Begin DeltaV - make strings static readonly
private static readonly ProtoId<TypingIndicatorPrototype> RobotTypingIndicator = "robot";
private static readonly ProtoId<ReagentPrototype> SynthBloodReagent = "SynthBlood";
private static readonly ProtoId<TagPrototype> SyntheticEmotesTag = "SyntheticEmotes";
private static readonly ProtoId<EmoteSoundsPrototype> SyntheticEmoteSounds = "SyntheticEmoteSounds";
// End DeltaV
[Dependency] private readonly BloodstreamSystem _bloodstream = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
public override void Initialize()
{
@@ -45,21 +38,5 @@ public sealed class SynthSystem : EntitySystem
_bloodstream.ChangeBloodReagents((uid, bloodstream), new([new(SynthBloodReagent, bloodstream.BloodReferenceSolution.Volume)]));
}
// End DeltaV
// Begin DeltaV - Add SyntheticEmotes tag and merge synthetic emote sounds into species sounds
_tag.AddTag(uid, SyntheticEmotesTag);
if (TryComp<VocalComponent>(uid, out var vocal)
&& _proto.TryIndex(SyntheticEmoteSounds, out var synthSounds)
&& vocal.EmoteSounds is { } currentSoundsId
&& _proto.TryIndex(currentSoundsId, out var currentSounds))
{
foreach (var (emoteId, sound) in synthSounds.Sounds)
{
currentSounds.Sounds.TryAdd(emoteId, sound);
}
Dirty(uid, vocal);
}
// End DeltaV
}
}
}
@@ -61,39 +61,6 @@ public sealed partial class CosmicCultRuleComponent : Component
[DataField]
public TimeSpan EvacShuttleTime = TimeSpan.FromMinutes(5);
#region Progress Checking
/// <summary>
/// The next time the monument should check the progress of the cult.
/// </summary>
public TimeSpan NextProgressCheck = TimeSpan.Zero;
/// <summary>
/// The amount of time between progress checks.
/// </summary>
public TimeSpan TimeBetweenProgressChecks = TimeSpan.FromMinutes(15);
/// <summary>
/// The progress value of the monument last time it was checked.
/// </summary>
[DataField]
public int LastProgress = 0;
/// <summary>
/// The number of times the the progress check as failed. Resets after some progress.
/// </summary>
public int ConsecutiveProgressFails = 0;
/// <summary>
/// The number of times the progress check has to fail for the round to start to end.
/// </summary>
public int ProgressFailureTolerance = 3;
public LocId ProgressFailTextShuttleCall = "cosmiccult-progress-fail-shuttle-call";
public LocId ProgressFailTextAnnouncement = "cosmiccult-progress-fail-announcement";
#endregion
[DataField]
public HashSet<EntityUid> Cultists = [];
@@ -62,15 +62,13 @@ using Robust.Shared.Random;
using Robust.Shared.Timing;
using System.Collections.Immutable;
using System.Linq;
using Content.Shared.StatusIcon;
using Content.Shared.SSDIndicator;
namespace Content.Server._DV.CosmicCult;
/// <summary>
/// Where all the main stuff for Cosmic Cultists happens.
/// </summary>
public sealed partial class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponent>
public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponent>
{
[Dependency] private readonly ActionsSystem _actions = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
@@ -174,28 +172,6 @@ public sealed partial class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRule
component.StewardVoteTimer = null;
StewardVote();
}
// Progress check. Is the cult trying to progress at all?
if (component.MonumentPlaced && _timing.CurTime > component.NextProgressCheck)
{
// We're going to assume one monument.
var monument = EntityQuery<MonumentComponent>().First();
if (component.LastProgress == monument.CurrentProgress)
component.ConsecutiveProgressFails++;
else
component.ConsecutiveProgressFails = 0;
// They haven't progressed enough in X checks, end the round.
if (component.ConsecutiveProgressFails >= component.ProgressFailureTolerance) {
SetWinType((uid, component), WinType.CrewMinor);
_roundEnd.DoRoundEndBehavior(component.RoundEndBehavior, component.EvacShuttleTime, component.RoundEndTextSender, component.ProgressFailTextShuttleCall, component.ProgressFailTextAnnouncement);
component.RoundEndBehavior = RoundEndBehavior.Nothing;
}
component.LastProgress = monument.CurrentProgress;
component.NextProgressCheck = _timing.CurTime + component.TimeBetweenProgressChecks;
}
if (component.ExtraRiftTimer is { } riftTimer && _timing.CurTime >= riftTimer && !component.RiftStop)
{
component.ExtraRiftTimer = _timing.CurTime + _rand.Next(TimeSpan.FromSeconds(230), TimeSpan.FromSeconds(360)); //3min50 to 6min between new rifts. Seconds instead of minutes for granularity.
@@ -466,19 +442,17 @@ public sealed partial class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRule
}
}
private int GetCultistsAlive()
private bool CultistsAlive()
{
var query = EntityQueryEnumerator<CosmicCultComponent, MobStateComponent>();
int cultistsAlive = 0;
while (query.MoveNext(out var ent, out _, out var mobComp))
{
if (TryComp<CuffableComponent>(ent, out var cuffed) && cuffed.CuffedHandCount > 0) continue;
if (TryComp<SSDIndicatorComponent>(ent, out var ssd) && ssd.IsSSD) continue; // TODO: Maybe check how long.
if (mobComp.Running && mobComp.CurrentState != MobState.Dead)
cultistsAlive++;
return true;
}
return cultistsAlive;
return false;
}
private void OnMobStateChanged(Entity<CosmicCultComponent> ent, ref MobStateChangedEvent args)
@@ -493,19 +467,14 @@ public sealed partial class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRule
private void CheckForActiveCultists()
{
// A lone cultist can't do anything, so check for more than one.
if (GetCultistsAlive() > 1)
if (CultistsAlive())
return;
var query = QueryActiveRules();
List<Entity<CosmicCultRuleComponent>> cosCultRules = new();
// ConfirmWinState needs to be outside the query, because it might add an active rule
while (query.MoveNext(out var ruleUid, out _, out var ruleComp, out _))
{
cosCultRules.Add((ruleUid, ruleComp));
ConfirmWinState((ruleUid, ruleComp));
}
cosCultRules.ForEach(ConfirmWinState);
}
private void ConfirmWinState(Entity<CosmicCultRuleComponent> ent)
@@ -535,6 +504,8 @@ public sealed partial class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRule
else
SetWinType(ent, WinType.Neutral); //The monument wasn't completed, no cultists escaped to midpoint. Some cultists still remain on the station, though.
if (CultistsAlive()) return; //If there are no cultists alive, ignore all previous checks, crew alreay won.
if (tier <= 1) //Prevent the cult getting cooked by accident before anyone even knows there's a cult.
{
SetWinType(ent, WinType.CrewMinor); //If we somehow get here at the end of the round, we'll still count this as a crew minor.
@@ -1,39 +0,0 @@
using Content.Server.Fax;
using Content.Shared._DV.Silicons;
using Content.Shared.Fax;
using Content.Shared.Fax.Components;
namespace Content.Server._DV.Silicons;
public sealed class StationAiFaxSystem : SharedStationAiFaxSystem
{
[Dependency] private readonly FaxSystem _fax = default!;
public override void Initialize()
{
base.Initialize();
Subs.BuiEvents<StationAiFaxComponent>(FaxUiKey.Key,
subs =>
{
subs.Event<StationAiFaxSendMessage>(OnSend);
subs.Event<StationAiFaxDuplicateMessage>(OnDuplicate);
});
}
private void OnSend(Entity<StationAiFaxComponent> ent, ref StationAiFaxSendMessage args)
{
if (GetDocument(ent, args.Document) is not { } document)
return;
_fax.Send(ent, Comp<FaxMachineComponent>(ent), args, document);
}
private void OnDuplicate(Entity<StationAiFaxComponent> ent, ref StationAiFaxDuplicateMessage args)
{
if (GetDocument(ent, args.Document) is not { } document)
return;
_fax.Copy(ent, Comp<FaxMachineComponent>(ent), args, document);
}
}
@@ -63,7 +63,7 @@ public sealed partial class FaxMachineComponent : Component
/// Sound to play when fax printing new message
/// </summary>
[DataField]
public SoundSpecifier? PrintSound = new SoundPathSpecifier("/Audio/Machines/printer.ogg"); // DeltaV - nullable
public SoundSpecifier PrintSound = new SoundPathSpecifier("/Audio/Machines/printer.ogg");
/// <summary>
/// Sound to play when fax successfully send message
+1 -4
View File
@@ -17,15 +17,13 @@ public sealed class FaxUiState : BoundUserInterfaceState
public bool IsPaperInserted { get; }
public bool CanSend { get; }
public bool CanCopy { get; }
public bool CanSendCooldown; // DeltaV - AI fax
public FaxUiState(string deviceName,
Dictionary<string, string> peers,
bool canSend,
bool canCopy,
bool isPaperInserted,
string? destAddress,
bool canSendCooldown) // DeltaV - AI fax
string? destAddress)
{
DeviceName = deviceName;
AvailablePeers = peers;
@@ -33,7 +31,6 @@ public sealed class FaxUiState : BoundUserInterfaceState
CanSend = canSend;
CanCopy = canCopy;
DestinationAddress = destAddress;
CanSendCooldown = canSendCooldown; // DeltaV - AI fax
}
}
@@ -68,11 +68,6 @@ public abstract class SharedSuitSensorSystem : EntitySystem
/// <returns>True if the sensor is assigned to a station or assigning it was successful. False otherwise.</returns>
public bool CheckSensorAssignedStation(Entity<SuitSensorComponent> sensor)
{
// Begin DeltaV - fallback
if (sensor.Comp.StationId.HasValue && _stationSystem.GetOwningStation(sensor.Owner) is null)
return true;
// End DeltaV - fallback
if (!sensor.Comp.StationId.HasValue && Transform(sensor.Owner).GridUid == null)
return false;
@@ -353,7 +348,7 @@ public abstract class SharedSuitSensorSystem : EntitySystem
var transform = ent.Comp2;
// check if sensor is enabled and worn by user
if (sensor.Mode == SuitSensorMode.SensorOff || sensor.User == null || !HasComp<MobStateComponent>(sensor.User)) // DeltaV - don't block on grids here
if (sensor.Mode == SuitSensorMode.SensorOff || sensor.User == null || !HasComp<MobStateComponent>(sensor.User) || transform.GridUid == null)
return null;
// try to get mobs id from ID slot
+1 -1
View File
@@ -276,7 +276,7 @@ public sealed class PaperSystem : EntitySystem
_appearance.SetData(entity, PaperVisuals.Status, status, appearance);
}
public void UpdateUserInterface(Entity<PaperComponent> entity) // DeltaV - station AI
private void UpdateUserInterface(Entity<PaperComponent> entity)
{
_uiSystem.SetUiState(entity.Owner, PaperUiKey.Key, new PaperBoundUserInterfaceState(entity.Comp.Content, entity.Comp.StampedBy, entity.Comp.Mode));
}
@@ -1,4 +0,0 @@
namespace Content.Shared._DV.Fax;
[ByRefEvent]
public readonly record struct FaxPrintedEvent(EntityUid Fax);
@@ -1,4 +1,3 @@
using Content.Shared.CartridgeLoader;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.DeviceNetwork.Systems;
@@ -55,11 +54,5 @@ public sealed class PageSenderSystem : EntitySystem
{ PagerConstants.DataBody, body },
};
_deviceNetwork.QueuePacket(ent, null, payload);
if (HasComp<PagerComponent>(ent))
{
var evt = new CartridgeLoaderNotificationSentEvent(Loc.GetString("pager-self-notification"), body);
RaiseLocalEvent(ent, ref evt);
}
}
}
@@ -1,82 +0,0 @@
using Content.Shared._DV.Fax;
using Content.Shared.Fax;
using Content.Shared.Paper;
using Content.Shared.Silicons.StationAi;
using Robust.Shared.Containers;
namespace Content.Shared._DV.Silicons;
public abstract class SharedStationAiFaxSystem : EntitySystem
{
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
[Dependency] private readonly PaperSystem _paper = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StationAiFaxComponent, EntInsertedIntoContainerMessage>(OnInserted);
SubscribeLocalEvent<StationAiFaxComponent, FaxPrintedEvent>(OnFaxPrinted);
Subs.BuiEvents<StationAiFaxComponent>(FaxUiKey.Key,
subs =>
{
subs.Event<StationAiFaxExamineMessage>(OnExamine);
subs.Event<StationAiFaxShredMessage>(OnShred);
});
}
protected virtual void OnInserted(Entity<StationAiFaxComponent> ent, ref EntInsertedIntoContainerMessage args)
{
if (HasComp<PaperComponent>(args.Entity))
EnsureComp<StationAiWhitelistComponent>(args.Entity);
}
private void OnExamine(Entity<StationAiFaxComponent> ent, ref StationAiFaxExamineMessage args)
{
if (GetDocument(ent, args.Document) is not { } document)
return;
if (TryComp<PaperComponent>(document, out var paper))
{
paper.Mode = paper.EditingDisabled || paper.StampedBy.Count != 0
? PaperComponent.PaperAction.Read
: PaperComponent.PaperAction.Write;
_paper.UpdateUserInterface((document, paper));
}
_userInterface.OpenUi(document, PaperComponent.PaperUiKey.Key, args.Actor);
}
private void OnShred(Entity<StationAiFaxComponent> ent, ref StationAiFaxShredMessage args)
{
if (GetDocument(ent, args.Document) is { } document)
{
PredictedQueueDel(document);
}
}
protected EntityUid? GetDocument(Entity<StationAiFaxComponent> ent, NetEntity netEntity)
{
if (GetEntity(netEntity) is not { Valid: true } entity)
return null;
if (!_container.TryGetContainingContainer(entity, out var container))
return null;
if (container.Owner != ent.Owner)
return null;
return entity;
}
private void OnFaxPrinted(Entity<StationAiFaxComponent> ent, ref FaxPrintedEvent args)
{
var container = _container.EnsureContainer<Container>(ent, StationAiFaxComponent.Container);
if (!_container.Insert(args.Fax, container, force: true))
{
PredictedQueueDel(args.Fax);
}
}
}
@@ -1,34 +0,0 @@
using Content.Shared._DV.Fax;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Silicons;
[RegisterComponent, NetworkedComponent, Access(typeof(SharedStationAiFaxSystem))]
public sealed partial class StationAiFaxComponent : Component
{
public const string Container = "PaperLibrary";
}
[Serializable, NetSerializable]
public abstract partial class StationAiFaxFileMessage : BoundUserInterfaceMessage
{
public readonly NetEntity Document;
public StationAiFaxFileMessage(NetEntity document)
{
Document = document;
}
}
[Serializable, NetSerializable]
public sealed partial class StationAiFaxSendMessage(NetEntity document) : StationAiFaxFileMessage(document);
[Serializable, NetSerializable]
public sealed partial class StationAiFaxExamineMessage(NetEntity document) : StationAiFaxFileMessage(document);
[Serializable, NetSerializable]
public sealed partial class StationAiFaxDuplicateMessage(NetEntity document) : StationAiFaxFileMessage(document);
[Serializable, NetSerializable]
public sealed partial class StationAiFaxShredMessage(NetEntity document) : StationAiFaxFileMessage(document);
+57 -62
View File
@@ -1,4 +1,61 @@
Entries:
- author: Velcroboy
changes:
- message: Reconfigurated the TEG tentacles
type: Tweak
id: 1957
time: '2025-12-13T19:18:53.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4965
- author: kotobdev
changes:
- message: The Redshirt trait has been added, which causes you to immediately die
instead of going crit.
type: Add
id: 1958
time: '2025-12-16T01:34:03.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4974
- author: Stxcking
changes:
- message: Courier, Boxer, Gladiator, and Prisoner have the option to choose glasses
in their loadout.
type: Tweak
- message: Surgeons get medical eyewear options in loadout.
type: Tweak
id: 1959
time: '2025-12-16T05:04:42.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4977
- author: Proxysseia
changes:
- message: replaced vestigial entity mentions with employee mentions. You can no
longer harass vent spiders.
type: Tweak
id: 1960
time: '2025-12-16T13:07:37.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4947
- author: MantasDab360
changes:
- message: Revenant's crayon is now infinite once again.
type: Fix
id: 1961
time: '2025-12-16T13:15:10.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4987
- author: Stxcking
changes:
- message: Corpsman's inventory on spawn has been cleaned up. Most medical gear
has been moved to the corpsman. locker.
type: Tweak
- message: Corpsman uniforms are now available in the SecDrobe.
type: Tweak
id: 1962
time: '2025-12-16T13:24:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4979
- author: marigauge
changes:
- message: IPCs now leave behind steel fibers when touching stuff.
type: Tweak
id: 1963
time: '2025-12-16T13:41:33.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4968
- author: marigauge
changes:
- message: Cybernetic eyes are no longer edible.
@@ -4355,66 +4412,4 @@
id: 2457
time: '2026-06-24T22:02:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6101
- author: ManuDemoen
changes:
- message: Fixed certain entities from not metabolizing alcohol
type: Fix
id: 2458
time: '2026-06-25T02:28:27.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6104
- author: Tmanzxd
changes:
- message: Removed the Surgeon time requirement for Chief Medical Officer, since
surgery is once again a week away.
type: Remove
id: 2459
time: '2026-06-25T13:10:38.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6112
- author: rebe83
changes:
- message: Washing machines now can fit larger items inside, such as felinids, rodentia,
or even a china lake. (China Lake not included)
type: Tweak
id: 2460
time: '2026-06-25T14:07:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6086
- author: sowelipililimute
changes:
- message: The station AI can now send and receive faxes.
type: Add
id: 2461
time: '2026-06-25T15:27:50.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6064
- author: ManuDemoen
changes:
- message: The nachos recipe has changed! Cut them from taco shells and then add
chili or cheese for variants.
type: Tweak
id: 2462
time: '2026-06-25T15:37:34.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6099
- author: wesk
changes:
- message: Synthetics can now use borg emotes!
type: Add
- message: Synthetics now has an option of being susceptible to Ion Storms.
type: Add
- message: Synthetics can now be purely mechanical! (cosmetical function only; you
spark when damaged.)
type: Add
id: 2463
time: '2026-06-25T16:17:27.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6090
- author: sowelipililimute
changes:
- message: Suit sensors now report their location, even while in space
type: Add
- message: Crew monitoring computers now have a radar UI when you're off-station
type: Add
- message: Due to suit sensors now working in space, salvage no longer needs deathrattles
for recovery, hence, they have been removed.
type: Remove
id: 2464
time: '2026-06-25T17:59:50.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6054
Order: 1
@@ -62,11 +62,9 @@ cosmiccult-summary-crewminor = The Monument did not reach full power.
cosmiccult-summary-crewmajor = All cosmic cultists were eliminated.
cosmiccult-summary-crewcomplete = All cosmic cultists were deconverted!
cosmiccult-elimination-shuttle-call = Based on scans from our long-range sensors, the Λ-CDM anomaly has subsided. We thank you for your prudence. An emergency shuttle has been automatically called to the station for decontamination and debriefing procedures. ETA: {$time} {$units}.
cosmiccult-elimination-announcement = Based on scans from our long-range sensors, the Λ-CDM anomaly has subsided. We thank you for your prudence. An emergency shuttle is already inbound. Return to Midpoint safely for decontamination and debriefing procedures.
cosmiccult-elimination-shuttle-call = Based on scans from our long-range sensors, the Λ-CDM anomaly has subsided. We thank you for your prudence. An emergency shuttle has been automatically called to the station for decontamination and debriefing procedures. ETA: {$time} {$units}. Please note, if the psychological impact of the anomaly is negligible, you may recall the shuttle to extend the shift.
cosmiccult-elimination-announcement = Based on scans from our long-range sensors, the Λ-CDM anomaly has subsided. We thank you for your prudence. An emergency shuttle is already inbound. Return to CentComm safely for decontamination and debriefing procedures.
cosmiccult-progress-fail-shuttle-call = Due to sustained Λ-CDM activity on you station, an emergency shuttle has been automatically called so that the station may be decontaminated as soon as possible. We thank you for your cooperation.
cosmiccult-progress-fail-announcement = Due to sustained Λ-CDM activity on you station, an emergency shuttle is already inbound. Please ensure as much of the station is ready and accessible for the decontamination team. We thank you for your cooperation.
## BRIEFINGS
-8
View File
@@ -1,8 +0,0 @@
fax-machine-ui-no-faxes =
You have no documents.
Add some, and they'll show up here.
fax-machine-ui-add-blank-file = Add blank document
fax-machine-ui-upload-file = Upload document…
fax-machine-ui-page-window = Send Document
fax-machine-ui-sending = Sending:
@@ -2,4 +2,3 @@ pager-error-different-networks = { THE($sender) } is on a different network from
pager-connection-added = { THE($receiver) } will now receive pages from { THE($sender) }.
pager-connection-removed = { THE($receiver) } will no longer receive pages from { THE($sender) }.
pager-notification = Page from { $sender }
pager-self-notification = Page received
@@ -73,9 +73,3 @@ trait-slavic-desc = You kome from ze East, and speak vith strong Slavic accent!
trait-no-paradox-clone-name = No Paradox Clone
trait-no-paradox-clone-desc = For whatever reason, the universe will only ever have one of you. You won't be able to have a paradox clone.
trait-ion-storm-susceptible-name = Susceptible to Ion Storms
trait-ion-storm-susceptible-desc = Your synthetic body lacks protection against ion storms. You have a high chance of being shocked in an event of an ion storm.
trait-mechanical-synthetic-name = Mechanical Synthetic
trait-mechanical-synthetic-desc = Your synthetic body is fully mechanical rather than biomechanical.
@@ -1,2 +0,0 @@
zombie-no-more-threat-announcement-shuttle-call = Long-range sensors indicate that you station has dealt with a biohazardous threat involving Romerol. Station decontamination required. The emergency shuttle has been called. ETA: {$time} {$units}.
zombie-no-more-threat-announcement = Long-range sensors indicate that you station has dealt with a biohazardous threat involving Romerol. Station decontamination required. The emergency shuttle is already en route.
+1 -1
View File
@@ -1,2 +1,2 @@
nuke-ops-no-more-threat-announcement-shuttle-call = Long-range sensors indicate the nuclear threat has been eliminated. The emergency shuttle has been called. ETA: {$time} {$units}.
nuke-ops-no-more-threat-announcement-shuttle-call = Long-range sensors indicate the nuclear threat has been eliminated. The emergency shuttle has been called. ETA: {$time} {$units}. You may recall the shuttle to extend the shift.
nuke-ops-no-more-threat-announcement = Long-range sensors indicate the nuclear threat has been eliminated. The emergency shuttle is already en route.
@@ -58,8 +58,8 @@
transmitFrequencyId: SuitSensor
savableAddress: false
- type: WirelessNetworkConnection
range: 3600 # DeltaV - was 1200
# - type: StationLimitedNetwork # DeltaV - this stinks and we don't want it to be limited
range: 1200
- type: StationLimitedNetwork
- type: entity
abstract: true
@@ -111,7 +111,7 @@
# End CD - Character Records
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV - NTNet
receiveFrequencyId: CrewMonitor
transmitFrequencyId: ShuttleTimer
- type: WirelessNetworkConnection
range: 500
@@ -68,10 +68,6 @@
enum.RingerUiKey.Key:
type: RingerBoundUserInterface
# End DeltaV - AI PDAs
# Begin DeltaV - AI fax
enum.FaxUiKey.Key:
type: StationAiFaxBoundUserInterface
# End DeltaV - AI fax
- type: IntrinsicUI
uis:
enum.RadarConsoleUiKey.Key:
@@ -82,16 +78,12 @@
toggleAction: ActionAGhostShowStationRecords
enum.CommunicationsConsoleUiKey.Key:
toggleAction: ActionAGhostShowCommunications
# Begin DeltaV - AI fax
enum.FaxUiKey.Key:
toggleAction: ActionStationAiOpenFax
# End DeltaV - AI fax
- type: CrewMonitoringConsole
- type: GeneralStationRecordConsole
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV
transmitFrequencyId: NTNet # DeltaV
receiveFrequencyId: CrewMonitor
transmitFrequencyId: ShuttleTimer
- type: RadarConsole
followEntity: false
- type: CommunicationsConsole
@@ -103,27 +95,6 @@
startPowerCorruptionAtCharIdx: 4
maxPowerCorruptionAtCharIdx: 20
- type: StationAiShop # DeltaV - AI Shop System
# Begin DeltaV - AI faxes
- type: FaxMachine
name: Station AI
printSound: null
paperSlot:
insertSound: /Audio/Machines/scanning.ogg
ejectSound: /Audio/Machines/tray_eject.ogg
whitelist:
components:
- FaxableObject
blacklist:
components:
- CargoSlip
tags:
- PaperSlip
- type: StationAiFax
- type: Pager
autoLinkJobs: [ StationAi ]
- type: PageSender
autoLinkJobs: [ StationAi ]
# End DeltaV - AI faxes
- type: entity
id: AiHeldIntellicard
@@ -563,10 +534,6 @@
containers:
program-container: !type:Container
Cartridge-Slot: !type:ContainerSlot
# Begin DeltaV - AI faxes
Paper: !type:ContainerSlot
PaperLibrary: !type:Container
# End DeltaV - AI faxes
- type: ItemSlots
- type: PdaBorderColor
borderColor: "#45453f"
@@ -818,7 +818,6 @@
entries:
Taco: CheeseTaco
Burger: CheeseBurger
Nachos: CheeseTaco # DeltaV
- type: Item
size: Tiny
storedOffset: 0,-3
@@ -114,20 +114,8 @@
- type: FlavorProfile
flavors:
- nachos
#- type: Sprite # DeltaV - replaced below to add foodSequenceLayers slot for sequence system
# state: nachos
# Begin DeltaV additions - nachos can be topped with cheese or chili to metamorph into variants
- type: Sprite
sprite: Objects/Consumable/Food/meals.rsi
layers:
- state: nachos
- map: ["foodSequenceLayers"]
- type: Appearance
- type: FoodSequenceStartPoint
key: Nachos
- type: FoodMetamorphableByAdding
onlyFinal: false
# End DeltaV additions
state: nachos
- type: SolutionContainerManager
solutions:
food:
@@ -1503,7 +1503,6 @@
Taco: ChiliPepper
Burger: ChiliPepper
Skewer: ChiliPepperSkewer
Nachos: ChiliPepper # DeltaV
- type: entity
name: chilly pepper
@@ -34,11 +34,6 @@
nameGeneration: food-sequence-taco-gen
contentSeparator: ", "
- type: Appearance
# Begin DeltaV additions - slicing a taco shell with a knife yields 2 nachos
- type: SliceableFood
count: 2
slice: FoodMealNachos
# End DeltaV additions
# Old tacos
@@ -20,10 +20,10 @@
- type: CrewMonitoringConsole
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV - NTNet
receiveFrequencyId: CrewMonitor
- type: WirelessNetworkConnection
range: 500
# - type: StationLimitedNetwork # DeltaV - don't restrict this unnecessarily
- type: StationLimitedNetwork
- type: ReverseEngineering # Nyano
difficulty: 2
recipes:
@@ -953,6 +953,7 @@
- type: entity
parent: AirlockChapelLocked # DeltaV - Chapel is in Epistemics
id: AirlockMaintChapelLocked
suffix: Chapel, Locked
components:
- type: Sprite
sprite: _DV/Structures/Doors/Airlocks/Standard/maint.rsi # DeltaV - Changed to our sprites
@@ -483,7 +483,7 @@
- type: CrewMonitoringConsole
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV - NTNet
receiveFrequencyId: CrewMonitor
- type: WirelessNetworkConnection
range: 1200
@@ -31,12 +31,12 @@
- type: SingletonDeviceNetServer
- type: DeviceNetwork
deviceNetId: Wireless
transmitFrequencyId: NTNet # DeltaV - NTNet
transmitFrequencyId: CrewMonitor
receiveFrequencyId: SuitSensor
autoConnect: false
- type: WirelessNetworkConnection
range: 10000 # Delta-V Maximises the range for the Crew Monitor Server to make it work for Listening Post
# - type: StationLimitedNetwork # DeltaV - make this work for salvies
- type: StationLimitedNetwork
- type: ApcPowerReceiver
powerLoad: 200
- type: ExtensionCableReceiver
@@ -71,14 +71,13 @@
- type: Climbable
delay: 1.6
- type: Storage
maxItemSize: Huge # DeltaV - changed to huge (so felinids can fit)
maxItemSize: Normal
grid:
- 0,0,5,5
storageOpenSound:
path: /Audio/Nyanotrasen/Machines/washer_open.ogg
storageCloseSound:
path: /Audio/Nyanotrasen/Machines/washer_close.ogg
- type: AllowsSleepInside # DeltaV - let felinids sleep inside washing machines
- type: ContainerContainer
containers:
storagebase: !type:Container
+6 -11
View File
@@ -344,12 +344,11 @@
category: Vocal
icon: Interface/Emotes/buzz.png
whitelist:
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
requireAll: true
components:
- Vocal
tags:
- SiliconEmotes
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
chatMessages: ["chat-emote-msg-buzz"]
chatTriggers:
- buzzing
@@ -398,12 +397,11 @@
category: Vocal
icon: Interface/Emotes/beep.png
whitelist:
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
requireAll: true
components:
- Vocal
tags:
- SiliconEmotes
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
chatMessages: ["chat-emote-msg-beep"]
chatTriggers:
- beep
@@ -417,12 +415,11 @@
category: Vocal
icon: Interface/Emotes/chime.png
whitelist:
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
requireAll: true
components:
- Vocal
tags:
- SiliconEmotes
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
chatMessages: ["chat-emote-msg-chime"]
chatTriggers:
- chime
@@ -436,12 +433,11 @@
category: Vocal
icon: Interface/Emotes/buzztwo.png
whitelist:
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
requireAll: true
components:
- Vocal
tags:
- SiliconEmotes
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
chatMessages: ["chat-emote-msg-buzzestwo"]
chatTriggers:
- buzztwice
@@ -461,15 +457,14 @@
category: Vocal
icon: Interface/Emotes/ping.png
whitelist:
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
requireAll: true
components:
- Vocal
tags:
- SiliconEmotes
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
chatMessages: ["chat-emote-msg-ping"]
chatTriggers:
- ping
- pings
- pinged
- pinging
- pinging
@@ -160,17 +160,3 @@
duration: 10
spreadAmount: 8
smokePrototype: AluminiumMetalFoam
- type: entity
parent: BaseMentalAction
id: ActionStationAiOpenFax
name: Fax machine interface
description: View a fax machine interface.
components:
- type: Action
icon:
sprite: _DV/Interface/Actions/actions_ai.rsi
state: fax
- type: InstantAction
event: !type:ToggleIntrinsicUIEvent
key: enum.FaxUiKey.Key
@@ -61,3 +61,5 @@
- id: ShelterCapsuleBar
cost: 10000
# TODO: mining drone stuff
- id: MedicalTrackingImplanter
cost: 10000
@@ -44,6 +44,7 @@
content:
- ClothingBeltSalvageWebbing
- ShelterCapsule
- MedicalTrackingImplanter
- NFWeaponHoloflareGun
# TODO: mining drone
@@ -16,34 +16,27 @@
prob: 0.90
children:
- id: TowelColorWhite
- id: TowelColorPurple
- id: TowelColorRed
- id: TowelColorBlue
- id: TowelColorDarkBlue
- id: TowelColorLightBlue
- id: TowelColorTeal
- id: TowelColorBrown
- id: TowelColorLightBrown
- id: TowelColorGray
- id: TowelColorGreen
- id: TowelColorDarkGreen
- id: TowelColorGold
- id: TowelColorOrange
- id: TowelColorBlack
- id: TowelColorPink
- !type:GroupSelector
weight: 0.1
children:
- id: TowelColorPurple
- id: TowelColorRed
- id: TowelColorBlue
- id: TowelColorDarkBlue
- id: TowelColorLightBlue
- id: TowelColorLightBrown
- id: TowelColorGray
- id: TowelColorGreen
- id: TowelColorDarkGreen
- id: TowelColorOrange
- id: TowelColorBlack
- id: TowelColorYellow
- id: TowelColorMaroon
- id: TowelColorYellow
- id: TowelColorMaroon
- id: TowelColorSilver
- !type:GroupSelector
weight: 0.05
children:
- id: TowelColorGold
weight: 0.5
- id: TowelColorSilver
- !type:GroupSelector
weight: 0.005
children:
- id: TowelColorNT
- id: TowelColorCentcom
- id: TowelColorSyndicate
@@ -22,6 +22,14 @@
- type: Implanter
implant: WatchdogImplant
- type: entity
parent: BaseImplantOnlyImplanter
id: MedicalTrackingImplanter
name: medical tracking implanter
components:
- type: Implanter
implant: MedicalTrackingImplant
- type: entity
parent: BaseImplantOnlyImplanterCentcomm
id: CentCommImplanter
@@ -41,6 +41,21 @@
targetUser: true
radioChannel: Security
- type: entity
parent: BaseSubdermalImplant
id: MedicalTrackingImplant
categories: [ HideSpawnMenu ]
name: medical tracking implant
description: This implants transmits a message on the medical channel in case the user goes into critical state or dies.
components:
- type: TriggerOnMobstateChange
mobState:
- Critical
- Dead
- type: RattleOnTrigger
targetUser: true
radioChannel: Medical
- type: entity
parent: BaseSubdermalImplant
id: CentCommImplant
@@ -23,7 +23,7 @@
alertsEnabled: false
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV - NTNet
receiveFrequencyId: CrewMonitor
- type: WirelessNetworkConnection
range: 500
- type: StationLimitedNetwork
@@ -25,7 +25,7 @@
- type: SingletonDeviceNetServer
- type: DeviceNetwork
deviceNetId: Wireless
transmitFrequencyId: NTNet # DeltaV - NTNet
transmitFrequencyId: CrewMonitor
receiveFrequencyId: SuitSensor
autoConnect: false
- type: WirelessNetworkConnection
@@ -47,6 +47,55 @@
baseRecipe: RecipeCarrotFries
burnTime: 10
- type: microwaveMealRecipe
id: RecipeNachos # Renamed to tortilla chips (nachos have cheese)
name: nachos recipe
result: FoodMealNachos
secretRecipe: true
time: 10
group: DeepFried
deepFried: true
solids:
FoodDoughTortillaFlat: 1
- type: deepFryerRecipe
id: DeepFryerRecipeTortillaChips
baseRecipe: RecipeNachos
burnTime: 15
- type: microwaveMealRecipe
id: RecipeNachosCheesy
name: cheesy nachos recipe
result: FoodMealNachosCheesy
secretRecipe: true
time: 10
group: DeepFried
deepFried: true
solids:
FoodCheeseSlice: 1
FoodDoughTortillaFlat: 1
- type: deepFryerRecipe
id: DeepFryerRecipeNachosCheesy
baseRecipe: RecipeNachosCheesy
burnTime: 15
- type: microwaveMealRecipe
id: RecipeNachosCuban
name: cuban nachos recipe
result: FoodMealNachosCuban
secretRecipe: true
time: 10
group: DeepFried
deepFried: true
solids:
FoodChiliPepper: 1
FoodDoughTortillaFlat: 1
- type: deepFryerRecipe
id: DeepFryerRecipeNachosCuban
baseRecipe: RecipeNachosCuban
burnTime: 15
- type: microwaveMealRecipe
id: RecipeFriedChicken
@@ -1,25 +0,0 @@
- type: metamorphRecipe
id: NachosCheesy
key: Nachos
result: FoodMealNachosCheesy
rules:
- !type:SequenceLength
range:
min: 1
max: 1
- !type:LastElementHasTags
tags:
- Cheese
- type: metamorphRecipe
id: NachosCuban
key: Nachos
result: FoodMealNachosCuban
rules:
- !type:SequenceLength
range:
min: 1
max: 1
- !type:LastElementHasTags
tags:
- Vegetable # Only vegetable tag for now since the only vegetable we allow on nachos is chili and they don't have another tag
@@ -65,9 +65,9 @@
- !type:RoleTimeRequirement
role: JobChemist
time: 6h
#- !type:RoleTimeRequirement
# role: JobSurgeon
# time: 3h
- !type:RoleTimeRequirement
role: JobSurgeon
time: 3h
- !type:RoleTimeRequirement
role: JobMedicalDoctor
time: 12h
-31
View File
@@ -40,34 +40,3 @@
- !type:AddCompsEffect
components:
- type: NoParadoxClone
- type: trait
id: SyntheticMechanical
name: trait-mechanical-synthetic-name
description: trait-mechanical-synthetic-desc
category: Meta
conditions:
- !type:TraitDependencyCondition
requires:
- Synthetic
effects:
- !type:AddCompsEffect
components:
- type: ESSparkOnHit
count: 2
prob: .32
- type: trait
id: SyntheticIonStormSusceptible
name: trait-ion-storm-susceptible-name
description: trait-ion-storm-susceptible-desc
category: Meta
conditions:
- !type:TraitDependencyCondition
requires:
- Synthetic
effects:
- !type:OverrideCompsEffect
components:
- type: Synth
ionStormAffected: true
@@ -28,4 +28,5 @@
id: Meta
name: trait-category-meta
priority: 50
maxTraits: 2
accentColor: "#eab308" # Yellow
@@ -734,19 +734,3 @@
sounds:
Mew:
collection: FelinidMews
- type: emoteSounds
id: SyntheticEmoteSounds
params:
variation: 0.05
sounds:
Beep:
path: /Audio/Machines/twobeep.ogg
Chime:
path: /Audio/Machines/chime.ogg
Buzz-Two:
path: /Audio/Machines/buzz-two.ogg
Buzz:
path: /Audio/Machines/buzz-sigh.ogg
Ping:
path: /Audio/Effects/Cargo/ping.ogg
-6
View File
@@ -132,9 +132,6 @@
- type: Tag
id: MothroachHide
- type: Tag
id: Nachos # Food sequence key
- type: Tag
id: Natural
@@ -171,9 +168,6 @@
- type: Tag
id: SpeedLoaderSpecial
- type: Tag
id: SyntheticEmotes # Allows characters with the synthetic trait to have silicon emotes.
- type: Tag
id: Vial # Storage Blacklist: CigPackBase
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
<path d="M2.062,12.348C1.979,12.124 1.979,11.876 2.062,11.652C3.719,7.635 7.655,5.001 12,5.001C16.345,5.001 20.281,7.635 21.938,11.652C22.021,11.876 22.021,12.124 21.938,12.348C20.281,16.365 16.345,18.999 12,18.999C7.655,18.999 3.719,16.365 2.062,12.348" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<circle cx="12" cy="12" r="3" style="fill:none;stroke:white;stroke-width:2px;"/>
</svg>

Before

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1,2 +0,0 @@
sample:
filter: true
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
<path d="M15,2L11,2C9.903,2 9,2.903 9,4L9,15C9,16.097 9.903,17 11,17L19,17C20.097,17 21,16.097 21,15L21,8" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M16.706,2.706C16.254,2.253 15.64,1.998 15,2L15,7C15,7.549 15.451,8 16,8L21,8C21.002,7.36 20.747,6.746 20.294,6.294L16.706,2.706Z" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M5,7C3.903,7 3,7.903 3,9L3,20C3,21.097 3.903,22 5,22L13,22C13.714,22 14.375,21.618 14.732,21" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
</svg>

Before

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,2 +0,0 @@
sample:
filter: true
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
<path d="M14.536,21.686C14.612,21.875 14.796,22 15,22C15.213,22 15.404,21.864 15.473,21.662L21.973,2.662C21.993,2.608 22.002,2.551 22.002,2.494C22.002,2.221 21.779,1.998 21.506,1.998C21.449,1.998 21.392,2.007 21.338,2.027L2.338,8.527C2.136,8.596 2,8.787 2,9C2,9.204 2.125,9.388 2.314,9.464L10.244,12.644C10.75,12.847 11.152,13.248 11.356,13.754L14.536,21.686Z" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M21.854,2.147L10.914,13.086" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
</svg>

Before

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

@@ -1,2 +0,0 @@
sample:
filter: true
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
<path d="M4,13L4,4C4,2.903 4.903,2 6,2L14,2C14.64,1.998 15.254,2.253 15.706,2.706L19.294,6.294C19.747,6.746 20.002,7.36 20,8L20,13" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M14,2L14,7C14,7.549 14.451,8 15,8L20,8" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M10,22L10,17" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M14,19L14,17" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M18,20L18,17" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M2,13L22,13" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
<path d="M6,20L6,17" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:2px;"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

@@ -1,2 +0,0 @@
sample:
filter: true
Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

@@ -30,12 +30,6 @@
},
{
"name": "pda"
},
{
"name": "fax"
},
{
"name": "apc"
}
]
}