Make Health Analysers UI continuously update (#22449)
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
<DefaultWindow xmlns="https://spacestation14.io"
|
<controls:FancyWindow
|
||||||
|
xmlns="https://spacestation14.io"
|
||||||
|
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||||
SetSize="250 100">
|
SetSize="250 100">
|
||||||
<ScrollContainer
|
<ScrollContainer
|
||||||
VerticalExpand="True">
|
VerticalExpand="True">
|
||||||
@@ -12,6 +14,16 @@
|
|||||||
Name="PatientDataContainer"
|
Name="PatientDataContainer"
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
Margin="0 0 5 10">
|
Margin="0 0 5 10">
|
||||||
|
<BoxContainer Name="ScanModePanel" HorizontalExpand="True" Visible="False" Margin="0 5 0 0">
|
||||||
|
<Label
|
||||||
|
Name="ScanMode"
|
||||||
|
Align="Left"
|
||||||
|
Text="{Loc health-analyzer-window-scan-mode-text}"/>
|
||||||
|
<Label
|
||||||
|
Name="ScanModeText"
|
||||||
|
Align="Right"
|
||||||
|
HorizontalExpand="True"/>
|
||||||
|
</BoxContainer>
|
||||||
<Label
|
<Label
|
||||||
Name="PatientName"/>
|
Name="PatientName"/>
|
||||||
<Label
|
<Label
|
||||||
@@ -30,4 +42,4 @@
|
|||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
</DefaultWindow>
|
</controls:FancyWindow>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Content.Client.UserInterface.Controls;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Prototypes;
|
using Content.Shared.Damage.Prototypes;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
@@ -7,7 +8,6 @@ using Content.Shared.IdentityManagement;
|
|||||||
using Content.Shared.MedicalScanner;
|
using Content.Shared.MedicalScanner;
|
||||||
using Content.Shared.Nutrition.Components;
|
using Content.Shared.Nutrition.Components;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
@@ -20,7 +20,7 @@ using Robust.Shared.Utility;
|
|||||||
namespace Content.Client.HealthAnalyzer.UI
|
namespace Content.Client.HealthAnalyzer.UI
|
||||||
{
|
{
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class HealthAnalyzerWindow : DefaultWindow
|
public sealed partial class HealthAnalyzerWindow : FancyWindow
|
||||||
{
|
{
|
||||||
private readonly IEntityManager _entityManager;
|
private readonly IEntityManager _entityManager;
|
||||||
private readonly SpriteSystem _spriteSystem;
|
private readonly SpriteSystem _spriteSystem;
|
||||||
@@ -62,6 +62,17 @@ namespace Content.Client.HealthAnalyzer.UI
|
|||||||
entityName = Identity.Name(target.Value, _entityManager);
|
entityName = Identity.Name(target.Value, _entityManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg.ScanMode.HasValue)
|
||||||
|
{
|
||||||
|
ScanModePanel.Visible = true;
|
||||||
|
ScanModeText.Text = Loc.GetString(msg.ScanMode.Value ? "health-analyzer-window-scan-mode-active" : "health-analyzer-window-scan-mode-inactive");
|
||||||
|
ScanModeText.FontColorOverride = msg.ScanMode.Value ? Color.Green : Color.Red;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScanModePanel.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
PatientName.Text = Loc.GetString(
|
PatientName.Text = Loc.GetString(
|
||||||
"health-analyzer-window-entity-health-text",
|
"health-analyzer-window-entity-health-text",
|
||||||
("entityName", entityName)
|
("entityName", entityName)
|
||||||
|
|||||||
@@ -1,32 +1,54 @@
|
|||||||
using Content.Server.UserInterface;
|
|
||||||
using Content.Shared.MedicalScanner;
|
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||||
|
|
||||||
|
namespace Content.Server.Medical.Components;
|
||||||
|
|
||||||
namespace Content.Server.Medical.Components
|
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// After scanning, retrieves the target Uid to use with its related UI.
|
/// After scanning, retrieves the target Uid to use with its related UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
|
[Access(typeof(HealthAnalyzerSystem))]
|
||||||
public sealed partial class HealthAnalyzerComponent : Component
|
public sealed partial class HealthAnalyzerComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// When should the next update be sent for the patient
|
||||||
|
/// </summary>
|
||||||
|
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||||
|
public TimeSpan NextUpdate = TimeSpan.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The delay between patient health updates
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public TimeSpan UpdateInterval = TimeSpan.FromSeconds(1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How long it takes to scan someone.
|
/// How long it takes to scan someone.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("scanDelay")]
|
[DataField]
|
||||||
public float ScanDelay = 0.8f;
|
public TimeSpan ScanDelay = TimeSpan.FromSeconds(0.8);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which entity has been scanned, for continuous updates
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public EntityUid? ScannedEntity;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum range in tiles at which the analyzer can receive continuous updates
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float MaxScanRange = 2.5f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sound played on scanning begin
|
/// Sound played on scanning begin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("scanningBeginSound")]
|
[DataField]
|
||||||
public SoundSpecifier? ScanningBeginSound;
|
public SoundSpecifier? ScanningBeginSound;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sound played on scanning end
|
/// Sound played on scanning end
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("scanningEndSound")]
|
[DataField]
|
||||||
public SoundSpecifier? ScanningEndSound;
|
public SoundSpecifier? ScanningEndSound;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -195,7 +195,8 @@ public sealed partial class CryoPodSystem : SharedCryoPodSystem
|
|||||||
(bloodstream != null && _solutionContainerSystem.ResolveSolution(entity.Comp.BodyContainer.ContainedEntity.Value,
|
(bloodstream != null && _solutionContainerSystem.ResolveSolution(entity.Comp.BodyContainer.ContainedEntity.Value,
|
||||||
bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution))
|
bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution))
|
||||||
? bloodSolution.FillFraction
|
? bloodSolution.FillFraction
|
||||||
: 0
|
: 0,
|
||||||
|
null
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,37 +6,81 @@ using Content.Server.Temperature.Components;
|
|||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.DoAfter;
|
using Content.Shared.DoAfter;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Interaction.Events;
|
||||||
using Content.Shared.MedicalScanner;
|
using Content.Shared.MedicalScanner;
|
||||||
using Content.Shared.Mobs.Components;
|
using Content.Shared.Mobs.Components;
|
||||||
|
using Content.Shared.PowerCell;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Server.Medical;
|
||||||
|
|
||||||
namespace Content.Server.Medical
|
|
||||||
{
|
|
||||||
public sealed class HealthAnalyzerSystem : EntitySystem
|
public sealed class HealthAnalyzerSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly PowerCellSystem _cell = default!;
|
[Dependency] private readonly PowerCellSystem _cell = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
||||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||||
|
[Dependency] private readonly TransformSystem _transformSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
SubscribeLocalEvent<HealthAnalyzerComponent, EntityUnpausedEvent>(OnEntityUnpaused);
|
||||||
SubscribeLocalEvent<HealthAnalyzerComponent, AfterInteractEvent>(OnAfterInteract);
|
SubscribeLocalEvent<HealthAnalyzerComponent, AfterInteractEvent>(OnAfterInteract);
|
||||||
SubscribeLocalEvent<HealthAnalyzerComponent, HealthAnalyzerDoAfterEvent>(OnDoAfter);
|
SubscribeLocalEvent<HealthAnalyzerComponent, HealthAnalyzerDoAfterEvent>(OnDoAfter);
|
||||||
|
SubscribeLocalEvent<HealthAnalyzerComponent, EntGotInsertedIntoContainerMessage>(OnInsertedIntoContainer);
|
||||||
|
SubscribeLocalEvent<HealthAnalyzerComponent, PowerCellSlotEmptyEvent>(OnPowerCellSlotEmpty);
|
||||||
|
SubscribeLocalEvent<HealthAnalyzerComponent, DroppedEvent>(OnDropped);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAfterInteract(Entity<HealthAnalyzerComponent> entity, ref AfterInteractEvent args)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
if (args.Target == null || !args.CanReach || !HasComp<MobStateComponent>(args.Target) || !_cell.HasActivatableCharge(entity.Owner, user: args.User))
|
var analyzerQuery = EntityQueryEnumerator<HealthAnalyzerComponent, TransformComponent>();
|
||||||
|
while (analyzerQuery.MoveNext(out var uid, out var component, out var transform))
|
||||||
|
{
|
||||||
|
//Update rate limited to 1 second
|
||||||
|
if (component.NextUpdate > _timing.CurTime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (component.ScannedEntity is not {} patient)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
component.NextUpdate = _timing.CurTime + component.UpdateInterval;
|
||||||
|
|
||||||
|
//Get distance between health analyzer and the scanned entity
|
||||||
|
var patientCoordinates = Transform(patient).Coordinates;
|
||||||
|
if (!patientCoordinates.InRange(EntityManager, _transformSystem, transform.Coordinates, component.MaxScanRange))
|
||||||
|
{
|
||||||
|
//Range too far, disable updates
|
||||||
|
StopAnalyzingEntity((uid, component), patient);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateScannedUser(uid, patient, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEntityUnpaused(Entity<HealthAnalyzerComponent> ent, ref EntityUnpausedEvent args)
|
||||||
|
{
|
||||||
|
ent.Comp.NextUpdate += args.PausedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Trigger the doafter for scanning
|
||||||
|
/// </summary>
|
||||||
|
private void OnAfterInteract(Entity<HealthAnalyzerComponent> uid, ref AfterInteractEvent args)
|
||||||
|
{
|
||||||
|
if (args.Target == null || !args.CanReach || !HasComp<MobStateComponent>(args.Target) || !_cell.HasDrawCharge(uid, user: args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_audio.PlayPvs(entity.Comp.ScanningBeginSound, entity);
|
_audio.PlayPvs(uid.Comp.ScanningBeginSound, uid);
|
||||||
|
|
||||||
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, TimeSpan.FromSeconds(entity.Comp.ScanDelay), new HealthAnalyzerDoAfterEvent(), entity.Owner, target: args.Target, used: entity.Owner)
|
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, uid.Comp.ScanDelay, new HealthAnalyzerDoAfterEvent(), uid, target: args.Target, used: uid)
|
||||||
{
|
{
|
||||||
BreakOnTargetMove = true,
|
BreakOnTargetMove = true,
|
||||||
BreakOnUserMove = true,
|
BreakOnUserMove = true,
|
||||||
@@ -44,17 +88,45 @@ namespace Content.Server.Medical
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDoAfter(Entity<HealthAnalyzerComponent> entity, ref HealthAnalyzerDoAfterEvent args)
|
private void OnDoAfter(Entity<HealthAnalyzerComponent> uid, ref HealthAnalyzerDoAfterEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled || args.Cancelled || args.Target == null || !_cell.TryUseActivatableCharge(entity.Owner, user: args.User))
|
if (args.Handled || args.Cancelled || args.Target == null || !_cell.HasDrawCharge(uid, user: args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_audio.PlayPvs(entity.Comp.ScanningEndSound, args.User);
|
_audio.PlayPvs(uid.Comp.ScanningEndSound, uid);
|
||||||
|
|
||||||
UpdateScannedUser(entity, args.User, args.Target.Value, entity.Comp);
|
OpenUserInterface(args.User, uid);
|
||||||
|
BeginAnalyzingEntity(uid, args.Target.Value);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn off when placed into a storage item or moved between slots/hands
|
||||||
|
/// </summary>
|
||||||
|
private void OnInsertedIntoContainer(Entity<HealthAnalyzerComponent> uid, ref EntGotInsertedIntoContainerMessage args)
|
||||||
|
{
|
||||||
|
if (uid.Comp.ScannedEntity is { } patient)
|
||||||
|
StopAnalyzingEntity(uid, patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disable continuous updates once battery is dead
|
||||||
|
/// </summary>
|
||||||
|
private void OnPowerCellSlotEmpty(Entity<HealthAnalyzerComponent> uid, ref PowerCellSlotEmptyEvent args)
|
||||||
|
{
|
||||||
|
if (uid.Comp.ScannedEntity is { } patient)
|
||||||
|
StopAnalyzingEntity(uid, patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn off the analyser when dropped
|
||||||
|
/// </summary>
|
||||||
|
private void OnDropped(Entity<HealthAnalyzerComponent> uid, ref DroppedEvent args)
|
||||||
|
{
|
||||||
|
if (uid.Comp.ScannedEntity is { } patient)
|
||||||
|
StopAnalyzingEntity(uid, patient);
|
||||||
|
}
|
||||||
|
|
||||||
private void OpenUserInterface(EntityUid user, EntityUid analyzer)
|
private void OpenUserInterface(EntityUid user, EntityUid analyzer)
|
||||||
{
|
{
|
||||||
if (!TryComp<ActorComponent>(user, out var actor) || !_uiSystem.TryGetUi(analyzer, HealthAnalyzerUiKey.Key, out var ui))
|
if (!TryComp<ActorComponent>(user, out var actor) || !_uiSystem.TryGetUi(analyzer, HealthAnalyzerUiKey.Key, out var ui))
|
||||||
@@ -63,37 +135,66 @@ namespace Content.Server.Medical
|
|||||||
_uiSystem.OpenUi(ui, actor.PlayerSession);
|
_uiSystem.OpenUi(ui, actor.PlayerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateScannedUser(EntityUid uid, EntityUid user, EntityUid? target, HealthAnalyzerComponent? healthAnalyzer)
|
/// <summary>
|
||||||
|
/// Mark the entity as having its health analyzed, and link the analyzer to it
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="healthAnalyzer">The health analyzer that should receive the updates</param>
|
||||||
|
/// <param name="target">The entity to start analyzing</param>
|
||||||
|
private void BeginAnalyzingEntity(Entity<HealthAnalyzerComponent> healthAnalyzer, EntityUid target)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref healthAnalyzer))
|
//Link the health analyzer to the scanned entity
|
||||||
return;
|
healthAnalyzer.Comp.ScannedEntity = target;
|
||||||
|
|
||||||
if (target == null || !_uiSystem.TryGetUi(uid, HealthAnalyzerUiKey.Key, out var ui))
|
_cell.SetPowerCellDrawEnabled(healthAnalyzer, true);
|
||||||
|
|
||||||
|
UpdateScannedUser(healthAnalyzer, target, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove the analyzer from the active list, and remove the component if it has no active analyzers
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="healthAnalyzer">The health analyzer that's receiving the updates</param>
|
||||||
|
/// <param name="target">The entity to analyze</param>
|
||||||
|
private void StopAnalyzingEntity(Entity<HealthAnalyzerComponent> healthAnalyzer, EntityUid target)
|
||||||
|
{
|
||||||
|
//Unlink the analyzer
|
||||||
|
healthAnalyzer.Comp.ScannedEntity = null;
|
||||||
|
|
||||||
|
_cell.SetPowerCellDrawEnabled(target, false);
|
||||||
|
|
||||||
|
UpdateScannedUser(healthAnalyzer, target, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send an update for the target to the healthAnalyzer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="healthAnalyzer">The health analyzer</param>
|
||||||
|
/// <param name="target">The entity being scanned</param>
|
||||||
|
/// <param name="scanMode">True makes the UI show ACTIVE, False makes the UI show INACTIVE</param>
|
||||||
|
public void UpdateScannedUser(EntityUid healthAnalyzer, EntityUid target, bool scanMode)
|
||||||
|
{
|
||||||
|
if (!_uiSystem.TryGetUi(healthAnalyzer, HealthAnalyzerUiKey.Key, out var ui))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!HasComp<DamageableComponent>(target))
|
if (!HasComp<DamageableComponent>(target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float bodyTemperature;
|
var bodyTemperature = float.NaN;
|
||||||
|
|
||||||
if (TryComp<TemperatureComponent>(target, out var temp))
|
if (TryComp<TemperatureComponent>(target, out var temp))
|
||||||
bodyTemperature = temp.CurrentTemperature;
|
bodyTemperature = temp.CurrentTemperature;
|
||||||
else
|
|
||||||
bodyTemperature = float.NaN;
|
|
||||||
|
|
||||||
float bloodAmount;
|
var bloodAmount = float.NaN;
|
||||||
|
|
||||||
if (TryComp<BloodstreamComponent>(target, out var bloodstream) &&
|
if (TryComp<BloodstreamComponent>(target, out var bloodstream) &&
|
||||||
_solutionContainerSystem.ResolveSolution(target.Value, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution))
|
_solutionContainerSystem.ResolveSolution(target, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution))
|
||||||
bloodAmount = bloodSolution.FillFraction;
|
bloodAmount = bloodSolution.FillFraction;
|
||||||
else
|
|
||||||
bloodAmount = float.NaN;
|
|
||||||
|
|
||||||
OpenUserInterface(user, uid);
|
|
||||||
|
|
||||||
_uiSystem.SendUiMessage(ui, new HealthAnalyzerScannedUserMessage(
|
_uiSystem.SendUiMessage(ui, new HealthAnalyzerScannedUserMessage(
|
||||||
GetNetEntity(target),
|
GetNetEntity(target),
|
||||||
bodyTemperature,
|
bodyTemperature,
|
||||||
bloodAmount
|
bloodAmount,
|
||||||
|
scanMode
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ public sealed class HealthAnalyzerScannedUserMessage : BoundUserInterfaceMessage
|
|||||||
public readonly NetEntity? TargetEntity;
|
public readonly NetEntity? TargetEntity;
|
||||||
public float Temperature;
|
public float Temperature;
|
||||||
public float BloodLevel;
|
public float BloodLevel;
|
||||||
|
public bool? ScanMode;
|
||||||
|
|
||||||
public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel)
|
public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode)
|
||||||
{
|
{
|
||||||
TargetEntity = targetEntity;
|
TargetEntity = targetEntity;
|
||||||
Temperature = temperature;
|
Temperature = temperature;
|
||||||
BloodLevel = bloodLevel;
|
BloodLevel = bloodLevel;
|
||||||
|
ScanMode = scanMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ health-analyzer-window-damage-group-text = {$damageGroup}: {$amount}
|
|||||||
health-analyzer-window-damage-type-text = {$damageType}: {$amount}
|
health-analyzer-window-damage-type-text = {$damageType}: {$amount}
|
||||||
health-analyzer-window-damage-type-duplicate-text = {$damageType}: {$amount} (duplicate)
|
health-analyzer-window-damage-type-duplicate-text = {$damageType}: {$amount} (duplicate)
|
||||||
|
|
||||||
|
health-analyzer-window-scan-mode-text = Scan Mode:
|
||||||
|
health-analyzer-window-scan-mode-active = ACTIVE
|
||||||
|
health-analyzer-window-scan-mode-inactive = INACTIVE
|
||||||
|
|
||||||
health-analyzer-window-damage-group-Brute = Brute
|
health-analyzer-window-damage-group-Brute = Brute
|
||||||
health-analyzer-window-damage-type-Blunt = Blunt
|
health-analyzer-window-damage-type-Blunt = Blunt
|
||||||
health-analyzer-window-damage-type-Slash = Slash
|
health-analyzer-window-damage-type-Slash = Slash
|
||||||
|
|||||||
@@ -45,8 +45,7 @@
|
|||||||
suffix: Powered
|
suffix: Powered
|
||||||
components:
|
components:
|
||||||
- type: PowerCellDraw
|
- type: PowerCellDraw
|
||||||
drawRate: 0
|
drawRate: 1.2 #Calculated for 5 minutes on a small cell
|
||||||
useRate: 20
|
|
||||||
- type: ActivatableUIRequiresPowerCell
|
- type: ActivatableUIRequiresPowerCell
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
Reference in New Issue
Block a user