diff --git a/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerBoundUserInterface.cs b/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerBoundUserInterface.cs index 4b2fa2a1fc..2280406c5b 100644 --- a/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerBoundUserInterface.cs +++ b/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerBoundUserInterface.cs @@ -22,6 +22,7 @@ namespace Content.Client.GameObjects.Components.MedicalScanner Title = Owner.Owner.Name, }; _window.OnClose += Close; + _window.ScanButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.ScanDNA)); _window.OpenCentered(); } diff --git a/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerWindow.cs b/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerWindow.cs index 61adc113f2..4668854fbf 100644 --- a/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerWindow.cs +++ b/Content.Client/GameObjects/Components/MedicalScanner/MedicalScannerWindow.cs @@ -12,18 +12,38 @@ namespace Content.Client.GameObjects.Components.MedicalScanner { public class MedicalScannerWindow : SS14Window { + public readonly Button ScanButton; + private readonly Label _diagnostics; protected override Vector2? CustomSize => (485, 90); + public MedicalScannerWindow() + { + Contents.AddChild(new VBoxContainer + { + Children = + { + (ScanButton = new Button + { + Text = "Scan and Save DNA" + }), + (_diagnostics = new Label + { + Text = "" + }) + } + }); + } + public void Populate(MedicalScannerBoundUserInterfaceState state) { - Contents.RemoveAllChildren(); var text = new StringBuilder(); if (!state.Entity.HasValue || !state.HasDamage() || !IoCManager.Resolve().TryGetEntity(state.Entity.Value, out var entity)) { - text.Append(Loc.GetString("No patient data.")); + _diagnostics.Text = Loc.GetString("No patient data."); + ScanButton.Disabled = true; } else { @@ -45,9 +65,10 @@ namespace Content.Client.GameObjects.Components.MedicalScanner text.Append("\n"); } - } - Contents.AddChild(new Label() {Text = text.ToString()}); + _diagnostics.Text = text.ToString(); + ScanButton.Disabled = state.IsScanned; + } } } } diff --git a/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs b/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs index 4e36ffed71..d50513e374 100644 --- a/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs +++ b/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.Power.ApcNetComponents; +using Content.Server.GameObjects.EntitySystems; using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.Components.Medical; using Content.Shared.GameObjects.EntitySystems; @@ -38,9 +39,14 @@ namespace Content.Server.GameObjects.Components.Medical _appearance = Owner.GetComponent(); _userInterface = Owner.GetComponent() .GetBoundUserInterface(MedicalScannerUiKey.Key); + _userInterface.OnReceiveMessage += OnUiReceiveMessage; _bodyContainer = ContainerManagerComponent.Ensure($"{Name}-bodyContainer", Owner); _powerReceiver = Owner.GetComponent(); + //TODO: write this so that it checks for a change in power events and acts accordingly. + var newState = GetUserInterfaceState(); + _userInterface.SetState(newState); + UpdateUserInterface(); } @@ -48,7 +54,8 @@ namespace Content.Server.GameObjects.Components.Medical new MedicalScannerBoundUserInterfaceState( null, new Dictionary(), - new Dictionary()); + new Dictionary(), + false); private MedicalScannerBoundUserInterfaceState GetUserInterfaceState() { @@ -68,7 +75,7 @@ namespace Content.Server.GameObjects.Components.Medical var classes = new Dictionary(damageable.DamageClasses); var types = new Dictionary(damageable.DamageTypes); - return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types); + return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types, CloningSystem.HasUid(body.Uid)); } private void UpdateUserInterface() @@ -92,12 +99,18 @@ namespace Content.Server.GameObjects.Components.Medical default: throw new ArgumentException(nameof(damageState)); } } + private MedicalScannerStatus GetStatus() { - var body = _bodyContainer.ContainedEntity; - return body == null - ? MedicalScannerStatus.Open - : GetStatusFromDamageState(body.GetComponent().CurrentDamageState); + if (Powered) + { + var body = _bodyContainer.ContainedEntity; + return body == null + ? MedicalScannerStatus.Open + : GetStatusFromDamageState(body.GetComponent().CurrentDamageState); + } + + return MedicalScannerStatus.Off; } private void UpdateAppearance() @@ -178,14 +191,28 @@ namespace Content.Server.GameObjects.Components.Medical public void Update(float frameTime) { - if (_bodyContainer.ContainedEntity == null) - { - // There's no need to update if there's no one inside - return; - } - UpdateUserInterface(); UpdateAppearance(); } + + private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj) + { + if (!(obj.Message is UiButtonPressedMessage message)) + { + return; + } + + switch (message.Button) + { + case UiButton.ScanDNA: + if (_bodyContainer.ContainedEntity != null) + { + CloningSystem.AddToScannedUids(_bodyContainer.ContainedEntity.Uid); + } + break; + default: + throw new ArgumentOutOfRangeException(); + } + } } } diff --git a/Content.Server/GameObjects/EntitySystems/CloningSystem.cs b/Content.Server/GameObjects/EntitySystems/CloningSystem.cs new file mode 100644 index 0000000000..469c0f6157 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/CloningSystem.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; + +namespace Content.Server.GameObjects.EntitySystems +{ + internal sealed class CloningSystem : EntitySystem + { + public static List scannedUids = new List(); + + public static void AddToScannedUids(EntityUid uid) + { + if (!scannedUids.Contains(uid)) + { + scannedUids.Add(uid); + } + } + + public static bool HasUid(EntityUid uid) + { + return scannedUids.Contains(uid); + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs b/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs index 3180063247..01d1cd20ac 100644 --- a/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs @@ -7,6 +7,7 @@ namespace Content.Server.GameObjects.EntitySystems [UsedImplicitly] internal sealed class MedicalScannerSystem : EntitySystem { + public override void Update(float frameTime) { foreach (var comp in ComponentManager.EntityQuery()) diff --git a/Content.Shared/GameObjects/Components/Medical/SharedMedicalScannerComponent.cs b/Content.Shared/GameObjects/Components/Medical/SharedMedicalScannerComponent.cs index 8573a50c63..10262d1fd2 100644 --- a/Content.Shared/GameObjects/Components/Medical/SharedMedicalScannerComponent.cs +++ b/Content.Shared/GameObjects/Components/Medical/SharedMedicalScannerComponent.cs @@ -17,15 +17,18 @@ namespace Content.Shared.GameObjects.Components.Medical public readonly EntityUid? Entity; public readonly Dictionary DamageClasses; public readonly Dictionary DamageTypes; + public readonly bool IsScanned; public MedicalScannerBoundUserInterfaceState( EntityUid? entity, Dictionary damageClasses, - Dictionary damageTypes) + Dictionary damageTypes, + bool isScanned) { Entity = entity; DamageClasses = damageClasses; DamageTypes = damageTypes; + IsScanned = isScanned; } public bool HasDamage() @@ -56,5 +59,24 @@ namespace Content.Shared.GameObjects.Components.Medical Green, Yellow, } + + [Serializable, NetSerializable] + public enum UiButton + { + ScanDNA, + } + + [Serializable, NetSerializable] + public class UiButtonPressedMessage : BoundUserInterfaceMessage + { + public readonly UiButton Button; + + public UiButtonPressedMessage(UiButton button) + { + Button = button; + } + } + + } } diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/meta.json b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/meta.json new file mode 100644 index 0000000000..36d0f22970 --- /dev/null +++ b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/meta.json @@ -0,0 +1,88 @@ +{ + "version": 1, + "license": "CC BY-SA 3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation at commit 9bebd81ae0b0a7f952b59886a765c681205de31f", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "pod_0", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "scanner", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "scanner_maintenance", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "scanner_occupied", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "scanner_open", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "scanner_open_maintenance", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "scanner_open_unpowered", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "scanner_unpowered", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/pod_0.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/pod_0.png new file mode 100644 index 0000000000..13d289fd6c Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/pod_0.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner.png new file mode 100644 index 0000000000..01b9c37f9e Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_maintenance.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_maintenance.png new file mode 100644 index 0000000000..b659cb7f35 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_maintenance.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_occupied.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_occupied.png new file mode 100644 index 0000000000..427daed697 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_occupied.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open.png new file mode 100644 index 0000000000..4af3b01611 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open_maintenance.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open_maintenance.png new file mode 100644 index 0000000000..513eb24d71 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open_maintenance.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open_unpowered.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open_unpowered.png new file mode 100644 index 0000000000..206e0c02ac Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_open_unpowered.png differ diff --git a/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_unpowered.png b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_unpowered.png new file mode 100644 index 0000000000..4d0705aac0 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Medical/Cloning.rsi/scanner_unpowered.png differ