From 58e500d254ad30fd181469f956c0a90d86359f01 Mon Sep 17 00:00:00 2001 From: Vanessa <908648+ShepardToTheStars@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:37:33 -0600 Subject: [PATCH] CentComm Shipyard (#5172) * Added CentComm shipyard console. Brought some things in Shipyard console up to modern standards. * More shipyard stuff * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * PR Feedback --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../Shipyard/UI/ShipyardConsoleMenu.xaml.cs | 64 +++++++++++-------- .../_DV/Shipyard/UI/VesselRow.xaml.cs | 7 +- .../Tests/_DV/ShipyardTest.cs | 8 ++- .../_DV/Shipyard/ShipyardConsoleSystem.cs | 48 +++++++++----- Content.Server/_DV/Shipyard/ShipyardSystem.cs | 41 ++++++------ .../Prototypes/VesselCategoryPrototype.cs | 15 +++++ .../_DV/Shipyard/ShipyardConsoleComponent.cs | 21 +++++- .../en-US/_DV/shipyard/shipyard-console.ftl | 21 +++++- .../en-US/cargo/cargo-console-component.ftl | 2 +- .../_DV/Catalog/Shipyard/categories.yml | 20 ++++++ .../_DV/Catalog/Shipyard/centcomm.yml | 3 + .../Prototypes/_DV/Catalog/Shipyard/ert.yml | 12 ++++ .../_DV/Catalog/Shipyard/military.yml | 1 + .../Structures/Machines/computers.yml | 41 +++++++++++- 14 files changed, 229 insertions(+), 75 deletions(-) create mode 100644 Resources/Prototypes/_DV/Catalog/Shipyard/centcomm.yml create mode 100644 Resources/Prototypes/_DV/Catalog/Shipyard/ert.yml diff --git a/Content.Client/_DV/Shipyard/UI/ShipyardConsoleMenu.xaml.cs b/Content.Client/_DV/Shipyard/UI/ShipyardConsoleMenu.xaml.cs index ce49f2bd4a4..c38e5ab4ce4 100644 --- a/Content.Client/_DV/Shipyard/UI/ShipyardConsoleMenu.xaml.cs +++ b/Content.Client/_DV/Shipyard/UI/ShipyardConsoleMenu.xaml.cs @@ -19,10 +19,12 @@ public sealed partial class ShipyardConsoleMenu : FancyWindow public event Action? OnPurchased; private readonly List _vessels = []; - private readonly List _categories = []; + private readonly List _categories = []; public Entity Console; - private string? _category; + + // The currently selected category + private ProtoId? _category; public ShipyardConsoleMenu(EntityUid console, IPrototypeManager proto, IEntityManager entMan, IPlayerManager player, AccessReaderSystem access, EntityWhitelistSystem whitelist) { @@ -33,46 +35,44 @@ public sealed partial class ShipyardConsoleMenu : FancyWindow _access = access; _player = player; + _categories.Clear(); + foreach (var vesselCategoryProto in Console.Comp.Categories) + { + if (proto.Resolve(vesselCategoryProto, out var vesselCategory)) + _categories.Add(vesselCategory); + } + // don't include ships that aren't allowed by whitelist, server won't accept them anyway foreach (var vessel in proto.EnumeratePrototypes()) { if (whitelist.IsWhitelistPassOrNull(vessel.Whitelist, console)) _vessels.Add(vessel); } + _vessels.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase)); - // only list categories in said ships - foreach (var vessel in _vessels) - { - foreach (var category in vessel.Categories) - { - if (!_categories.Contains(category)) - _categories.Add(category); - } - } - - _categories.Sort(); // inserting here and not adding at the start so it doesn't get affected by sort - _categories.Insert(0, Loc.GetString("cargo-console-menu-populate-categories-all-text")); - PopulateCategories(); + PopulateCategories(Console); - SearchBar.OnTextChanged += _ => PopulateProducts(); + SearchBar.OnTextChanged += _ => PopulateProducts(Console); Categories.OnItemSelected += args => { - _category = args.Id == 0 ? null : _categories[args.Id]; + _category = _categories[args.Id]; Categories.SelectId(args.Id); - PopulateProducts(); + PopulateProducts(Console); }; + + PopulateProducts(Console); } /// /// Populates the list of products that will actually be shown, using the current filters. /// - private void PopulateProducts() + private void PopulateProducts(Entity entity) { Vessels.RemoveAllChildren(); - var access = _player.LocalSession?.AttachedEntity is {} player + var access = _player.LocalSession?.AttachedEntity is { } player && _access.IsAllowed(player, Console); var search = SearchBar.Text.Trim().ToLowerInvariant(); @@ -80,10 +80,11 @@ public sealed partial class ShipyardConsoleMenu : FancyWindow { if (search.Length != 0 && !vessel.Name.Contains(search, StringComparison.InvariantCultureIgnoreCase)) continue; - if (_category != null && !vessel.Categories.Contains(_category)) + + if (_category != null && !vessel.Categories.Contains(_category.Value.Id)) continue; - var vesselEntry = new VesselRow(vessel, access); + var vesselEntry = new VesselRow(vessel, access, isFree: !entity.Comp.UseStationFunds); vesselEntry.OnPurchasePressed += () => OnPurchased?.Invoke(vessel.ID); Vessels.AddChild(vesselEntry); } @@ -92,18 +93,29 @@ public sealed partial class ShipyardConsoleMenu : FancyWindow /// /// Populates the list categories that will actually be shown, using the current filters. /// - private void PopulateCategories() + private void PopulateCategories(Entity entity) { Categories.Clear(); - foreach (var category in _categories) + // Guh, there's gotta be an easier way to select a category by default... + var selectedId = 0; // Default to the first category. May get overridden later. + for (var i = 0; i < _categories.Count; i++) { - Categories.AddItem(category); + Categories.AddItem(_categories[i].LocalizedName, i); + + if (entity.Comp.DefaultCategory.HasValue && entity.Comp.DefaultCategory.Value.Id.Equals(_categories[i].ID, StringComparison.CurrentCultureIgnoreCase)) + selectedId = i; + } + + if (selectedId >= 0 && selectedId < _categories.Count) + { + _category = _categories[selectedId]; + Categories.SelectId(selectedId); } } public void UpdateState(ShipyardConsoleState state) { BankAccountLabel.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", state.Balance.ToString())); - PopulateProducts(); + PopulateProducts(Console); } } diff --git a/Content.Client/_DV/Shipyard/UI/VesselRow.xaml.cs b/Content.Client/_DV/Shipyard/UI/VesselRow.xaml.cs index aa1f0a1c205..2a8f1e62f7b 100644 --- a/Content.Client/_DV/Shipyard/UI/VesselRow.xaml.cs +++ b/Content.Client/_DV/Shipyard/UI/VesselRow.xaml.cs @@ -12,7 +12,7 @@ public sealed partial class VesselRow : PanelContainer { public event Action? OnPurchasePressed; - public VesselRow(VesselPrototype vessel, bool access) + public VesselRow(VesselPrototype vessel, bool access = false, bool isFree = false) { RobustXamlLoader.Load(this); @@ -24,6 +24,9 @@ public sealed partial class VesselRow : PanelContainer Purchase.Disabled = !access; Purchase.OnPressed += _ => OnPurchasePressed?.Invoke(); - Price.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", vessel.Price)); + if (isFree) + Purchase.Text = Loc.GetString("shipyard-console-price-free"); + else + Purchase.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", vessel.Price)); } } diff --git a/Content.IntegrationTests/Tests/_DV/ShipyardTest.cs b/Content.IntegrationTests/Tests/_DV/ShipyardTest.cs index 4df33d1af50..ed8cdd14a4a 100644 --- a/Content.IntegrationTests/Tests/_DV/ShipyardTest.cs +++ b/Content.IntegrationTests/Tests/_DV/ShipyardTest.cs @@ -28,7 +28,9 @@ public sealed class ShipyardTest { foreach (var vessel in proto.EnumeratePrototypes()) { - var shuttle = shipyard.TryCreateShuttle(vessel.Path); + var shuttleCreated = shipyard.TryCreateShuttle(vessel.Path, out var shuttle); + + Assert.That(shuttleCreated, Is.True, $"TryCreateShuttle returned false for {vessel.ID}!"); Assert.That(shuttle, Is.Not.Null, $"Failed to spawn shuttle {vessel.ID}!"); var value = pricing.AppraiseGrid(shuttle.Value); @@ -57,7 +59,9 @@ public sealed class ShipyardTest { foreach (var vessel in proto.EnumeratePrototypes()) { - var shuttle = shipyard.TryCreateShuttle(vessel.Path); + var shuttleCreated = shipyard.TryCreateShuttle(vessel.Path, out var shuttle); + + Assert.That(shuttleCreated, Is.True, $"TryCreateShuttle returned false for {vessel.ID}!"); Assert.That(shuttle, Is.Not.Null, $"Failed to spawn shuttle {vessel.ID}!"); var console = FindComponent(entities, shuttle.Value); diff --git a/Content.Server/_DV/Shipyard/ShipyardConsoleSystem.cs b/Content.Server/_DV/Shipyard/ShipyardConsoleSystem.cs index f669f514d18..89501a96de1 100644 --- a/Content.Server/_DV/Shipyard/ShipyardConsoleSystem.cs +++ b/Content.Server/_DV/Shipyard/ShipyardConsoleSystem.cs @@ -1,8 +1,8 @@ -using Content.Server.Cargo.Components; using Content.Server.Cargo.Systems; using Content.Server.Radio.EntitySystems; using Content.Server.Station.Systems; using Content.Shared.Cargo.Components; +using Content.Shared.Popups; using Content.Shared.Shipyard; using Content.Shared.Shipyard.Prototypes; using Content.Shared.Whitelist; @@ -39,29 +39,43 @@ public sealed class ShipyardConsoleSystem : SharedShipyardConsoleSystem if (_whitelist.IsWhitelistFail(vessel.Whitelist, ent)) return; - if (GetBankAccount(ent) is not {} bank) - return; - - if (bank.Comp.Accounts[bank.Comp.PrimaryAccount] < vessel.Price) + var purchasingGrid = Transform(ent).GridUid; + Entity? bankAccount = null; + if (ent.Comp.UseStationFunds) { - var popup = Loc.GetString("cargo-console-insufficient-funds", ("cost", vessel.Price)); - Popup.PopupEntity(popup, ent, user); - Audio.PlayPvs(ent.Comp.DenySound, ent); - return; + bankAccount = GetBankAccount(ent); + if (!bankAccount.HasValue) + { + var popup = Loc.GetString("shipyard-console-error-bank"); + Popup.PopupEntity(popup, ent, user, PopupType.SmallCaution); + Audio.PlayPvs(ent.Comp.DenySound, ent); + return; + } + + if (bankAccount.Value.Comp.Accounts[bankAccount.Value.Comp.PrimaryAccount] < vessel.Price) + { + var popup = Loc.GetString("cargo-console-insufficient-funds", ("cost", vessel.Price)); + Popup.PopupEntity(popup, ent, user, PopupType.SmallCaution); + Audio.PlayPvs(ent.Comp.DenySound, ent); + return; + } + + purchasingGrid = bankAccount.Value.Owner; } - if (_shipyard.TrySendShuttle(bank.Owner, vessel.Path) is not {} shuttle) + if (purchasingGrid is not { } grid + || !_shipyard.TrySendShuttle(grid, vessel.Path, out var shuttle)) { var popup = Loc.GetString("shipyard-console-error"); - Popup.PopupEntity(popup, ent, user); + Popup.PopupEntity(popup, ent, user, PopupType.SmallCaution); Audio.PlayPvs(ent.Comp.DenySound, ent); return; } - _meta.SetEntityName(shuttle, $"{vessel.Name} {_random.Next(1000):000}"); - - _cargo.UpdateBankAccount((bank, bank), -vessel.Price, _cargo.CreateAccountDistribution(bank)); + if (bankAccount.HasValue) + _cargo.UpdateBankAccount(bankAccount.Value.Owner, -vessel.Price, _cargo.CreateAccountDistribution(bankAccount.Value)); + _meta.SetEntityName(shuttle.Value, $"{vessel.Name} {_random.Next(1000):000}"); var message = Loc.GetString("shipyard-console-docking", ("vessel", vessel.Name)); _radio.SendRadioMessage(ent, message, ent.Comp.Channel, ent); Audio.PlayPvs(ent.Comp.ConfirmSound, ent); @@ -76,7 +90,7 @@ public sealed class ShipyardConsoleSystem : SharedShipyardConsoleSystem if (!_ui.IsUiOpen(uid, ShipyardConsoleUiKey.Key)) return; - if (GetBankAccount(uid) is {} bank) + if (GetBankAccount(uid) is { } bank) UpdateUI(uid, args.Balance[bank.Comp.PrimaryAccount]); } } @@ -88,7 +102,7 @@ public sealed class ShipyardConsoleSystem : SharedShipyardConsoleSystem private void UpdateUI(EntityUid uid) { - if (GetBankAccount(uid) is {} bank) + if (GetBankAccount(uid) is { } bank) UpdateUI(uid, bank.Comp.Accounts[bank.Comp.PrimaryAccount]); } @@ -103,7 +117,7 @@ public sealed class ShipyardConsoleSystem : SharedShipyardConsoleSystem private Entity? GetBankAccount(EntityUid console) { - if (_station.GetOwningStation(console) is not {} station) + if (_station.GetOwningStation(console) is not { } station) return null; if (!TryComp(station, out var bank)) diff --git a/Content.Server/_DV/Shipyard/ShipyardSystem.cs b/Content.Server/_DV/Shipyard/ShipyardSystem.cs index 792f1655888..8702ff0c8f0 100644 --- a/Content.Server/_DV/Shipyard/ShipyardSystem.cs +++ b/Content.Server/_DV/Shipyard/ShipyardSystem.cs @@ -1,13 +1,12 @@ using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Systems; -using Content.Server.Station.Systems; using Content.Shared._DV.CCVars; -using Content.Shared.Station.Components; using Content.Shared.Tag; using Robust.Shared.EntitySerialization.Systems; using Robust.Shared.Configuration; using Robust.Shared.Prototypes; using Robust.Shared.Utility; +using System.Diagnostics.CodeAnalysis; namespace Content.Server.Shipyard; @@ -21,7 +20,6 @@ public sealed class ShipyardSystem : EntitySystem [Dependency] private readonly MapLoaderSystem _mapLoader = default!; [Dependency] private readonly SharedMapSystem _map = default!; [Dependency] private readonly ShuttleSystem _shuttle = default!; - [Dependency] private readonly StationSystem _station = default!; public ProtoId DockTag = "DockShipyard"; @@ -37,50 +35,47 @@ public sealed class ShipyardSystem : EntitySystem /// /// Creates a ship from its yaml path in the shipyard. /// - public Entity? TryCreateShuttle(ResPath path) + public bool TryCreateShuttle(ResPath path, [NotNullWhen(true)] out Entity? shuttle) { + shuttle = null; if (!Enabled) - return null; + return false; var map = _map.CreateMap(out var mapId); if (!_mapLoader.TryLoadGrid(mapId, path, out var grid)) { Log.Error($"Failed to load shuttle {path}"); Del(map); - return null; + return false; } if (!TryComp(grid, out var comp)) { Log.Error($"Shuttle {path}'s grid was missing ShuttleComponent"); Del(map); - return null; + return false; } _map.SetPaused(map, false); _mapDeleterShuttle.Enable(grid.Value); - return (grid.Value, comp); + shuttle = (grid.Value, comp); + return true; } /// - /// Adds a ship to the shipyard and attempts to ftl-dock it to the given station. + /// Adds a ship to the shipyard and attempts to ftl-dock it to the given grid. /// - public Entity? TrySendShuttle(Entity station, ResPath path) + public bool TrySendShuttle(Entity shuttleDestination, ResPath path, [NotNullWhen(true)] out Entity? shuttle) { - if (!Resolve(station, ref station.Comp)) - return null; + shuttle = null; + if (!Resolve(shuttleDestination, ref shuttleDestination.Comp)) + return false; - if (_station.GetLargestGrid(station) is not {} grid) - { - Log.Error($"Station {ToPrettyString(station):station} had no largest grid to FTL to"); - return null; - } + if (!TryCreateShuttle(path, out shuttle)) + return false; - if (TryCreateShuttle(path) is not {} shuttle) - return null; - - Log.Info($"Shuttle {path} was spawned for {ToPrettyString(station):station}, FTLing to {grid}"); - _shuttle.FTLToDock(shuttle, shuttle.Comp, grid, priorityTag: DockTag); - return shuttle; + Log.Info($"Shuttle {path} was spawned for {ToPrettyString(shuttleDestination):station}"); + _shuttle.FTLToDock(shuttle.Value, shuttle.Value.Comp, shuttleDestination, priorityTag: DockTag); + return true; } } diff --git a/Content.Shared/_DV/Shipyard/Prototypes/VesselCategoryPrototype.cs b/Content.Shared/_DV/Shipyard/Prototypes/VesselCategoryPrototype.cs index c9e55c4643d..a00d8817063 100644 --- a/Content.Shared/_DV/Shipyard/Prototypes/VesselCategoryPrototype.cs +++ b/Content.Shared/_DV/Shipyard/Prototypes/VesselCategoryPrototype.cs @@ -9,6 +9,21 @@ namespace Content.Shared.Shipyard.Prototypes; [Prototype("vesselCategory")] public sealed class VesselCategoryPrototype : IPrototype { + /// + /// The unique ID for the vessel category. + /// [ViewVariables, IdDataField] public string ID { get; } = default!; + + /// + /// The LocId containing the localization ID of the category name. + /// + [DataField(required: true)] + private LocId Name { get; set; } + + /// + /// Gets the localized string from the LocID set by + /// + [ViewVariables(VVAccess.ReadOnly)] + public string LocalizedName => Loc.GetString(Name); } diff --git a/Content.Shared/_DV/Shipyard/ShipyardConsoleComponent.cs b/Content.Shared/_DV/Shipyard/ShipyardConsoleComponent.cs index c3887e5709a..621339817cc 100644 --- a/Content.Shared/_DV/Shipyard/ShipyardConsoleComponent.cs +++ b/Content.Shared/_DV/Shipyard/ShipyardConsoleComponent.cs @@ -1,4 +1,5 @@ using Content.Shared.Radio; +using Content.Shared.Shipyard.Prototypes; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; @@ -8,7 +9,7 @@ namespace Content.Shared.Shipyard; /// /// Component for the shipyard console. /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedShipyardConsoleSystem))] +[RegisterComponent, NetworkedComponent] public sealed partial class ShipyardConsoleComponent : Component { /// @@ -28,4 +29,22 @@ public sealed partial class ShipyardConsoleComponent : Component /// [DataField] public ProtoId Channel = "Command"; + + /// + /// If false, shuttles won't use the station's bank and will be available at no cost. + /// + [DataField] + public bool UseStationFunds = true; + + /// + /// The list of selectable categories. Note that this does not filter ships, just allows some categories to be hidden from crew (e.g. CentComm, ERT). Does not need to include All. + /// + [DataField(required: true)] + public List> Categories = new(); + + /// + /// If not null, will attempt to set the category when opening the shipyard console. + /// + [DataField] + public ProtoId? DefaultCategory = null; } diff --git a/Resources/Locale/en-US/_DV/shipyard/shipyard-console.ftl b/Resources/Locale/en-US/_DV/shipyard/shipyard-console.ftl index 50917d8f8b2..f7a2096e5ed 100644 --- a/Resources/Locale/en-US/_DV/shipyard/shipyard-console.ftl +++ b/Resources/Locale/en-US/_DV/shipyard/shipyard-console.ftl @@ -1,5 +1,22 @@ shipyard-console-menu-title = Shipyard Console -shipyard-console-error = Temporary embargo is in place, try later? -shipyard-console-docking = {$vessel} is en route to the station, eta 60 seconds. +shipyard-console-error = Temporary embargo is in place. Try again later? +shipyard-console-error-bank = Cannot access station funds from this location. +shipyard-console-docking = {$vessel} is en route to the station. ETA approximately 60 seconds. shipyard-console-purchase = Purchase +shipyard-console-price-free = Free + +# Vessel Categories +vessel-category-civilian = Civilian +vessel-category-military = Military +vessel-category-experimental = Experimental +vessel-category-small = Small +vessel-category-medium = Medium +vessel-category-large = Large +vessel-category-medical = Medical +vessel-category-mining = Mining +vessel-category-research = Research +vessel-category-shipping = Shipping +vessel-category-transport = Transport +vessel-category-centcomm = CentComm +vessel-category-ert = ERT diff --git a/Resources/Locale/en-US/cargo/cargo-console-component.ftl b/Resources/Locale/en-US/cargo/cargo-console-component.ftl index bc28306db11..2a6fe5ceae4 100644 --- a/Resources/Locale/en-US/cargo/cargo-console-component.ftl +++ b/Resources/Locale/en-US/cargo/cargo-console-component.ftl @@ -38,7 +38,7 @@ cargo-console-station-not-found = No available station cargo-console-invalid-product = Invalid product ID cargo-console-too-many = Too many approved orders cargo-console-snip-snip = Order trimmed to capacity -cargo-console-insufficient-funds = Insufficient funds (require {$cost}) +cargo-console-insufficient-funds = Insufficient funds (requires ${$cost}) cargo-console-unfulfilled = No room to fulfill order cargo-console-trade-station = Sent to {$destination} cargo-console-unlock-approved-order-broadcast = [bold]{$productName} x{$orderAmount}[/bold], which cost [bold]{$cost}[/bold], was approved by [bold]{$approver}[/bold] diff --git a/Resources/Prototypes/_DV/Catalog/Shipyard/categories.yml b/Resources/Prototypes/_DV/Catalog/Shipyard/categories.yml index 2d11d3fae80..4cf186c4835 100644 --- a/Resources/Prototypes/_DV/Catalog/Shipyard/categories.yml +++ b/Resources/Prototypes/_DV/Catalog/Shipyard/categories.yml @@ -1,35 +1,55 @@ # class - type: vesselCategory id: Civilian + name: vessel-category-civilian - type: vesselCategory id: Military + name: vessel-category-military - type: vesselCategory id: Experimental + name: vessel-category-experimental # size - type: vesselCategory id: Small + name: vessel-category-small - type: vesselCategory id: Medium + name: vessel-category-medium - type: vesselCategory id: Large + name: vessel-category-large # purpose - type: vesselCategory id: Medical + name: vessel-category-medical - type: vesselCategory id: Mining + name: vessel-category-mining - type: vesselCategory id: Research + name: vessel-category-research - type: vesselCategory id: Shipping + name: vessel-category-shipping - type: vesselCategory id: Transport + name: vessel-category-transport + +# admin +- type: vesselCategory + id: CentComm + name: vessel-category-centcomm + +- type: vesselCategory + id: ERT + name: vessel-category-ert diff --git a/Resources/Prototypes/_DV/Catalog/Shipyard/centcomm.yml b/Resources/Prototypes/_DV/Catalog/Shipyard/centcomm.yml new file mode 100644 index 00000000000..f917c6ff8be --- /dev/null +++ b/Resources/Prototypes/_DV/Catalog/Shipyard/centcomm.yml @@ -0,0 +1,3 @@ +# Ships put in here still need to have a price associated with them due to the arbitrage tests. +# The CentComm console won't charge for them so just put like a million spesos or something +# in the case that the station does see it in their console (could be a random bug, idk!) diff --git a/Resources/Prototypes/_DV/Catalog/Shipyard/ert.yml b/Resources/Prototypes/_DV/Catalog/Shipyard/ert.yml new file mode 100644 index 00000000000..4dab88b2482 --- /dev/null +++ b/Resources/Prototypes/_DV/Catalog/Shipyard/ert.yml @@ -0,0 +1,12 @@ +# Ships put in here still need to have a price associated with them due to the arbitrage tests. +# The CentComm console won't charge for them so just put like a million spesos or something +# in the case that the station does see it in their console (could be a random bug, idk!) + +- type: vessel + id: Ares + name: NT-Ares + description: A small ship, outfitted with some combat supplies for those extra dangerous ERT situations. Combat supplies include a Hristov, 4 hyperzine injectors, a handheld crew monitor, and an experimenal RCD. + price: 1000000 + path: /Maps/Shuttles/AdminSpawn/ERT-Small-Deathsquad.yml + categories: + - ERT diff --git a/Resources/Prototypes/_DV/Catalog/Shipyard/military.yml b/Resources/Prototypes/_DV/Catalog/Shipyard/military.yml index 6f728aac80c..322bade2db6 100644 --- a/Resources/Prototypes/_DV/Catalog/Shipyard/military.yml +++ b/Resources/Prototypes/_DV/Catalog/Shipyard/military.yml @@ -8,3 +8,4 @@ - Military - Small - Transport + - ERT diff --git a/Resources/Prototypes/_DV/Entities/Structures/Machines/computers.yml b/Resources/Prototypes/_DV/Entities/Structures/Machines/computers.yml index b34fc27accd..1f66e05e3a4 100644 --- a/Resources/Prototypes/_DV/Entities/Structures/Machines/computers.yml +++ b/Resources/Prototypes/_DV/Entities/Structures/Machines/computers.yml @@ -2,9 +2,21 @@ parent: BaseComputer id: ComputerShipyard name: shipyard console - description: Used to purchase and sell shuttles + description: Used to purchase shuttles for the station. components: - type: ShipyardConsole + categories: + - Transport + - Shipping + - Medical + - Mining + - Civilian + - Research + - Military + - Experimental + - Small + - Medium + - Large - type: AccessReader access: [[ Captain ]] - type: ActivatableUI @@ -30,6 +42,33 @@ - map: ["computerLayerKeys"] state: tech_key +- type: entity + parent: ComputerShipyard + id: ComputerShipyardAdmin + name: central command shipyard console + description: Used to purchase shuttles for CentComm personnel and agents to use. The costs are heavily subsidized and small amounts of funds are laundered from all of NanoTrasen's stations, making ships purchased here essentially free. + components: + - type: ShipyardConsole + channel: CentCom + useStationFunds: false + categories: + - CentComm + - ERT + - Transport + - Shipping + - Medical + - Mining + - Civilian + - Research + - Military + - Experimental + - Small + - Medium + - Large + defaultCategory: ERT # Probably switch to CentComm once we have ships in that category + - type: AccessReader + access: [[ CentralCommand ]] + - type: entity abstract: true parent: BaseComputer