diff --git a/Content.Client/MassMedia/Ui/MiniArticleCardControl.xaml b/Content.Client/MassMedia/Ui/MiniArticleCardControl.xaml new file mode 100644 index 0000000000..528cbef31a --- /dev/null +++ b/Content.Client/MassMedia/Ui/MiniArticleCardControl.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/Content.Client/MassMedia/Ui/MiniArticleCardControl.xaml.cs b/Content.Client/MassMedia/Ui/MiniArticleCardControl.xaml.cs new file mode 100644 index 0000000000..86058959b4 --- /dev/null +++ b/Content.Client/MassMedia/Ui/MiniArticleCardControl.xaml.cs @@ -0,0 +1,26 @@ +using Content.Client.Message; +using Content.Shared.Research.Prototypes; +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Client.MassMedia.Ui; + +[GenerateTypedNameReferences] +public sealed partial class MiniArticleCardControl : Control +{ + public Action? OnDeletePressed; + public int ArtcileNum; + + public MiniArticleCardControl(string name) + { + RobustXamlLoader.Load(this); + + Name.SetMarkup(name); + + Delete.OnPressed += _ => OnDeletePressed?.Invoke(); + } +} diff --git a/Content.Client/MassMedia/Ui/NewsReadBoundUserInterface.cs b/Content.Client/MassMedia/Ui/NewsReadBoundUserInterface.cs new file mode 100644 index 0000000000..98ffd44359 --- /dev/null +++ b/Content.Client/MassMedia/Ui/NewsReadBoundUserInterface.cs @@ -0,0 +1,58 @@ +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Content.Shared.MassMedia.Components; +using Robust.Shared.Timing; + +namespace Content.Client.MassMedia.Ui +{ + [UsedImplicitly] + public sealed class NewsReadBoundUserInterface : BoundUserInterface + { + [Dependency] private readonly IGameTiming _gameTiming = default!; + + [ViewVariables] + private NewsReadMenu? _menu; + + [ViewVariables] + private string _windowName = Loc.GetString("news-read-ui-default-title"); + + public NewsReadBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + _menu = new NewsReadMenu(_windowName); + + _menu.OpenCentered(); + _menu.OnClose += Close; + + _menu.NextButtonPressed += () => SendMessage(new NewsReadNextMessage()); + _menu.PastButtonPressed += () => SendMessage(new NewsReadPrevMessage()); + + SendMessage(new NewsReadArticleRequestMessage()); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Close(); + _menu?.Dispose(); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + if (_menu == null) + return; + + if (state is NewsReadBoundUserInterfaceState cast) + _menu.UpdateUI(cast.Article, cast.TargetNum, cast.TotalNum); + if (state is NewsReadEmptyBoundUserInterfaceState) + _menu.UpdateEmptyUI(); + } + } +} diff --git a/Content.Client/MassMedia/Ui/NewsReadMenu.xaml b/Content.Client/MassMedia/Ui/NewsReadMenu.xaml new file mode 100644 index 0000000000..b4c3698946 --- /dev/null +++ b/Content.Client/MassMedia/Ui/NewsReadMenu.xaml @@ -0,0 +1,52 @@ + + + + + + + diff --git a/Content.Client/MassMedia/Ui/NewsWriteMenu.xaml.cs b/Content.Client/MassMedia/Ui/NewsWriteMenu.xaml.cs new file mode 100644 index 0000000000..788f31b9c9 --- /dev/null +++ b/Content.Client/MassMedia/Ui/NewsWriteMenu.xaml.cs @@ -0,0 +1,42 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; +using Content.Shared.MassMedia.Systems; + +namespace Content.Client.MassMedia.Ui; + +[GenerateTypedNameReferences] +public sealed partial class NewsWriteMenu : DefaultWindow +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + public event Action? ShareButtonPressed; + public event Action? DeleteButtonPressed; + + public NewsWriteMenu(string name) + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + if (Window != null) + Window.Title = name; + + Share.OnPressed += _ => ShareButtonPressed?.Invoke(); + } + + public void UpdateUI(NewsArticle[] articles) + { + ArticleCardsContainer.Children.Clear(); + + for (int i = 0; i < articles.Length; i++) + { + var mini = new MiniArticleCardControl(articles[i].Name); + mini.ArtcileNum = i; + mini.OnDeletePressed += () => DeleteButtonPressed?.Invoke(mini.ArtcileNum); + + ArticleCardsContainer.AddChild(mini); + } + } +} diff --git a/Content.Client/PDA/PdaBoundUserInterface.cs b/Content.Client/PDA/PdaBoundUserInterface.cs index bd23d5ea55..2238948cce 100644 --- a/Content.Client/PDA/PdaBoundUserInterface.cs +++ b/Content.Client/PDA/PdaBoundUserInterface.cs @@ -73,6 +73,12 @@ namespace Content.Client.PDA SendMessage(new PdaLockUplinkMessage()); }; + _menu.NewsReadButton.OnPressed += _ => + { + SendMessage(new PdaOpenNewsMessage()); + }; + + _menu.OnProgramItemPressed += ActivateCartridge; _menu.OnInstallButtonPressed += InstallCartridge; _menu.OnUninstallButtonPressed += UninstallCartridge; diff --git a/Content.Client/PDA/PdaMenu.xaml b/Content.Client/PDA/PdaMenu.xaml index a06032d6d2..f6b07d1ca6 100644 --- a/Content.Client/PDA/PdaMenu.xaml +++ b/Content.Client/PDA/PdaMenu.xaml @@ -1,4 +1,4 @@ - + Articles = new List(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnWriteUiMessage); + SubscribeLocalEvent(OnWriteUiMessage); + SubscribeLocalEvent(OnWriteUiMessage); + SubscribeLocalEvent(OnReadUiMessage); + SubscribeLocalEvent(OnReadUiMessage); + SubscribeLocalEvent(OnReadUiMessage); + + SubscribeLocalEvent(OnRoundRestart); + } + + private void OnRoundRestart(RoundRestartCleanupEvent ev) + { + if (Articles != null) Articles.Clear(); + } + + public void ToggleUi(EntityUid user, EntityUid deviceEnt, NewsReadComponent? component) + { + if (!Resolve(deviceEnt, ref component)) + return; + + if (!TryComp(user, out var actor)) + return; + + _ui.TryToggleUi(deviceEnt, NewsReadUiKey.Key, actor.PlayerSession); + } + + public void ToggleUi(EntityUid user, EntityUid deviceEnt, NewsWriteComponent? component) + { + if (!Resolve(deviceEnt, ref component)) + return; + + if (!TryComp(user, out var actor)) + return; + + _ui.TryToggleUi(deviceEnt, NewsWriteUiKey.Key, actor.PlayerSession); + } + + public void UpdateWriteUi(EntityUid uid, NewsWriteComponent component) + { + if (!_ui.TryGetUi(uid, NewsWriteUiKey.Key, out _)) + return; + + var state = new NewsWriteBoundUserInterfaceState(Articles.ToArray()); + _ui.TrySetUiState(uid, NewsWriteUiKey.Key, state); + } + + public void UpdateReadUi(EntityUid uid, NewsReadComponent component) + { + if (!_ui.TryGetUi(uid, NewsReadUiKey.Key, out _)) + return; + + if (component.ArticleNum < 0) NewsReadLeafArticle(component, -1); + + if (Articles.Any()) + _ui.TrySetUiState(uid, NewsReadUiKey.Key, new NewsReadBoundUserInterfaceState(Articles[component.ArticleNum], component.ArticleNum + 1, Articles.Count)); + else + _ui.TrySetUiState(uid, NewsReadUiKey.Key, new NewsReadEmptyBoundUserInterfaceState()); + } + + public void OnWriteUiMessage(EntityUid uid, NewsWriteComponent component, NewsWriteShareMessage msg) + { + Articles.Add(msg.Article); + + UpdateReadDevices(); + UpdateWriteDevices(); + TryNotify(); + } + + public void OnWriteUiMessage(EntityUid uid, NewsWriteComponent component, NewsWriteDeleteMessage msg) + { + if (msg.ArticleNum < Articles.Count) + { + Articles.RemoveAt(msg.ArticleNum); + } + + UpdateReadDevices(); + UpdateWriteDevices(); + } + + public void OnWriteUiMessage(EntityUid uid, NewsWriteComponent component, NewsWriteArticlesRequestMessage msg) + { + UpdateWriteUi(uid, component); + } + + public void OnReadUiMessage(EntityUid uid, NewsReadComponent component, NewsReadNextMessage msg) + { + NewsReadLeafArticle(component, 1); + + UpdateReadUi(uid, component); + } + + public void OnReadUiMessage(EntityUid uid, NewsReadComponent component, NewsReadPrevMessage msg) + { + NewsReadLeafArticle(component, -1); + + UpdateReadUi(uid, component); + } + + public void OnReadUiMessage(EntityUid uid, NewsReadComponent component, NewsReadArticleRequestMessage msg) + { + UpdateReadUi(uid, component); + } + + private void NewsReadLeafArticle(NewsReadComponent component, int leafDir) + { + component.ArticleNum += leafDir; + + if (component.ArticleNum >= Articles.Count) component.ArticleNum = 0; + if (component.ArticleNum < 0) component.ArticleNum = Articles.Count - 1; + } + + private void TryNotify() + { + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var comp, out var ringer)) + { + _ringer.RingerPlayRingtone(comp.Owner, ringer); + } + } + + private void UpdateReadDevices() + { + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var comp)) + { + UpdateReadUi(comp.Owner, comp); + } + } + + private void UpdateWriteDevices() + { + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var comp)) + { + UpdateWriteUi(comp.Owner, comp); + } + } +} + diff --git a/Content.Server/PDA/PdaSystem.cs b/Content.Server/PDA/PdaSystem.cs index 31df32f7ad..e02e79ddd9 100644 --- a/Content.Server/PDA/PdaSystem.cs +++ b/Content.Server/PDA/PdaSystem.cs @@ -15,6 +15,8 @@ using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Containers; using Content.Shared.Light.Component; +using Content.Server.MassMedia.Components; +using Content.Server.MassMedia.Systems; namespace Content.Server.PDA { @@ -25,6 +27,7 @@ namespace Content.Server.PDA [Dependency] private readonly RingerSystem _ringer = default!; [Dependency] private readonly StationSystem _station = default!; [Dependency] private readonly StoreSystem _store = default!; + [Dependency] private readonly NewsSystem _news = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly UnpoweredFlashlightSystem _unpoweredFlashlight = default!; [Dependency] private readonly MindSystem _mindSystem = default!; @@ -42,6 +45,7 @@ namespace Content.Server.PDA SubscribeLocalEvent(OnUiMessage); SubscribeLocalEvent(OnUiMessage); SubscribeLocalEvent(OnUiMessage); + SubscribeLocalEvent(OnUiMessage); SubscribeLocalEvent(OnStationRenamed); SubscribeLocalEvent(OnAlertLevelChanged); @@ -112,6 +116,7 @@ namespace Content.Server.PDA var address = GetDeviceNetAddress(uid); var hasInstrument = HasComp(uid); var showUplink = HasComp(uid) && IsUnlocked(uid); + var showNews = HasComp(uid); UpdateStationName(uid, pda); UpdateAlertLevel(uid, pda); @@ -133,6 +138,7 @@ namespace Content.Server.PDA pda.StationName, showUplink, hasInstrument, + showNews, address); _cartridgeLoader?.UpdateUiState(uid, state); @@ -195,6 +201,18 @@ namespace Content.Server.PDA } } + private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaOpenNewsMessage msg) + { + if (!PdaUiKey.Key.Equals(msg.UiKey)) + return; + + if (TryComp(uid, out var news)) + { + _news.ToggleUi(msg.Session.AttachedEntity!.Value, uid, news); + UpdatePdaUi(uid, pda); + } + } + private bool IsUnlocked(EntityUid uid) { return !TryComp(uid, out var uplink) || uplink.Unlocked; diff --git a/Content.Server/PDA/Ringer/RingerComponent.cs b/Content.Server/PDA/Ringer/RingerComponent.cs index 5ef26a8426..2d70f78a5b 100644 --- a/Content.Server/PDA/Ringer/RingerComponent.cs +++ b/Content.Server/PDA/Ringer/RingerComponent.cs @@ -22,7 +22,7 @@ namespace Content.Server.PDA.Ringer /// [ViewVariables(VVAccess.ReadWrite)] [DataField("range")] - public float Range = 3f; + public float Range = 0.5f; [ViewVariables(VVAccess.ReadWrite)] [DataField("volume")] diff --git a/Content.Server/PDA/Ringer/RingerSystem.cs b/Content.Server/PDA/Ringer/RingerSystem.cs index 03aa1069e6..46bcc999b8 100644 --- a/Content.Server/PDA/Ringer/RingerSystem.cs +++ b/Content.Server/PDA/Ringer/RingerSystem.cs @@ -2,6 +2,7 @@ using Content.Server.Store.Components; using Content.Server.Store.Systems; using Content.Shared.PDA; using Content.Shared.PDA.Ringer; +using Content.Shared.Popups; using Content.Shared.Store; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -19,6 +20,7 @@ namespace Content.Server.PDA.Ringer [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; public override void Initialize() { @@ -48,6 +50,18 @@ namespace Content.Server.PDA.Ringer private void RingerPlayRingtone(EntityUid uid, RingerComponent ringer, RingerPlayRingtoneMessage args) { EnsureComp(uid); + + _popupSystem.PopupEntity(Loc.GetString("comp-ringer-vibration-popup"), uid, Filter.Pvs(uid, 0.05f), false, PopupType.Small); + + UpdateRingerUserInterface(uid, ringer); + } + + public void RingerPlayRingtone(EntityUid uid, RingerComponent ringer) + { + EnsureComp(uid); + + _popupSystem.PopupEntity(Loc.GetString("comp-ringer-vibration-popup"), uid, Filter.Pvs(uid, 0.05f), false, PopupType.Small); + UpdateRingerUserInterface(uid, ringer); } diff --git a/Content.Shared/MassMedia/Components/SharedNewsReadComponent.cs b/Content.Shared/MassMedia/Components/SharedNewsReadComponent.cs new file mode 100644 index 0000000000..499aede51f --- /dev/null +++ b/Content.Shared/MassMedia/Components/SharedNewsReadComponent.cs @@ -0,0 +1,57 @@ +using Robust.Shared.Serialization; +using Content.Shared.MassMedia.Systems; + +namespace Content.Shared.MassMedia.Components; + +[Serializable, NetSerializable] +public enum NewsReadUiKey : byte +{ + Key +} + +[Serializable, NetSerializable] +public sealed class NewsReadBoundUserInterfaceState : BoundUserInterfaceState +{ + public NewsArticle Article; + public int TargetNum; + public int TotalNum; + + public NewsReadBoundUserInterfaceState(NewsArticle article, int targetNum, int totalNum) + { + Article = article; + TargetNum = targetNum; + TotalNum = totalNum; + } +} + +[Serializable, NetSerializable] +public sealed class NewsReadEmptyBoundUserInterfaceState : BoundUserInterfaceState +{ + public NewsReadEmptyBoundUserInterfaceState() + { + } +} + +[Serializable, NetSerializable] +public sealed class NewsReadNextMessage : BoundUserInterfaceMessage +{ + public NewsReadNextMessage() + { + } +} + +[Serializable, NetSerializable] +public sealed class NewsReadPrevMessage : BoundUserInterfaceMessage +{ + public NewsReadPrevMessage() + { + } +} + +[Serializable, NetSerializable] +public sealed class NewsReadArticleRequestMessage : BoundUserInterfaceMessage +{ + public NewsReadArticleRequestMessage() + { + } +} diff --git a/Content.Shared/MassMedia/Components/SharedNewsWriteComponent.cs b/Content.Shared/MassMedia/Components/SharedNewsWriteComponent.cs new file mode 100644 index 0000000000..c7386698e0 --- /dev/null +++ b/Content.Shared/MassMedia/Components/SharedNewsWriteComponent.cs @@ -0,0 +1,51 @@ +using Robust.Shared.Serialization; +using Content.Shared.MassMedia.Systems; + +namespace Content.Shared.MassMedia.Components; + +[Serializable, NetSerializable] +public enum NewsWriteUiKey : byte +{ + Key +} + +[Serializable, NetSerializable] +public sealed class NewsWriteBoundUserInterfaceState : BoundUserInterfaceState +{ + public NewsArticle[] Articles; + + public NewsWriteBoundUserInterfaceState(NewsArticle[] articles) + { + Articles = articles; + } +} + +[Serializable, NetSerializable] +public sealed class NewsWriteShareMessage : BoundUserInterfaceMessage +{ + public NewsArticle Article; + + public NewsWriteShareMessage(NewsArticle article) + { + Article = article; + } +} + +[Serializable, NetSerializable] +public sealed class NewsWriteDeleteMessage : BoundUserInterfaceMessage +{ + public int ArticleNum; + + public NewsWriteDeleteMessage(int num) + { + ArticleNum = num; + } +} + +[Serializable, NetSerializable] +public sealed class NewsWriteArticlesRequestMessage : BoundUserInterfaceMessage +{ + public NewsWriteArticlesRequestMessage() + { + } +} diff --git a/Content.Shared/MassMedia/Systems/SharedNewsSystem.cs b/Content.Shared/MassMedia/Systems/SharedNewsSystem.cs new file mode 100644 index 0000000000..140452eb65 --- /dev/null +++ b/Content.Shared/MassMedia/Systems/SharedNewsSystem.cs @@ -0,0 +1,9 @@ +namespace Content.Shared.MassMedia.Systems; + +[Serializable] +public struct NewsArticle +{ + public string Name; + public string Content; + public TimeSpan ShareTime; +} diff --git a/Content.Shared/PDA/PdaMessagesUi.cs b/Content.Shared/PDA/PdaMessagesUi.cs index 00d29e1e1a..7bcc0afbe9 100644 --- a/Content.Shared/PDA/PdaMessagesUi.cs +++ b/Content.Shared/PDA/PdaMessagesUi.cs @@ -32,6 +32,12 @@ public sealed class PdaShowMusicMessage : BoundUserInterfaceMessage public PdaShowMusicMessage() { } } +[Serializable, NetSerializable] +public sealed class PdaOpenNewsMessage : BoundUserInterfaceMessage +{ + public PdaOpenNewsMessage() { } +} + [Serializable, NetSerializable] public sealed class PdaRequestUpdateInterfaceMessage : BoundUserInterfaceMessage { diff --git a/Content.Shared/PDA/PdaUpdateState.cs b/Content.Shared/PDA/PdaUpdateState.cs index 053527a868..581db5cad5 100644 --- a/Content.Shared/PDA/PdaUpdateState.cs +++ b/Content.Shared/PDA/PdaUpdateState.cs @@ -13,17 +13,19 @@ namespace Content.Shared.PDA public string? StationName; public bool HasUplink; public bool CanPlayMusic; + public bool HasNewsTab; public string? Address; public PdaUpdateState(bool flashlightEnabled, bool hasPen, PdaIdInfoText pdaOwnerInfo, string? stationName, bool hasUplink = false, - bool canPlayMusic = false, string? address = null) + bool canPlayMusic = false, bool hasNewsTab = false, string? address = null) { FlashlightEnabled = flashlightEnabled; HasPen = hasPen; PdaOwnerInfo = pdaOwnerInfo; HasUplink = hasUplink; CanPlayMusic = canPlayMusic; + HasNewsTab = hasNewsTab; StationName = stationName; Address = address; } diff --git a/Resources/Locale/en-US/mass-media/news-ui.ftl b/Resources/Locale/en-US/mass-media/news-ui.ftl new file mode 100644 index 0000000000..9dbc62b402 --- /dev/null +++ b/Resources/Locale/en-US/mass-media/news-ui.ftl @@ -0,0 +1,14 @@ +pda-news-button-label = News +pda-news-button-description = View station news +news-read-ui-next-text = Next +news-read-ui-past-text = Past +news-read-ui-default-title = Station News +news-read-ui-not-found-text = No articles found +news-read-ui-time-prefix-text = Publication time: +news-write-ui-default-title = Mass-media Management +news-write-ui-articles-label = Articles: +news-write-ui-delete-text = Delete +news-write-ui-share-text = Publish +news-write-ui-article-name-label = Heading: +news-write-ui-article-content-label = Content: + diff --git a/Resources/Locale/en-US/pda/Ringer/ringer-component.ftl b/Resources/Locale/en-US/pda/Ringer/ringer-component.ftl index aa02d982a4..138cdd5514 100644 --- a/Resources/Locale/en-US/pda/Ringer/ringer-component.ftl +++ b/Resources/Locale/en-US/pda/Ringer/ringer-component.ftl @@ -3,6 +3,8 @@ # For the PDA Ringer screen +comp-ringer-vibration-popup = PDA vibrates + comp-ringer-ui-menu-title = Ringtone comp-ringer-ui-test-ringtone-button = Test diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml index caa2831509..b72f53689c 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml @@ -365,3 +365,16 @@ components: - type: ComputerBoard prototype: ComputerIFFSyndicate + +- type: entity + parent: BaseComputerCircuitboard + id: ComputerMassMediaCircuitboard + name: mass media console board + description: Write your message to the world! + components: + - type: Sprite + state: cpu_service + - type: StaticPrice + price: 150 + - type: ComputerBoard + prototype: ComputerMassMedia \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index b6a396755c..915a7b6fd0 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -97,8 +97,11 @@ type: InstrumentBoundUserInterface - key: enum.HealthAnalyzerUiKey.Key type: HealthAnalyzerBoundUserInterface + - key: enum.NewsReadUiKey.Key + type: NewsReadBoundUserInterface - type: CrewManifestViewer unsecure: true + - type: NewsRead - type: Tag tags: - DoorBumpOpener diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index 2b2c1fb200..13544c3bf0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -940,3 +940,33 @@ radius: 1.5 energy: 1.6 color: "#b89f25" + +- type: entity + parent: BaseComputer + id: ComputerMassMedia + name: mass-media console + description: Write your message to the world! + components: + - type: Sprite + layers: + - map: ["computerLayerBody"] + state: computer + - map: ["computerLayerKeyboard"] + state: generic_keyboard + - map: ["computerLayerScreen"] + state: service + - map: ["computerLayerKeys"] + state: service_keys + - type: Computer + board: ComputerMassMediaCircuitboard + - type: DeviceNetworkRequiresPower + - type: NewsWrite + - type: ActivatableUI + key: enum.NewsWriteUiKey.Key + - type: ActivatableUIRequiresVision + - type: Transform + anchored: true + - type: UserInterface + interfaces: + - key: enum.NewsWriteUiKey.Key + type: NewsWriteBoundUserInterface diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index da5781057c..7dae0e0d4a 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -316,6 +316,7 @@ - BoozeDispenserMachineCircuitboard - SodaDispenserMachineCircuitboard - TelecomServerCircuitboard + - MassMediaCircuitboard - type: MaterialStorage whitelist: tags: diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml index a7d858e464..e4d798803c 100644 --- a/Resources/Prototypes/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml @@ -645,3 +645,11 @@ materials: Steel: 100 Glass: 900 + +- type: latheRecipe + id: MassMediaCircuitboard + result: ComputerMassMediaCircuitboard + completetime: 4 + materials: + Steel: 100 + Glass: 900 diff --git a/Resources/Prototypes/Research/civilianservices.yml b/Resources/Prototypes/Research/civilianservices.yml index 46b0598731..8c661ed8e8 100644 --- a/Resources/Prototypes/Research/civilianservices.yml +++ b/Resources/Prototypes/Research/civilianservices.yml @@ -106,6 +106,7 @@ - ComputerTelevisionCircuitboard - SynthesizerInstrument - DawInstrumentMachineCircuitboard + - MassMediaCircuitboard # Tier 2 diff --git a/Resources/Textures/Structures/Machines/computers.rsi/meta.json b/Resources/Textures/Structures/Machines/computers.rsi/meta.json index b663858ccd..c43d5d7e52 100644 --- a/Resources/Textures/Structures/Machines/computers.rsi/meta.json +++ b/Resources/Textures/Structures/Machines/computers.rsi/meta.json @@ -6,1654 +6,1684 @@ "x": 32, "y": 32 }, - "states": [ - { - "name": "ai-fixer", - "directions": 4 - }, - { - "name": "ai-fixer-404", - "directions": 4 - }, - { - "name": "ai-fixer-empty", - "directions": 4, - "delays": [ - [ - 0.7, - 0.7 - ], - [ - 0.7, - 0.7 - ], - [ - 0.7, - 0.7 - ], - [ - 0.7, - 0.7 - ] - ] - }, - { - "name": "ai-fixer-full", - "directions": 4 - }, - { - "name": "ai-fixer-on", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "aiupload", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ] - ] - }, - { - "name": "aiupload_key", - "directions": 4 - }, - { - "name": "alert-0", - "directions": 4 - }, - { - "name": "alert-1", - "directions": 4 - }, - { - "name": "alert-2", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ] - ] - }, - { - "name": "area_atmos", - "directions": 4, - "delays": [ - [ - 1, - 1 - ], - [ - 1, - 1 - ], - [ - 1, - 1 - ], - [ - 1, - 1 - ] - ] - }, - { - "name": "artifact", - "directions": 4, - "delays": [ - [ - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - [ - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - [ - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - [ - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ] - ] - }, - { - "name": "atmos_key", - "directions": 4 - }, - { - "name": "atmos_key_off", - "directions": 4 - }, - { - "name": "bounty", - "directions": 4, - "delays": [ - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ], - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ], - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ], - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ] - ] - }, - { - "name": "broken", - "directions": 4 - }, - { - "name": "cameras", - "directions": 4, - "delays": [ - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ], - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ], - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ], - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ] - ] - }, - { - "name": "comm", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ] - ] - }, - { - "name": "comm_logs", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2 - ], - [ - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2 - ], - [ - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2 - ], - [ - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2, - 0.1, - 0.2 - ] - ] - }, - { - "name": "comm_monitor", - "directions": 4, - "delays": [ - [ - 0.4, - 0.4, - 0.4 - ], - [ - 0.4, - 0.4, - 0.4 - ], - [ - 0.4, - 0.4, - 0.4 - ], - [ - 0.4, - 0.4, - 0.4 - ] - ] - }, - { - "name": "comm_syndie", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ] - ] - }, - { - "name": "command", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ] - ] - }, - { - "name": "computer", - "directions": 4 - }, - { - "name": "screen_broken", - "directions": 4 - }, - { - "name": "crew", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "dna", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2, - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.8, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.8, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.8, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.8, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2, - 0.2, - 0.2 - ] - ] - }, - { - "name": "dron_control_monitor", - "directions": 4, - "delays": [ - [ - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05 - ], - [ - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05 - ], - [ - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05 - ], - [ - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05, - 0.05 - ] - ] - }, - { - "name": "engie_cams", - "directions": 4, - "delays": [ - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ], - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ], - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ], - [ - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1, - 1.8, - 0.1 - ] - ] - }, - { - "name": "engine", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ] - ] - }, - { - "name": "entertainment", - "delays": [ - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ] - ] - }, - { - "name": "eris_control", - "directions": 4, - "delays": [ - [ - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5 - ], - [ - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5 - ], - [ - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5 - ], - [ - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5, - 0.5 - ] - ] - }, - { - "name": "error", - "directions": 4 - }, - { - "name": "explosive", - "directions": 4, - "delays": [ - [ - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1 - ], - [ - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1 - ], - [ - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1 - ], - [ - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1, - 1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "forensic", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ] - ] - }, - { - "name": "generic", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ] - ] - }, - { - "name": "generic_keys", - "directions": 4 - }, - { - "name": "generic_keyboard", - "directions": 4 - }, - { - "name": "holocontrol", - "directions": 4, - "delays": [ - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ], - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ], - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ], - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ] - ] - }, - { - "name": "id", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ] - ] - }, - { - "name": "id_key", - "directions": 4 - }, - { - "name": "id_key_off", - "directions": 4 - }, - { - "name": "mass_driver" - }, - { - "name": "mecha", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "med_key", - "directions": 4 - }, - { - "name": "med_key_off", - "directions": 4 - }, - { - "name": "medcomp", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ], - [ - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2, - 0.2 - ] - ] - }, - { - "name": "mining", - "directions": 4, - "delays": [ - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ], - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ], - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ], - [ - 1, - 0.1, - 1, - 0.1, - 1, - 0.1, - 1, - 0.1 - ] - ] - }, - { - "name": "mining_key", - "directions": 4 - }, - { - "name": "mining_key_off", - "directions": 4 - }, - { - "name": "power_key", - "directions": 4 - }, - { - "name": "power_key_off", - "directions": 4 - }, - { - "name": "power_monitor", - "directions": 4, - "delays": [ - [ - 0.6, - 0.6, - 0.6, - 0.6 - ], - [ - 0.6, - 0.6, - 0.6, - 0.6 - ], - [ - 0.6, - 0.6, - 0.6, - 0.6 - ], - [ - 0.6, - 0.6, - 0.6, - 0.6 - ] - ] - }, - { - "name": "power_monitor_warn", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ] - ] - }, - { - "name": "rd_key", - "directions": 4 - }, - { - "name": "rd_key_off", - "directions": 4 - }, - { - "name": "rdcomp", - "directions": 4 - }, - { - "name": "recharge_comp", - "directions": 4 - }, - { - "name": "recharge_comp_on", - "directions": 4, - "delays": [ - [ - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2 - ], - [ - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2 - ], - [ - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2 - ], - [ - 0.2, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.2 - ] - ] - }, - { - "name": "request", - "directions": 4, - "delays": [ - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ], - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ], - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ], - [ - 0.3, - 0.3, - 0.3, - 0.3, - 0.3, - 0.3 - ] - ] - }, - { - "name": "robot", - "directions": 4 - }, - { - "name": "security", - "directions": 4, - "delays": [ - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ], - [ - 0.2, - 0.2 - ] - ] - }, - { - "name": "security_key", - "directions": 4 - }, - { - "name": "security_key_off", - "directions": 4 - }, - { - "name": "shuttle", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "solar_screen", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "supply", - "directions": 4 - }, - { - "name": "syndie_key", - "directions": 4 - }, - { - "name": "syndie_key_off", - "directions": 4 - }, - { - "name": "syndishuttle", - "directions": 4 - }, - { - "name": "tank", - "directions": 4 - }, - { - "name": "tcboss", - "directions": 4 - }, - { - "name": "tech_key", - "directions": 4 - }, - { - "name": "tech_key_off", - "directions": 4 - }, - { - "name": "teleport", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "teleport_key", - "directions": 4 - }, - { - "name": "teleport_key_off", - "directions": 4 - }, - { - "name": "telesci", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "telesci_key", - "directions": 4 - }, - { - "name": "telesci_key_off", - "directions": 4 - }, - { - "name": "turbinecomp", - "directions": 4 - }, - { - "name": "computer-datatheory" - }, - { - "name": "avionics-systems" - }, - { - "name": "television" - }, - { - "name": "television_broken" - }, - { - "name": "telescreen", - "directions": 4 - }, - { - "name": "telescreen_frame", - "directions": 4 - }, - { - "name": "telescreen_broken", - "directions": 4 - }, - { - "name": "detective_television" - } - ] + "states": [ + { + "name": "ai-fixer", + "directions": 4 + }, + { + "name": "ai-fixer-404", + "directions": 4 + }, + { + "name": "ai-fixer-empty", + "directions": 4, + "delays": [ + [ + 0.7, + 0.7 + ], + [ + 0.7, + 0.7 + ], + [ + 0.7, + 0.7 + ], + [ + 0.7, + 0.7 + ] + ] + }, + { + "name": "ai-fixer-full", + "directions": 4 + }, + { + "name": "ai-fixer-on", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "aiupload", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "aiupload_key", + "directions": 4 + }, + { + "name": "alert-0", + "directions": 4 + }, + { + "name": "alert-1", + "directions": 4 + }, + { + "name": "alert-2", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ] + ] + }, + { + "name": "area_atmos", + "directions": 4, + "delays": [ + [ + 1, + 1 + ], + [ + 1, + 1 + ], + [ + 1, + 1 + ], + [ + 1, + 1 + ] + ] + }, + { + "name": "artifact", + "directions": 4, + "delays": [ + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ] + ] + }, + { + "name": "atmos_key", + "directions": 4 + }, + { + "name": "atmos_key_off", + "directions": 4 + }, + { + "name": "bounty", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "broken", + "directions": 4 + }, + { + "name": "cameras", + "directions": 4, + "delays": [ + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ], + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ], + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ], + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ] + ] + }, + { + "name": "comm", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ] + ] + }, + { + "name": "comm_logs", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ], + [ + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ], + [ + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ], + [ + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ] + ] + }, + { + "name": "comm_monitor", + "directions": 4, + "delays": [ + [ + 0.4, + 0.4, + 0.4 + ], + [ + 0.4, + 0.4, + 0.4 + ], + [ + 0.4, + 0.4, + 0.4 + ], + [ + 0.4, + 0.4, + 0.4 + ] + ] + }, + { + "name": "comm_syndie", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ] + ] + }, + { + "name": "command", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "computer", + "directions": 4 + }, + { + "name": "screen_broken", + "directions": 4 + }, + { + "name": "crew", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "dna", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.8, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.8, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.8, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.8, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "dron_control_monitor", + "directions": 4, + "delays": [ + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ] + ] + }, + { + "name": "engie_cams", + "directions": 4, + "delays": [ + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ], + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ], + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ], + [ + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1, + 1.8, + 0.1 + ] + ] + }, + { + "name": "engine", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "entertainment", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "eris_control", + "directions": 4, + "delays": [ + [ + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5 + ], + [ + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5 + ], + [ + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5 + ], + [ + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5 + ] + ] + }, + { + "name": "error", + "directions": 4 + }, + { + "name": "explosive", + "directions": 4, + "delays": [ + [ + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1 + ], + [ + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1 + ], + [ + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1 + ], + [ + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1, + 1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "forensic", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "generic", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "generic_keys", + "directions": 4 + }, + { + "name": "generic_keyboard", + "directions": 4 + }, + { + "name": "holocontrol", + "directions": 4, + "delays": [ + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ], + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ], + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ], + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ] + ] + }, + { + "name": "id", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "id_key", + "directions": 4 + }, + { + "name": "id_key_off", + "directions": 4 + }, + { + "name": "mass_driver" + }, + { + "name": "mecha", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "med_key", + "directions": 4 + }, + { + "name": "med_key_off", + "directions": 4 + }, + { + "name": "medcomp", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "mining", + "directions": 4, + "delays": [ + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ], + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ], + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ], + [ + 1, + 0.1, + 1, + 0.1, + 1, + 0.1, + 1, + 0.1 + ] + ] + }, + { + "name": "mining_key", + "directions": 4 + }, + { + "name": "mining_key_off", + "directions": 4 + }, + { + "name": "power_key", + "directions": 4 + }, + { + "name": "power_key_off", + "directions": 4 + }, + { + "name": "power_monitor", + "directions": 4, + "delays": [ + [ + 0.6, + 0.6, + 0.6, + 0.6 + ], + [ + 0.6, + 0.6, + 0.6, + 0.6 + ], + [ + 0.6, + 0.6, + 0.6, + 0.6 + ], + [ + 0.6, + 0.6, + 0.6, + 0.6 + ] + ] + }, + { + "name": "power_monitor_warn", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "rd_key", + "directions": 4 + }, + { + "name": "rd_key_off", + "directions": 4 + }, + { + "name": "rdcomp", + "directions": 4 + }, + { + "name": "recharge_comp", + "directions": 4 + }, + { + "name": "recharge_comp_on", + "directions": 4, + "delays": [ + [ + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2 + ], + [ + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2 + ], + [ + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2 + ], + [ + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2 + ] + ] + }, + { + "name": "request", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "robot", + "directions": 4 + }, + { + "name": "security", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "security_key", + "directions": 4 + }, + { + "name": "security_key_off", + "directions": 4 + }, + { + "name": "shuttle", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "solar_screen", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "supply", + "directions": 4 + }, + { + "name": "syndie_key", + "directions": 4 + }, + { + "name": "syndie_key_off", + "directions": 4 + }, + { + "name": "syndishuttle", + "directions": 4 + }, + { + "name": "tank", + "directions": 4 + }, + { + "name": "tcboss", + "directions": 4 + }, + { + "name": "tech_key", + "directions": 4 + }, + { + "name": "tech_key_off", + "directions": 4 + }, + { + "name": "teleport", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "teleport_key", + "directions": 4 + }, + { + "name": "teleport_key_off", + "directions": 4 + }, + { + "name": "telesci", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "telesci_key", + "directions": 4 + }, + { + "name": "telesci_key_off", + "directions": 4 + }, + { + "name": "turbinecomp", + "directions": 4 + }, + { + "name": "computer-datatheory" + }, + { + "name": "avionics-systems" + }, + { + "name": "television" + }, + { + "name": "television_broken" + }, + { + "name": "telescreen", + "directions": 4 + }, + { + "name": "telescreen_frame", + "directions": 4 + }, + { + "name": "telescreen_broken", + "directions": 4 + }, + { + "name": "detective_television" + }, + { + "directions": 4, + "name": "service", + "delays": [ + [ + 0.5, + 0.5, + 0.5 + ], + [ + 0.5, + 0.5, + 0.5 + ], + [ + 0.5, + 0.5, + 0.5 + ], + [ + 0.5, + 0.5, + 0.5 + ] + ] + }, + { + "name": "service_keys", + "directions": 4 + } + ] } diff --git a/Resources/Textures/Structures/Machines/computers.rsi/service.png b/Resources/Textures/Structures/Machines/computers.rsi/service.png new file mode 100644 index 0000000000..9d9884e4be Binary files /dev/null and b/Resources/Textures/Structures/Machines/computers.rsi/service.png differ diff --git a/Resources/Textures/Structures/Machines/computers.rsi/service_keys.png b/Resources/Textures/Structures/Machines/computers.rsi/service_keys.png new file mode 100644 index 0000000000..691c996080 Binary files /dev/null and b/Resources/Textures/Structures/Machines/computers.rsi/service_keys.png differ