Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69b6463898 | ||
|
|
2dc3f61cd8 | ||
|
|
164b9be1f9 | ||
|
|
eb95b25eaa | ||
|
|
d3b13a6c83 | ||
|
|
2ab0163598 | ||
|
|
6cdeb3d9cf | ||
|
|
d7543bd24a | ||
|
|
f7f800c439 | ||
|
|
b6ed84325f | ||
|
|
61aee79dc2 | ||
|
|
55fe6026ea | ||
|
|
6dfa12a509 | ||
|
|
485fd14f05 | ||
|
|
031b37ffcb | ||
|
|
06365bdbf0 | ||
|
|
7f18c5f346 | ||
|
|
d407652eb0 | ||
|
|
9108e2c9b5 | ||
|
|
c7ef614f3d | ||
|
|
fa735f7669 |
@@ -12,12 +12,21 @@ 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:
|
||||
|
||||
@@ -24,7 +24,11 @@ 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
|
||||
|
||||
@@ -32,6 +36,10 @@ 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
|
||||
|
||||
@@ -24,6 +24,10 @@ 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
|
||||
@@ -32,6 +36,10 @@ 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
|
||||
|
||||
@@ -20,6 +20,7 @@ jobs:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v4.1.0
|
||||
with:
|
||||
@@ -30,6 +31,12 @@ 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
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ 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
|
||||
@@ -47,6 +51,10 @@ 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
|
||||
|
||||
@@ -17,12 +17,20 @@ 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,13 +1,16 @@
|
||||
<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"/>
|
||||
<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" />
|
||||
|
||||
<BoxContainer Orientation="Vertical" Margin="0 0 10 0">
|
||||
<controls:StripeBack>
|
||||
<PanelContainer>
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -27,6 +28,7 @@ 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;
|
||||
@@ -39,8 +41,10 @@ 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)
|
||||
@@ -50,8 +54,10 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
|
||||
if (_entManager.TryGetComponent<TransformComponent>(mapUid, out var xform))
|
||||
NavMap.MapUid = xform.GridUid;
|
||||
|
||||
else
|
||||
NavMap.Visible = false;
|
||||
// Begin DeltaV - handle navmap visibility based on current position
|
||||
// else
|
||||
// NavMap.Visible = false;
|
||||
// End DeltaV - handle navmap visibility based on current position
|
||||
|
||||
StationName.AddStyleClass("LabelBig");
|
||||
StationName.Text = stationName;
|
||||
@@ -62,6 +68,19 @@ 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();
|
||||
}
|
||||
@@ -69,6 +88,7 @@ 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)
|
||||
@@ -304,7 +324,7 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
|
||||
jobContainer.AddChild(jobLabel);
|
||||
|
||||
// Add user coordinates to the navmap
|
||||
if (coordinates != null && NavMap.Visible && _blipTexture != null)
|
||||
if (coordinates != null && _blipTexture != null) // DeltaV - don't filter the navmap visibility
|
||||
{
|
||||
NavMap.TrackedEntities.TryAdd(sensor.SuitSensorUid,
|
||||
new NavMapBlip
|
||||
|
||||
@@ -56,8 +56,8 @@ public partial class NavMapControl : MapGridControl
|
||||
|
||||
// Constants
|
||||
protected float UpdateTime = 1.0f;
|
||||
protected float MaxSelectableDistance = 10f;
|
||||
protected float MinDragDistance = 5f;
|
||||
public float MaxSelectableDistance = 10f; // DeltaV - accessible to CrewMonitoringShuttleControl
|
||||
public float MinDragDistance = 5f; // DeltaV - accessible to CrewMonitoringShuttleControl
|
||||
protected static float MinDisplayedRange = 8f;
|
||||
protected static float MaxDisplayedRange = 128f;
|
||||
protected static float DefaultDisplayedRange = 48f;
|
||||
@@ -193,6 +193,13 @@ 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);
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<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>
|
||||
@@ -0,0 +1,27 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<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>
|
||||
@@ -0,0 +1,70 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
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 _));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<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>
|
||||
@@ -0,0 +1,92 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<Button xmlns="https://spacestation14.io">
|
||||
<TextureRect Name="TextureRect"
|
||||
TextureScale="0.5 0.5"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Stretch="KeepCentered"/>
|
||||
</Button>
|
||||
@@ -0,0 +1,17 @@
|
||||
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 = 269; // DeltaV - was 218
|
||||
var recipesLimit = 266; // DeltaV - was 218
|
||||
|
||||
if (recipesCount > recipesLimit)
|
||||
{
|
||||
|
||||
@@ -184,6 +184,11 @@ 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);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -90,10 +91,10 @@ public sealed class FaxSystem : EntitySystem
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<FaxMachineComponent, ApcPowerReceiverComponent>();
|
||||
while (query.MoveNext(out var uid, out var fax, out var receiver))
|
||||
var query = EntityQueryEnumerator<FaxMachineComponent>();
|
||||
while (query.MoveNext(out var uid, out var fax)) // DeltaV - faxes aren't necessarily powered
|
||||
{
|
||||
if (!receiver.Powered)
|
||||
if (TryComp<ApcPowerReceiverComponent>(uid, out var receiver) && !receiver.Powered) // DeltaV - faxes aren't necessarily powered
|
||||
continue;
|
||||
|
||||
ProcessPrintingAnimation(uid, frameTime, fax);
|
||||
@@ -392,7 +393,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);
|
||||
var state = new FaxUiState(component.FaxName, component.KnownFaxes, canSend, canCopy, isPaperInserted, component.DestinationFaxAddress, component.SendTimeoutRemaining <= 0); // DeltaV - AI fax
|
||||
_userInterface.SetUiState(uid, FaxUiKey.Key, state);
|
||||
}
|
||||
|
||||
@@ -461,7 +462,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, FaxCopyMessage args)
|
||||
public void Copy(EntityUid uid, FaxMachineComponent? component, BoundUserInterfaceMessage args, EntityUid? item = null) // DeltaV - station AI fax
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
@@ -469,7 +470,7 @@ public sealed class FaxSystem : EntitySystem
|
||||
if (component.SendTimeoutRemaining > 0)
|
||||
return;
|
||||
|
||||
var sendEntity = component.PaperSlot.Item;
|
||||
var sendEntity = item ?? component.PaperSlot.Item; // DeltaV - station AI fax
|
||||
if (sendEntity == null)
|
||||
return;
|
||||
|
||||
@@ -511,7 +512,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, FaxSendMessage args)
|
||||
public void Send(EntityUid uid, FaxMachineComponent? component, BoundUserInterfaceMessage args, EntityUid? item = null) // DeltaV - station AI fax
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
@@ -519,7 +520,7 @@ public sealed class FaxSystem : EntitySystem
|
||||
if (component.SendTimeoutRemaining > 0)
|
||||
return;
|
||||
|
||||
var sendEntity = component.PaperSlot.Item;
|
||||
var sendEntity = item ?? component.PaperSlot.Item; // DeltaV - station AI fax
|
||||
if (sendEntity == null)
|
||||
return;
|
||||
|
||||
@@ -635,6 +636,10 @@ 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,3 +1,4 @@
|
||||
using Content.Server.RoundEnd; // DeltaV
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -25,4 +26,29 @@ 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,6 +30,7 @@ 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;
|
||||
|
||||
@@ -500,12 +501,23 @@ 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.
|
||||
var operatives = EntityQuery<NukeOperativeComponent, MobStateComponent, TransformComponent>(true);
|
||||
|
||||
// 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 operativesAlive = operatives
|
||||
.Where(op =>
|
||||
op.Item3.MapID == shuttleMapId
|
||||
|| op.Item3.MapID == targetStationMap)
|
||||
.Any(op => op.Item2.CurrentState == MobState.Alive && op.Item1.Running);
|
||||
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
|
||||
|
||||
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;
|
||||
using Content.Server.RoundEnd; // DeltaV
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Zombies;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
@@ -114,11 +114,31 @@ 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]);
|
||||
|
||||
if (GetInfectedFraction(false) > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested())
|
||||
|
||||
// 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
|
||||
{
|
||||
foreach (var station in _station.GetStations())
|
||||
{
|
||||
|
||||
@@ -351,7 +351,7 @@ namespace Content.Server.RoundEnd
|
||||
else
|
||||
{
|
||||
RequestRoundEnd(time, null, false, textCall,
|
||||
Loc.GetString(sender));
|
||||
Loc.GetString(sender), cantRecall: true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6,4 +6,41 @@ 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,9 +6,12 @@ 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;
|
||||
@@ -17,6 +20,8 @@ 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)
|
||||
{
|
||||
@@ -26,18 +31,32 @@ 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;
|
||||
|
||||
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);
|
||||
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
|
||||
}
|
||||
// CD - End of synth trait
|
||||
|
||||
|
||||
@@ -7,7 +7,16 @@ namespace Content.Server._CD.Traits;
|
||||
public sealed partial class SynthComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The chance that the synth is alerted of an ion storm
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float AlertChance = 0.3f;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
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;
|
||||
@@ -12,9 +15,13 @@ 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()
|
||||
{
|
||||
@@ -38,5 +45,21 @@ 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,6 +61,39 @@ 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,13 +62,15 @@ 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 class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponent>
|
||||
public sealed partial class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponent>
|
||||
{
|
||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
@@ -172,6 +174,28 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
|
||||
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.
|
||||
@@ -442,17 +466,19 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
|
||||
}
|
||||
}
|
||||
|
||||
private bool CultistsAlive()
|
||||
private int GetCultistsAlive()
|
||||
{
|
||||
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)
|
||||
return true;
|
||||
cultistsAlive++;
|
||||
}
|
||||
|
||||
return false;
|
||||
return cultistsAlive;
|
||||
}
|
||||
|
||||
private void OnMobStateChanged(Entity<CosmicCultComponent> ent, ref MobStateChangedEvent args)
|
||||
@@ -467,14 +493,19 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
|
||||
|
||||
private void CheckForActiveCultists()
|
||||
{
|
||||
if (CultistsAlive())
|
||||
// A lone cultist can't do anything, so check for more than one.
|
||||
if (GetCultistsAlive() > 1)
|
||||
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 _))
|
||||
{
|
||||
ConfirmWinState((ruleUid, ruleComp));
|
||||
cosCultRules.Add((ruleUid, ruleComp));
|
||||
}
|
||||
cosCultRules.ForEach(ConfirmWinState);
|
||||
}
|
||||
|
||||
private void ConfirmWinState(Entity<CosmicCultRuleComponent> ent)
|
||||
@@ -504,8 +535,6 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
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");
|
||||
public SoundSpecifier? PrintSound = new SoundPathSpecifier("/Audio/Machines/printer.ogg"); // DeltaV - nullable
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when fax successfully send message
|
||||
|
||||
@@ -17,13 +17,15 @@ 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)
|
||||
string? destAddress,
|
||||
bool canSendCooldown) // DeltaV - AI fax
|
||||
{
|
||||
DeviceName = deviceName;
|
||||
AvailablePeers = peers;
|
||||
@@ -31,6 +33,7 @@ public sealed class FaxUiState : BoundUserInterfaceState
|
||||
CanSend = canSend;
|
||||
CanCopy = canCopy;
|
||||
DestinationAddress = destAddress;
|
||||
CanSendCooldown = canSendCooldown; // DeltaV - AI fax
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,11 @@ 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;
|
||||
|
||||
@@ -348,7 +353,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) || transform.GridUid == null)
|
||||
if (sensor.Mode == SuitSensorMode.SensorOff || sensor.User == null || !HasComp<MobStateComponent>(sensor.User)) // DeltaV - don't block on grids here
|
||||
return null;
|
||||
|
||||
// try to get mobs id from ID slot
|
||||
|
||||
@@ -276,7 +276,7 @@ public sealed class PaperSystem : EntitySystem
|
||||
_appearance.SetData(entity, PaperVisuals.Status, status, appearance);
|
||||
}
|
||||
|
||||
private void UpdateUserInterface(Entity<PaperComponent> entity)
|
||||
public void UpdateUserInterface(Entity<PaperComponent> entity) // DeltaV - station AI
|
||||
{
|
||||
_uiSystem.SetUiState(entity.Owner, PaperUiKey.Key, new PaperBoundUserInterfaceState(entity.Comp.Content, entity.Comp.StampedBy, entity.Comp.Mode));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Content.Shared._DV.Fax;
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct FaxPrintedEvent(EntityUid Fax);
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
@@ -54,5 +55,11 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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);
|
||||
@@ -1,61 +1,4 @@
|
||||
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.
|
||||
@@ -4412,4 +4355,66 @@
|
||||
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,9 +62,11 @@ 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}. 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-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-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
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
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,3 +2,4 @@ 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,3 +73,9 @@ 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.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
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,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}. You may recall the shuttle to extend the shift.
|
||||
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 = Long-range sensors indicate the nuclear threat has been eliminated. The emergency shuttle is already en route.
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
- type: entity
|
||||
id: OrganDionaNymphStomach
|
||||
parent: MobDionaNymph # DeltaV - Nymph ghost roles
|
||||
parent: MobDionaNymphAccent
|
||||
categories: [ HideSpawnMenu ]
|
||||
name: diona nymph
|
||||
suffix: Stomach
|
||||
@@ -196,7 +196,7 @@
|
||||
|
||||
- type: entity
|
||||
id: OrganDionaNymphLungs
|
||||
parent: MobDionaNymph # DeltaV - Nymph ghost roles
|
||||
parent: MobDionaNymphAccent
|
||||
categories: [ HideSpawnMenu ]
|
||||
name: diona nymph
|
||||
suffix: Lungs
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
transmitFrequencyId: SuitSensor
|
||||
savableAddress: false
|
||||
- type: WirelessNetworkConnection
|
||||
range: 1200
|
||||
- type: StationLimitedNetwork
|
||||
range: 3600 # DeltaV - was 1200
|
||||
# - type: StationLimitedNetwork # DeltaV - this stinks and we don't want it to be limited
|
||||
|
||||
- type: entity
|
||||
abstract: true
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
# End CD - Character Records
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
receiveFrequencyId: CrewMonitor
|
||||
receiveFrequencyId: NTNet # DeltaV - NTNet
|
||||
transmitFrequencyId: ShuttleTimer
|
||||
- type: WirelessNetworkConnection
|
||||
range: 500
|
||||
|
||||
@@ -68,6 +68,10 @@
|
||||
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:
|
||||
@@ -78,12 +82,16 @@
|
||||
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: CrewMonitor
|
||||
transmitFrequencyId: ShuttleTimer
|
||||
receiveFrequencyId: NTNet # DeltaV
|
||||
transmitFrequencyId: NTNet # DeltaV
|
||||
- type: RadarConsole
|
||||
followEntity: false
|
||||
- type: CommunicationsConsole
|
||||
@@ -95,6 +103,27 @@
|
||||
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
|
||||
@@ -534,6 +563,10 @@
|
||||
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,6 +818,7 @@
|
||||
entries:
|
||||
Taco: CheeseTaco
|
||||
Burger: CheeseBurger
|
||||
Nachos: CheeseTaco # DeltaV
|
||||
- type: Item
|
||||
size: Tiny
|
||||
storedOffset: 0,-3
|
||||
|
||||
@@ -114,8 +114,20 @@
|
||||
- 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
|
||||
state: nachos
|
||||
sprite: Objects/Consumable/Food/meals.rsi
|
||||
layers:
|
||||
- state: nachos
|
||||
- map: ["foodSequenceLayers"]
|
||||
- type: Appearance
|
||||
- type: FoodSequenceStartPoint
|
||||
key: Nachos
|
||||
- type: FoodMetamorphableByAdding
|
||||
onlyFinal: false
|
||||
# End DeltaV additions
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
|
||||
@@ -1503,6 +1503,7 @@
|
||||
Taco: ChiliPepper
|
||||
Burger: ChiliPepper
|
||||
Skewer: ChiliPepperSkewer
|
||||
Nachos: ChiliPepper # DeltaV
|
||||
|
||||
- type: entity
|
||||
name: chilly pepper
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
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: CrewMonitor
|
||||
receiveFrequencyId: NTNet # DeltaV - NTNet
|
||||
- type: WirelessNetworkConnection
|
||||
range: 500
|
||||
- type: StationLimitedNetwork
|
||||
# - type: StationLimitedNetwork # DeltaV - don't restrict this unnecessarily
|
||||
- type: ReverseEngineering # Nyano
|
||||
difficulty: 2
|
||||
recipes:
|
||||
|
||||
@@ -951,9 +951,8 @@
|
||||
sprite: _DV/Structures/Doors/Airlocks/Standard/maint.rsi # DeltaV - Changed to our sprites
|
||||
|
||||
- type: entity
|
||||
parent: AirlockMaintRnDLocked # DeltaV - Chapel is in Epistemics
|
||||
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: CrewMonitor
|
||||
receiveFrequencyId: NTNet # DeltaV - NTNet
|
||||
- type: WirelessNetworkConnection
|
||||
range: 1200
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
- type: SingletonDeviceNetServer
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
transmitFrequencyId: CrewMonitor
|
||||
transmitFrequencyId: NTNet # DeltaV - NTNet
|
||||
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
|
||||
# - type: StationLimitedNetwork # DeltaV - make this work for salvies
|
||||
- type: ApcPowerReceiver
|
||||
powerLoad: 200
|
||||
- type: ExtensionCableReceiver
|
||||
|
||||
@@ -71,13 +71,14 @@
|
||||
- type: Climbable
|
||||
delay: 1.6
|
||||
- type: Storage
|
||||
maxItemSize: Normal
|
||||
maxItemSize: Huge # DeltaV - changed to huge (so felinids can fit)
|
||||
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
|
||||
|
||||
@@ -344,11 +344,12 @@
|
||||
category: Vocal
|
||||
icon: Interface/Emotes/buzz.png
|
||||
whitelist:
|
||||
requireAll: true
|
||||
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
|
||||
components:
|
||||
- Vocal
|
||||
tags:
|
||||
- SiliconEmotes
|
||||
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
|
||||
chatMessages: ["chat-emote-msg-buzz"]
|
||||
chatTriggers:
|
||||
- buzzing
|
||||
@@ -397,11 +398,12 @@
|
||||
category: Vocal
|
||||
icon: Interface/Emotes/beep.png
|
||||
whitelist:
|
||||
requireAll: true
|
||||
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
|
||||
components:
|
||||
- Vocal
|
||||
tags:
|
||||
- SiliconEmotes
|
||||
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
|
||||
chatMessages: ["chat-emote-msg-beep"]
|
||||
chatTriggers:
|
||||
- beep
|
||||
@@ -415,11 +417,12 @@
|
||||
category: Vocal
|
||||
icon: Interface/Emotes/chime.png
|
||||
whitelist:
|
||||
requireAll: true
|
||||
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
|
||||
components:
|
||||
- Vocal
|
||||
tags:
|
||||
- SiliconEmotes
|
||||
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
|
||||
chatMessages: ["chat-emote-msg-chime"]
|
||||
chatTriggers:
|
||||
- chime
|
||||
@@ -433,11 +436,12 @@
|
||||
category: Vocal
|
||||
icon: Interface/Emotes/buzztwo.png
|
||||
whitelist:
|
||||
requireAll: true
|
||||
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
|
||||
components:
|
||||
- Vocal
|
||||
tags:
|
||||
- SiliconEmotes
|
||||
- SyntheticEmotes # Delta-V change - added machine emotes for the synthetic trait.
|
||||
chatMessages: ["chat-emote-msg-buzzestwo"]
|
||||
chatTriggers:
|
||||
- buzztwice
|
||||
@@ -457,14 +461,15 @@
|
||||
category: Vocal
|
||||
icon: Interface/Emotes/ping.png
|
||||
whitelist:
|
||||
requireAll: true
|
||||
# requireAll: true # Delta-V change - makes the whitelist become an any check instead of requiring everything.
|
||||
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,3 +160,17 @@
|
||||
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,5 +61,3 @@
|
||||
- id: ShelterCapsuleBar
|
||||
cost: 10000
|
||||
# TODO: mining drone stuff
|
||||
- id: MedicalTrackingImplanter
|
||||
cost: 10000
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
content:
|
||||
- ClothingBeltSalvageWebbing
|
||||
- ShelterCapsule
|
||||
- MedicalTrackingImplanter
|
||||
- NFWeaponHoloflareGun
|
||||
|
||||
# TODO: mining drone
|
||||
|
||||
@@ -16,27 +16,34 @@
|
||||
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
|
||||
- id: TowelColorYellow
|
||||
- id: TowelColorMaroon
|
||||
- id: TowelColorSilver
|
||||
- !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
|
||||
- !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,14 +22,6 @@
|
||||
- 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,21 +41,6 @@
|
||||
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: CrewMonitor
|
||||
receiveFrequencyId: NTNet # DeltaV - NTNet
|
||||
- type: WirelessNetworkConnection
|
||||
range: 500
|
||||
- type: StationLimitedNetwork
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
- type: SingletonDeviceNetServer
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
transmitFrequencyId: CrewMonitor
|
||||
transmitFrequencyId: NTNet # DeltaV - NTNet
|
||||
receiveFrequencyId: SuitSensor
|
||||
autoConnect: false
|
||||
- type: WirelessNetworkConnection
|
||||
|
||||
@@ -47,55 +47,6 @@
|
||||
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
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
- 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
|
||||
|
||||
@@ -40,3 +40,34 @@
|
||||
- !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,5 +28,4 @@
|
||||
id: Meta
|
||||
name: trait-category-meta
|
||||
priority: 50
|
||||
maxTraits: 2
|
||||
accentColor: "#eab308" # Yellow
|
||||
|
||||
@@ -734,3 +734,19 @@
|
||||
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
|
||||
|
||||
@@ -132,6 +132,9 @@
|
||||
- type: Tag
|
||||
id: MothroachHide
|
||||
|
||||
- type: Tag
|
||||
id: Nachos # Food sequence key
|
||||
|
||||
- type: Tag
|
||||
id: Natural
|
||||
|
||||
@@ -168,6 +171,9 @@
|
||||
- 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
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 864 B |
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,2 @@
|
||||
sample:
|
||||
filter: true
|
||||
@@ -0,0 +1,7 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 1019 B |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,2 @@
|
||||
sample:
|
||||
filter: true
|
||||
@@ -0,0 +1,6 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 996 B |
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,2 @@
|
||||
sample:
|
||||
filter: true
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,2 @@
|
||||
sample:
|
||||
filter: true
|
||||
|
After Width: | Height: | Size: 364 B |
|
After Width: | Height: | Size: 500 B |
@@ -30,6 +30,12 @@
|
||||
},
|
||||
{
|
||||
"name": "pda"
|
||||
},
|
||||
{
|
||||
"name": "fax"
|
||||
},
|
||||
{
|
||||
"name": "apc"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||