Add 'Scan DNA' function to medical scanner (#1783)

* Add art assets for cloning

* Added a 'Scan DNA' button to the medical scanner

* Made the UI update unconditional for the medical scanner until checks for power changes are in place

* Update Medical scanner to reflect powered status and fix #1774

* added a 'scan dna' button the the medical scanner that will add the contained bodies Uid to a list in CloningSystem, fixed an issue with the menu not populating if the scanner starts in an unpowered state

* Add disabling logic to 'Scan DNA' button on medical scanner

* Removed un-used libraries

* changed scan dna button to Scan and Save DNA
This commit is contained in:
SoulSloth
2020-08-19 10:23:20 -04:00
committed by GitHub
parent cd1afb6582
commit dc77c399b9
15 changed files with 201 additions and 17 deletions

View File

@@ -22,6 +22,7 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
Title = Owner.Owner.Name, Title = Owner.Owner.Name,
}; };
_window.OnClose += Close; _window.OnClose += Close;
_window.ScanButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.ScanDNA));
_window.OpenCentered(); _window.OpenCentered();
} }

View File

@@ -12,18 +12,38 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
{ {
public class MedicalScannerWindow : SS14Window public class MedicalScannerWindow : SS14Window
{ {
public readonly Button ScanButton;
private readonly Label _diagnostics;
protected override Vector2? CustomSize => (485, 90); 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) public void Populate(MedicalScannerBoundUserInterfaceState state)
{ {
Contents.RemoveAllChildren();
var text = new StringBuilder(); var text = new StringBuilder();
if (!state.Entity.HasValue || if (!state.Entity.HasValue ||
!state.HasDamage() || !state.HasDamage() ||
!IoCManager.Resolve<IEntityManager>().TryGetEntity(state.Entity.Value, out var entity)) !IoCManager.Resolve<IEntityManager>().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 else
{ {
@@ -45,9 +65,10 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
text.Append("\n"); text.Append("\n");
} }
}
Contents.AddChild(new Label() {Text = text.ToString()}); _diagnostics.Text = text.ToString();
ScanButton.Disabled = state.IsScanned;
}
} }
} }
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.Components.Medical; using Content.Shared.GameObjects.Components.Medical;
using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems;
@@ -38,9 +39,14 @@ namespace Content.Server.GameObjects.Components.Medical
_appearance = Owner.GetComponent<AppearanceComponent>(); _appearance = Owner.GetComponent<AppearanceComponent>();
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>() _userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
.GetBoundUserInterface(MedicalScannerUiKey.Key); .GetBoundUserInterface(MedicalScannerUiKey.Key);
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
_bodyContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-bodyContainer", Owner); _bodyContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-bodyContainer", Owner);
_powerReceiver = Owner.GetComponent<PowerReceiverComponent>(); _powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
//TODO: write this so that it checks for a change in power events and acts accordingly.
var newState = GetUserInterfaceState();
_userInterface.SetState(newState);
UpdateUserInterface(); UpdateUserInterface();
} }
@@ -48,7 +54,8 @@ namespace Content.Server.GameObjects.Components.Medical
new MedicalScannerBoundUserInterfaceState( new MedicalScannerBoundUserInterfaceState(
null, null,
new Dictionary<DamageClass, int>(), new Dictionary<DamageClass, int>(),
new Dictionary<DamageType, int>()); new Dictionary<DamageType, int>(),
false);
private MedicalScannerBoundUserInterfaceState GetUserInterfaceState() private MedicalScannerBoundUserInterfaceState GetUserInterfaceState()
{ {
@@ -68,7 +75,7 @@ namespace Content.Server.GameObjects.Components.Medical
var classes = new Dictionary<DamageClass, int>(damageable.DamageClasses); var classes = new Dictionary<DamageClass, int>(damageable.DamageClasses);
var types = new Dictionary<DamageType, int>(damageable.DamageTypes); var types = new Dictionary<DamageType, int>(damageable.DamageTypes);
return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types); return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types, CloningSystem.HasUid(body.Uid));
} }
private void UpdateUserInterface() private void UpdateUserInterface()
@@ -92,12 +99,18 @@ namespace Content.Server.GameObjects.Components.Medical
default: throw new ArgumentException(nameof(damageState)); default: throw new ArgumentException(nameof(damageState));
} }
} }
private MedicalScannerStatus GetStatus() private MedicalScannerStatus GetStatus()
{ {
var body = _bodyContainer.ContainedEntity; if (Powered)
return body == null {
? MedicalScannerStatus.Open var body = _bodyContainer.ContainedEntity;
: GetStatusFromDamageState(body.GetComponent<IDamageableComponent>().CurrentDamageState); return body == null
? MedicalScannerStatus.Open
: GetStatusFromDamageState(body.GetComponent<IDamageableComponent>().CurrentDamageState);
}
return MedicalScannerStatus.Off;
} }
private void UpdateAppearance() private void UpdateAppearance()
@@ -178,14 +191,28 @@ namespace Content.Server.GameObjects.Components.Medical
public void Update(float frameTime) public void Update(float frameTime)
{ {
if (_bodyContainer.ContainedEntity == null)
{
// There's no need to update if there's no one inside
return;
}
UpdateUserInterface(); UpdateUserInterface();
UpdateAppearance(); 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();
}
}
} }
} }

View File

@@ -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<EntityUid> scannedUids = new List<EntityUid>();
public static void AddToScannedUids(EntityUid uid)
{
if (!scannedUids.Contains(uid))
{
scannedUids.Add(uid);
}
}
public static bool HasUid(EntityUid uid)
{
return scannedUids.Contains(uid);
}
}
}

View File

@@ -7,6 +7,7 @@ namespace Content.Server.GameObjects.EntitySystems
[UsedImplicitly] [UsedImplicitly]
internal sealed class MedicalScannerSystem : EntitySystem internal sealed class MedicalScannerSystem : EntitySystem
{ {
public override void Update(float frameTime) public override void Update(float frameTime)
{ {
foreach (var comp in ComponentManager.EntityQuery<MedicalScannerComponent>()) foreach (var comp in ComponentManager.EntityQuery<MedicalScannerComponent>())

View File

@@ -17,15 +17,18 @@ namespace Content.Shared.GameObjects.Components.Medical
public readonly EntityUid? Entity; public readonly EntityUid? Entity;
public readonly Dictionary<DamageClass, int> DamageClasses; public readonly Dictionary<DamageClass, int> DamageClasses;
public readonly Dictionary<DamageType, int> DamageTypes; public readonly Dictionary<DamageType, int> DamageTypes;
public readonly bool IsScanned;
public MedicalScannerBoundUserInterfaceState( public MedicalScannerBoundUserInterfaceState(
EntityUid? entity, EntityUid? entity,
Dictionary<DamageClass, int> damageClasses, Dictionary<DamageClass, int> damageClasses,
Dictionary<DamageType, int> damageTypes) Dictionary<DamageType, int> damageTypes,
bool isScanned)
{ {
Entity = entity; Entity = entity;
DamageClasses = damageClasses; DamageClasses = damageClasses;
DamageTypes = damageTypes; DamageTypes = damageTypes;
IsScanned = isScanned;
} }
public bool HasDamage() public bool HasDamage()
@@ -56,5 +59,24 @@ namespace Content.Shared.GameObjects.Components.Medical
Green, Green,
Yellow, Yellow,
} }
[Serializable, NetSerializable]
public enum UiButton
{
ScanDNA,
}
[Serializable, NetSerializable]
public class UiButtonPressedMessage : BoundUserInterfaceMessage
{
public readonly UiButton Button;
public UiButtonPressedMessage(UiButton button)
{
Button = button;
}
}
} }
} }

View File

@@ -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
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB