diff --git a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs
index 04075000f5b..4983d3df13d 100644
--- a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs
+++ b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs
@@ -2,6 +2,7 @@ using Content.Client.Cargo.UI;
using Content.Shared.Cargo.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
+using Content.Shared._DV.Cargo.Components; // DeltaV: Bounty claim messages
namespace Content.Client.Cargo.BUI;
@@ -30,6 +31,18 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface
{
SendMessage(new BountySkipMessage(id));
};
+
+ // DeltaV: bounty claim stuff begins
+ _menu.OnClaimButtonPressed += id =>
+ {
+ SendMessage(new BountyClaimedMessage(id));
+ };
+
+ _menu.OnStatusOptionSelected += (id, status) =>
+ {
+ SendMessage(new BountySetStatusMessage(id, status));
+ };
+ // DeltaV: bounty claim stuff ends
}
protected override void UpdateState(BoundUserInterfaceState message)
diff --git a/Content.Client/Cargo/UI/BountyEntry.xaml b/Content.Client/Cargo/UI/BountyEntry.xaml
index 99874cf1a5d..837edc7d900 100644
--- a/Content.Client/Cargo/UI/BountyEntry.xaml
+++ b/Content.Client/Cargo/UI/BountyEntry.xaml
@@ -10,6 +10,8 @@
+
+
@@ -17,14 +19,22 @@
+ StyleClasses="OpenBoth"/>
+
+
+
+
diff --git a/Content.Client/Cargo/UI/BountyEntry.xaml.cs b/Content.Client/Cargo/UI/BountyEntry.xaml.cs
index bac7d84bf78..477d46ab759 100644
--- a/Content.Client/Cargo/UI/BountyEntry.xaml.cs
+++ b/Content.Client/Cargo/UI/BountyEntry.xaml.cs
@@ -17,6 +17,8 @@ public sealed partial class BountyEntry : BoxContainer
public Action? OnLabelButtonPressed;
public Action? OnSkipButtonPressed;
+ public Action? OnClaimButtonPressed; // DeltaV
+ public Action? OnStatusOptionSelected; // DeltaV
public TimeSpan EndTime;
public TimeSpan UntilNextSkip;
@@ -45,6 +47,20 @@ public sealed partial class BountyEntry : BoxContainer
PrintButton.OnPressed += _ => OnLabelButtonPressed?.Invoke();
SkipButton.OnPressed += _ => OnSkipButtonPressed?.Invoke();
+
+ // Begin DeltaV bounty claiming
+ ClaimButton.OnPressed += _ => OnClaimButtonPressed?.Invoke();
+ BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.Undelivered)}"), 0);
+ BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.Waiting)}"), 1);
+ BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.OnShuttle)}"), 2);
+
+ BountyStatusSelector.Select((int) bounty.Status);
+ BountyStatusSelector.ToolTip = Loc.GetString($"bounty-console-status-tooltip-{bounty.Status.ToString()}");
+
+ var claimedByText = string.IsNullOrEmpty(bounty.ClaimedBy) ? Loc.GetString("bounty-console-claimed-by-none") : bounty.ClaimedBy;
+ ClaimedBylabel.SetMarkup(Loc.GetString("bounty-console-claimed-by", ("claimant", claimedByText)));
+ StatusLabel.SetMarkup(Loc.GetString($"bounty-console-formatted-status-{bounty.Status.ToString()}"));
+ // End DeltaV bounty claiming
}
private void UpdateSkipButton(float deltaSeconds)
diff --git a/Content.Client/Cargo/UI/CargoBountyMenu.xaml b/Content.Client/Cargo/UI/CargoBountyMenu.xaml
index 526ba69129b..2c3a9566ba5 100644
--- a/Content.Client/Cargo/UI/CargoBountyMenu.xaml
+++ b/Content.Client/Cargo/UI/CargoBountyMenu.xaml
@@ -1,8 +1,9 @@
-
+
? OnLabelButtonPressed;
public Action? OnSkipButtonPressed;
+ public Action? OnClaimButtonPressed; // DeltaV
+ public Action? OnStatusOptionSelected; // DeltaV
public CargoBountyMenu()
{
@@ -31,6 +33,8 @@ public sealed partial class CargoBountyMenu : FancyWindow
var entry = new BountyEntry(b, untilNextSkip);
entry.OnLabelButtonPressed += () => OnLabelButtonPressed?.Invoke(b.Id);
entry.OnSkipButtonPressed += () => OnSkipButtonPressed?.Invoke(b.Id);
+ entry.OnClaimButtonPressed += () => OnClaimButtonPressed?.Invoke(b.Id); // DeltaV
+ entry.BountyStatusSelector.OnItemSelected += args => OnStatusOptionSelected?.Invoke(b.Id, args.Id); // DeltaV
BountyEntriesContainer.AddChild(entry);
}
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml
index 25385c41ff6..bcb75e159b1 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml
@@ -59,9 +59,12 @@
-
-
-
+
+
+
+
+
+
@@ -73,10 +76,41 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs
index 8f667e0ec34..01bc36e382b 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs
@@ -19,12 +19,25 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
+
+// BEGIN DeltaV
+using Content.Client._DV.Traits.Assorted;
+using Content.Shared._DV.Traits.Assorted;
+using Content.Shared._DV.Medical; // Uncloneable
+using Content.Shared._DV.MedicalRecords; // Medical Records
+
+// Health Analyzer Plus
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Body.Systems;
+using Content.Client.Body.Systems;
+using Content.Shared.Chemistry.EntitySystems;
+using Content.Client.Chemistry.Containers.EntitySystems;
+using Content.Shared.Body.Components;
+// END DeltaV
namespace Content.Client.HealthAnalyzer.UI;
-using Content.Client._DV.Traits.Assorted; // DeltaV
-using Content.Shared._DV.Traits.Assorted; // DeltaV
-using Content.Shared._DV.Medical; // DeltaV - Uncloneable
-using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
+
// Health analyzer UI is split from its window because it's used by both the
// health analyzer item and the cryo pod UI.
@@ -32,6 +45,8 @@ using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
[GenerateTypedNameReferences]
public sealed partial class HealthAnalyzerControl : BoxContainer
{
+ private const string REAGENT_GROUP_MEDICINE = "Medicine"; // DeltaV - Health Analyzer
+
private readonly IEntityManager _entityManager;
private readonly SpriteSystem _spriteSystem;
private readonly IPrototypeManager _prototypes;
@@ -41,6 +56,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
private readonly UnborgableSystem _unborgable; // DeltaV
private readonly RedshirtSystem _redshirt; // DeltaV
private readonly UncloneableSystem _uncloneable; // DeltaV
+ private readonly SharedBloodstreamSystem _bloodstream; // DeltaV
+ private readonly SharedSolutionContainerSystem _solutionContainer; // DeltaV
// Begin DeltaV - Medical Records
private readonly ButtonGroup _triageStatusGroup = new();
@@ -66,6 +83,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
_unborgable = _entityManager.System(); // DeltaV
_redshirt = _entityManager.System(); // DeltaV
_uncloneable = _entityManager.System(); // DeltaV
+ _bloodstream = _entityManager.System(); // DeltaV
+ _solutionContainer = _entityManager.System(); // DeltaV
// Begin DeltaV - Medical Records
foreach (var item in Enum.GetValues())
@@ -138,9 +157,13 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
? $"{state.Temperature - Atmospherics.T0C:F1} °C ({state.Temperature:F1} K)"
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
+ // Begin DeltaV - Health Analyzer Plus
+ /*
BloodLabel.Text = !float.IsNaN(state.BloodLevel)
? $"{state.BloodLevel * 100:F1} %"
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
+ */
+ // End DeltaV - Health Analyzer Plus
StatusLabel.Text =
_entityManager.TryGetComponent(target.Value, out var mobStateComponent)
@@ -149,7 +172,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
// Total Damage
- DamageLabel.Text = _damageable.GetTotalDamage(target.Value).ToString();
+ // DamageLabel.Text = _damageable.GetTotalDamage(target.Value).ToString(); // DeltaV - Health Analyzer Plus
// Alerts
// DeltaV traits - This is going to be horrid if we just keep adding things like this.
@@ -216,6 +239,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
var damagePerType = _damageable.GetAllDamage(target.Value).DamageDict;
DrawDiagnosticGroups(damageSortedGroups, damagePerType);
+ DrawBloodstreamInfo(target.Value, state.BloodSolution, state.BloodLevel); // End DeltaV - Health Analyzer Plus
// Begin DeltaV - Medical Records
if (state.MedicalRecord is not { } records)
@@ -254,7 +278,15 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
Dictionary, FixedPoint2> groups,
IReadOnlyDictionary, FixedPoint2> damageDict)
{
- GroupsContainer.RemoveAllChildren();
+ // Begin DeltaV - Health Analyzer Plus
+ // GroupsContainer.RemoveAllChildren();
+ DamageGroupsContainer.RemoveAllChildren();
+
+ // Begin DeltaV - Health Analyzer Plus
+ var totalDamage = damageDict.Sum(x => x.Value.Double());
+ TotalDamageLabel.Text = Loc.GetString("health-analyzer-plus-window-entity-total-damage-text", ("amount", Math.Round(totalDamage, 2)));
+ NoDamageLabel.Visible = totalDamage == 0;
+ // End DeltaV - Health Analyzer Plus
foreach (var (damageGroupId, damageAmount) in groups)
{
@@ -275,7 +307,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId));
- GroupsContainer.AddChild(groupContainer);
+ // GroupsContainer.AddChild(groupContainer); // DeltaV - Health Analyzer Plus
+ DamageGroupsContainer.AddChild(groupContainer); // DeltaV - Health Analyzer Plus
// Show the damage for each type in that group.
var group = _prototypes.Index(damageGroupId);
@@ -296,6 +329,116 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
}
}
+ // Begin DeltaV - Health Analyzer Plus
+ private void DrawBloodstreamInfo(EntityUid target, Solution? bloodSolution, float bloodlevel)
+ {
+ BloodstreamReagentListContainer.RemoveAllChildren();
+
+ List bloodstream = new();
+ double totalReagentQuantity = 0;
+ double unknownReagents = 0;
+ // Make sure we can access the bloodtype and reagents before trying to use them
+ if (bloodSolution is not null)
+ {
+ if (!_entityManager.TryGetComponent(target, out var bloodstreamComp) ||
+ !_solutionContainer.ResolveSolution(target, bloodstreamComp.BloodSolutionName, ref bloodstreamComp.BloodSolution, out var bloodReagentSolution))
+ return;
+
+ // Get the blood reagent IDs to ignore in the scan
+ var bloodReagentIds = bloodstreamComp.BloodReferenceSolution.Select(b => b.Reagent);
+
+ // Get all of the medicines in the bloodstream
+ foreach (var reagent in bloodSolution!.Contents)
+ {
+ if (bloodReagentIds.Contains(reagent.Reagent))
+ continue;
+
+ if (_prototypes.Index(reagent.Reagent.Prototype).Group == REAGENT_GROUP_MEDICINE)
+ {
+ bloodstream.Add(reagent);
+ totalReagentQuantity += reagent.Quantity.Double();
+ }
+ else
+ {
+ unknownReagents += reagent.Quantity.Double();
+ }
+ }
+ }
+
+ var bloodQuantityPercent = !float.IsNaN(bloodlevel)
+ ? $"{bloodlevel * 100:F1} %"
+ : Loc.GetString("health-analyzer-window-entity-unknown-value-text");
+
+ // Display the percent and amount of blood in the system
+ // Normal health scanner is percent only, this one adds the actual units too
+ BloodLevelLabel.Text = Loc.GetString(
+ "health-analyzer-plus-window-entity-blood-level-quantity-text",
+ ("percent", bloodQuantityPercent)
+ );
+
+ // Display the total amount of reagents in the bloodstream, 0 is valid
+ TotalReagentQuantityLabel.Text = Loc.GetString(
+ "health-analyzer-plus-window-entity-total-reagents-text",
+ ("amount", Math.Round(totalReagentQuantity, 1).ToString("0.0"))
+ );
+
+ // If the bloodstream was empty, display a message instead to fill the space with something
+ NoReagentsLabel.Visible = bloodstream.Count == 0 && unknownReagents == 0;
+
+ // For each of the reagents in the bloodstream, add them to the list of reagents
+ // If there are none, this loop will simply do nothing
+ foreach (var (reagentID, reagentQuantity) in bloodstream)
+ {
+ var reagentPrototype = _prototypes.Index(reagentID.Prototype);
+
+ // Make a new container for each reagent we add to the list
+ var reagentContainer = new BoxContainer
+ {
+ Align = AlignMode.Begin,
+ Orientation = LayoutOrientation.Vertical
+ };
+
+ // Add the string "[] : u" for the current reagent
+ // The [] is a unicode block character, and is colored with the reagent color
+ // to make it easier to identify
+ reagentContainer.AddChild(
+ new RichTextLabel
+ {
+ Text = Loc.GetString("health-analyzer-plus-window-reagent-text",
+ ("reagentColor", reagentPrototype.SubstanceColor),
+ ("reagentName", reagentPrototype.LocalizedName),
+ ("amount", Math.Round(reagentQuantity.Double(), 1).ToString("0.0"))
+ )
+ }
+ );
+
+ BloodstreamReagentListContainer.AddChild(reagentContainer);
+ }
+
+ // Add unknown reagents (if any)
+ if (unknownReagents > 0)
+ {
+ var unknownReagentContainer = new BoxContainer
+ {
+ Align = AlignMode.Begin,
+ Orientation = LayoutOrientation.Vertical
+ };
+
+ unknownReagentContainer.AddChild(
+ new RichTextLabel
+ {
+ Text = Loc.GetString("health-analyzer-plus-window-unknown-reagents-text",
+ ("amount", Math.Round(unknownReagents, 1).ToString("0.0"))
+ )
+ }
+ );
+ BloodstreamReagentListContainer.AddChild(unknownReagentContainer);
+ }
+
+ return;
+ }
+ // End DeltaV - Health Analyzer Plus
+
private Texture GetTexture(string texture)
{
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
index 24747e516ca..36f93171319 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
@@ -7,7 +7,9 @@
+ VerticalExpand="True"
+ VScrollBarHidden="True"
+ HScrollBarHidden="True">
x.ID == Profile.Species);
- if (species != null)
- _defaultHeight = species.DefaultHeight;
+ var prototype = _prototypeManager.Index(Profile.Species);
+ _defaultHeight = prototype.DefaultHeight;
- var prototype = _prototypeManager.Index(Profile.Species);
var sliderPercent = (Profile.Height - prototype.MinHeight) /
(prototype.MaxHeight - prototype.MinHeight);
CDHeightSlider.Value = sliderPercent;
- CDHeight.Text = Profile.Height.ToString(CultureInfo.InvariantCulture);
+
+ var scaleReference = _defaultHeight * prototype.BaseScale.Y;
+ var newHeight = MathF.Round(MathHelper.Lerp(prototype.MinHeight, prototype.MaxHeight, sliderPercent), 2);
+ CDHeightLabel.Text = UnitConversion.GetMetricAndImperialDisplayFromScale(scaleReference * newHeight);
+ CDPullSpeedReductionLabel.Text = SmallCharacterSystem.GetPullSpeedPenaltyDisplayFromScale(newHeight);
}
// End CD - Character Records
diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml
index 06a33cd01b1..e0c9f1544aa 100644
--- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml
+++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml
@@ -73,9 +73,13 @@
+
-
-
+
+
+
+
+
diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
index 4cbcd4767b3..7ae72c6806c 100644
--- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
+++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
@@ -2,9 +2,6 @@ using Content.Client.Humanoid;
using Content.Client.Message;
using Content.Client.Players.PlayTimeTracking;
using Content.Client.Sprite;
-using Content.Client.UserInterface.Systems.Guidebook;
-using Content.Shared._DV.Species; // DeltaV - Species hider
-using Content.Shared.Body;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
@@ -22,13 +19,8 @@ using Robust.Shared.ContentPack;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Direction = Robust.Shared.Maths.Direction;
-// Begin CD - Character Records
-using System.Globalization;
-using Content.Client._CD.Records.UI;
-using Content.Shared._CD.Records;
-// End CD - Character Records
-using Content.Shared._DV.Traits;
-using Content.Shared.Humanoid.Prototypes; // DV - Traits
+using Content.Client._CD.Records.UI; // CD - Character Records
+using Content.Shared._DV.Body.Systems; // DV - Traits
namespace Content.Client.Lobby.UI
{
@@ -221,34 +213,18 @@ namespace Content.Client.Lobby.UI
// Begin CD - Character Records
#region CDHeight
- CDHeight.OnTextChanged += args =>
- {
- if (Profile is null || !float.TryParse(args.Text, out var newHeight))
- return;
-
- var prototype = _prototypeManager.Index(Profile.Species);
- newHeight = MathF.Round(Math.Clamp(newHeight, prototype.MinHeight, prototype.MaxHeight), 2);
-
- // The percentage between the start and end numbers, aka "inverse lerp"
- var sliderPercent = (newHeight - prototype.MinHeight) /
- (prototype.MaxHeight - prototype.MinHeight);
- CDHeightSlider.Value = sliderPercent;
-
- SetProfileHeight(newHeight);
- };
-
- CDHeightReset.OnPressed += _ =>
- {
- CDHeight.SetText(_defaultHeight.ToString(CultureInfo.InvariantCulture), true);
- };
-
CDHeightSlider.OnValueChanged += _ =>
{
if (Profile is null)
return;
- var prototype = _prototypeManager.Index(Profile.Species);
+
+ var prototype = _prototypeManager.Index(Profile.Species);
var newHeight = MathF.Round(MathHelper.Lerp(prototype.MinHeight, prototype.MaxHeight, CDHeightSlider.Value), 2);
- CDHeight.Text = newHeight.ToString(CultureInfo.InvariantCulture);
+
+ var speciesScale = prototype.BaseScale.Y;
+
+ CDHeightLabel.Text = UnitConversion.GetMetricAndImperialDisplayFromScale(newHeight * speciesScale);
+ CDPullSpeedReductionLabel.Text = SmallCharacterSystem.GetPullSpeedPenaltyDisplayFromScale(newHeight);
SetProfileHeight(newHeight);
};
diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringNavMapControl.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringNavMapControl.cs
index c2806a79f7d..9771886fa6d 100644
--- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringNavMapControl.cs
+++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringNavMapControl.cs
@@ -75,9 +75,11 @@ public sealed partial class CrewMonitoringNavMapControl : NavMapControl
if (!LocalizedNames.TryGetValue(netEntity, out var name))
name = Loc.GetString("navmap-unknown-entity");
+ var pos = _xform.ToMapCoordinates(blip.Coordinates); // DeltaV - map-coordinates
+
var message = name + "\n" + Loc.GetString("navmap-location",
- ("x", MathF.Round(blip.Coordinates.X)),
- ("y", MathF.Round(blip.Coordinates.Y)));
+ ("x", MathF.Round(pos.X)), // DeltaV - map-coordinates
+ ("y", MathF.Round(pos.Y))); // DeltaV - map-coordinates
_trackedEntityLabel.Text = message;
_trackedEntityPanel.Visible = true;
diff --git a/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs b/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs
index 211225119ba..6559542b775 100644
--- a/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs
+++ b/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs
@@ -88,9 +88,9 @@ public sealed partial class CryoPodWindow : FancyWindow
// Health analyzer
var maybePatient = _entityManager.GetEntity(msg.Health.TargetEntity);
var hasPatient = msg.Health.TargetEntity.HasValue;
- var hasDamage = hasPatient && msg.HasDamage;
+ // var hasDamage = hasPatient && msg.HasDamage; // DeltaV - Health Analyzer Plus
- NoDamageText.Visible = (hasPatient && !hasDamage);
+ NoDamageText.Visible = false; //(hasPatient && !hasDamage); // DeltaV - Health Analyzer Plus
HealthSection.Visible = hasPatient;
EjectPatientButton.Disabled = !hasPatient;
diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
index 5e1bcd59857..79c36c969e5 100644
--- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
+++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
@@ -208,6 +208,7 @@ namespace Content.Client.Options.UI.Tabs
AddButton(ContentKeyFunctions.MovePulledObject);
AddButton(ContentKeyFunctions.ReleasePulledObject);
AddButton(ContentKeyFunctions.Point);
+ AddButton(ContentKeyFunctions.OfferItem); // Floofstation
AddButton(ContentKeyFunctions.RotateObjectClockwise);
AddButton(ContentKeyFunctions.RotateObjectCounterclockwise);
AddButton(ContentKeyFunctions.FlipObject);
diff --git a/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml b/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml
index 9e3ee929c5c..f51c2f53fd0 100644
--- a/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml
+++ b/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml
@@ -1,9 +1,8 @@
+ SetSize="550 300">
@@ -30,9 +29,6 @@
-
-
-
diff --git a/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs b/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs
index 6e2dd8346a6..d854afa09be 100644
--- a/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs
+++ b/Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs
@@ -1,7 +1,6 @@
using System.Linq;
using Content.Client.UserInterface.Controls;
using Content.Client.UserInterface.Systems.Guidebook;
-using Content.Shared._CD.Silicons; // CosmicDrift
using Content.Shared.Guidebook;
using Content.Shared.Silicons.Borgs;
using Content.Shared.Silicons.Borgs.Components;
@@ -30,7 +29,6 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
private BorgTypePrototype? _selectedBorgType;
public event Action>? ConfirmedBorgType;
- public event Action? ConfirmedBorgSubtype; // CosmicDrift event - borg subtypes
private static readonly List> GuidebookEntries = new() { "Cyborgs", "Robotics" };
@@ -58,13 +56,6 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
ConfirmTypeButton.OnPressed += ConfirmButtonPressed;
HelpGuidebookIds = GuidebookEntries;
-
- // Start CosmicDrift Changes - borg subtypes
- ChassisSpriteSelection.SubtypeSelected += () =>
- {
- ConfirmTypeButton.Disabled = false;
- };
- // End CosmicDrift Changes - borg subtypes
}
private void UpdateInformation(BorgTypePrototype prototype)
@@ -96,14 +87,6 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
NameLabel.Text = PrototypeName(prototype);
DescriptionLabel.Text = Loc.GetString($"borg-type-{prototype.ID}-desc");
ChassisView.SetPrototype(prototype.DummyPrototype);
-
- // Start CosmicDrift Changes - borg subtypes
- if (_selectedBorgType != null)
- {
- ConfirmTypeButton.Disabled = true;
- ChassisSpriteSelection.Update(_selectedBorgType);
- }
- // End CosmicDrift Changes - borg subtypes
}
private void ConfirmButtonPressed(BaseButton.ButtonEventArgs obj)
@@ -111,7 +94,6 @@ public sealed partial class BorgSelectTypeMenu : FancyWindow
if (_selectedBorgType == null)
return;
- ConfirmedBorgSubtype?.Invoke(ChassisSpriteSelection.SubtypePrototype); // CosmicDrift
ConfirmedBorgType?.Invoke(_selectedBorgType);
}
diff --git a/Content.Client/Silicons/Borgs/BorgSelectTypeUserInterface.cs b/Content.Client/Silicons/Borgs/BorgSelectTypeUserInterface.cs
index 482014d7a89..69a55dd38be 100644
--- a/Content.Client/Silicons/Borgs/BorgSelectTypeUserInterface.cs
+++ b/Content.Client/Silicons/Borgs/BorgSelectTypeUserInterface.cs
@@ -1,6 +1,4 @@
-using Content.Shared._CD.Silicons; // CosmicDrift
-using Content.Shared._CD.Silicons.Borgs; // CosmicDrift
-using Content.Shared.Silicons.Borgs.Components;
+using Content.Shared.Silicons.Borgs.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
@@ -28,6 +26,5 @@ public sealed class BorgSelectTypeUserInterface : BoundUserInterface
_menu = this.CreateWindow();
_menu.ConfirmedBorgType += prototype => SendPredictedMessage(new BorgSelectTypeMessage(prototype));
- _menu.ConfirmedBorgSubtype += subtypePrototype => SendPredictedMessage(new BorgSelectSubtypeMessage(subtypePrototype?.ID)); // CosmicDrift - borg subtypes
}
}
diff --git a/Content.Client/Silicons/Borgs/BorgSwitchableTypeSystem.cs b/Content.Client/Silicons/Borgs/BorgSwitchableTypeSystem.cs
index 82e2487cd79..cfc0f843863 100644
--- a/Content.Client/Silicons/Borgs/BorgSwitchableTypeSystem.cs
+++ b/Content.Client/Silicons/Borgs/BorgSwitchableTypeSystem.cs
@@ -1,12 +1,9 @@
-using Content.Client.PDA; // DeltaV
-using Content.Shared._CD.Silicons.Borgs; // CosmicDrift
+using Content.Client.PDA; // DeltaV
using Content.Shared.Movement.Components;
using Content.Shared.Silicons.Borgs;
using Content.Shared.Silicons.Borgs.Components;
using Robust.Client.GameObjects;
-using Robust.Client.ResourceManagement; // CosmicDrift
-using Robust.Shared.Serialization.TypeSerializers.Implementations; // CosmicDrift
-using Robust.Shared.Timing; // CosmicDrift
+using Robust.Shared.Serialization; // DeltaV
namespace Content.Client.Silicons.Borgs;
@@ -20,7 +17,6 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
[Dependency] private readonly BorgSystem _borgSystem = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
- [Dependency] private readonly IGameTiming _timing = default!; // CosmicDrift - borg subtypes
public override void Initialize()
{
@@ -44,20 +40,15 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
Entity entity,
BorgTypePrototype prototype)
{
- // Begin Afterlight Addition - added checks to stop sprite state errors
- if (!_timing.IsFirstTimePredicted)
- return;
-
- if (TryComp(entity, out var subtype) &&
- subtype.BorgSubtype != null)
- {
- var ev = new TypeTryingToUpdateVisualsEvent();
- RaiseLocalEvent(entity, ref ev);
- return;
- }
- // End Afterlight Additions - added checks to stop sprite state errors
+ // Begin DeltaV Additions
+ if (prototype.ClientComponents is {} add)
+ EntityManager.AddComponents(entity, add);
+ // End DeltaV Additions
if (TryComp(entity, out SpriteComponent? sprite))
{
+ // Begin DeltaV Additions - work around engine bug with AddComponents
+ ((ISerializationHooks) sprite).AfterDeserialization();
+ // End DeltaV Additions
_sprite.LayerSetRsiState((entity, sprite), BorgVisualLayers.Body, prototype.SpriteBodyState);
_sprite.LayerSetRsiState((entity, sprite), BorgVisualLayers.LightStatus, prototype.SpriteToggleLightState);
}
@@ -85,26 +76,6 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
}
// DeltaV - borg pdas
- // Start CosmicDrift Changes - borg subtypes
- if (prototype.SpriteBodyMovementState is { } movementState)
- {
- var spriteMovement = EnsureComp(entity);
- spriteMovement.NoMovementLayers.Clear();
- spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
- {
- State = prototype.SpriteBodyState,
- };
- spriteMovement.MovementLayers.Clear();
- spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
- {
- State = movementState,
- };
- }
- else
- {
- RemComp(entity);
- }
- // End CosmicDrift Changes - borg subtypes
base.UpdateEntityAppearance(entity, prototype);
}
}
diff --git a/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml b/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml
index a952accd81d..2c157b97559 100644
--- a/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml
+++ b/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml
@@ -49,11 +49,6 @@
-
-
-
-
-
diff --git a/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml.cs b/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml.cs
index dd6dafd0fbd..4a822a1d595 100644
--- a/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml.cs
+++ b/Content.Client/_CD/Records/UI/CharacterRecordViewer.xaml.cs
@@ -325,8 +325,7 @@ public sealed partial class CharacterRecordViewer : FancyWindow
RecordContainerJob.Text = record.JobTitle; /* At some point in the future we might want to display the icon */
RecordContainerGender.Text = record.Gender.ToString();
RecordContainerSpecies.Text = record.Species;
- RecordContainerHeight.Text = cr.Height + " " + UnitConversion.GetImperialDisplayLength(cr.Height);
- RecordContainerWeight.Text = cr.Weight + " " + UnitConversion.GetImperialDisplayMass(cr.Weight);
+ RecordContainerWeight.Text = $"{cr.Weight} ({UnitConversion.GetImperialDisplayMass(cr.Weight)})";
RecordContainerContactName.SetValue(cr.EmergencyContactName);
RecordContainerEmployment.Visible = false;
diff --git a/Content.Client/_CD/Records/UI/RecordEditorGui.xaml b/Content.Client/_CD/Records/UI/RecordEditorGui.xaml
index ef1b6e2135c..fe99a0b5a82 100644
--- a/Content.Client/_CD/Records/UI/RecordEditorGui.xaml
+++ b/Content.Client/_CD/Records/UI/RecordEditorGui.xaml
@@ -5,12 +5,6 @@
-
-
-
-
-
-
diff --git a/Content.Client/_CD/Records/UI/RecordEditorGui.xaml.cs b/Content.Client/_CD/Records/UI/RecordEditorGui.xaml.cs
index f360a206239..bd0ee1b8728 100644
--- a/Content.Client/_CD/Records/UI/RecordEditorGui.xaml.cs
+++ b/Content.Client/_CD/Records/UI/RecordEditorGui.xaml.cs
@@ -25,14 +25,6 @@ public sealed partial class RecordEditorGui : Control
#region General
- HeightEdit.OnTextChanged += args =>
- {
- if (!int.TryParse(args.Text, out var newHeight))
- return;
- UpdateImperialHeight(newHeight);
- UpdateRecords(_records.WithHeight(newHeight));
- };
-
WeightEdit.OnTextChanged += args =>
{
if (!int.TryParse(args.Text, out var newWeight))
@@ -128,8 +120,6 @@ public sealed partial class RecordEditorGui : Control
private void UpdateWidgets()
{
- HeightEdit.SetText(_records.Height.ToString());
- UpdateImperialHeight(_records.Height);
WeightEdit.SetText(_records.Weight.ToString());
UpdateImperialWeight(_records.Weight);
ContactNameEdit.SetText(_records.EmergencyContactName);
@@ -143,13 +133,8 @@ public sealed partial class RecordEditorGui : Control
PostmortemEdit.SetText(_records.PostmortemInstructions);
}
- private void UpdateImperialHeight(int newHeight)
- {
- HeightImperialLabel.Text = UnitConversion.GetImperialDisplayLength(newHeight);
- }
-
private void UpdateImperialWeight(int newWeight)
{
- WeightImperialLabel.Text = UnitConversion.GetImperialDisplayMass(newWeight);
+ WeightImperialLabel.Text = $"({UnitConversion.GetImperialDisplayMass(newWeight)})";
}
}
diff --git a/Content.Client/_CD/Records/UI/UnitConversion.cs b/Content.Client/_CD/Records/UI/UnitConversion.cs
index 239ec6937e0..9f743b7d870 100644
--- a/Content.Client/_CD/Records/UI/UnitConversion.cs
+++ b/Content.Client/_CD/Records/UI/UnitConversion.cs
@@ -2,15 +2,47 @@ namespace Content.Client._CD.Records.UI;
public static class UnitConversion
{
+ ///
+ /// DeltaV - The average height of a human in centimeters. According to the US CDC, its
+ /// 171 for men and 160 for women. So average of that is ~165cm.
+ ///
+ /// Just kidding, we're going with EE's arbitrary standard of 175cm.
+ ///
+ private const int AVERAGE_HEIGHT_CM = 175;
+
+ ///
+ /// DeltaV - 1.0 scale is considered average for humans, so a scale of 1 will be 175cm.
+ /// Ensure that scale also includes the base species height AND the user-defined height.
+ ///
+ ///
+ ///
+ private static int GetMetricHeightFromScale(float scale = 1)
+ {
+ // cast as int because we don't care about decimal
+ return (int)Math.Max(scale * AVERAGE_HEIGHT_CM, 1); // can't be shorter than 1cm I guess
+ }
+
+ ///
+ /// DeltaV - Gets nicely formatted string that contains both metric and imperial measurements.
+ /// With a scale of 1, it should look like... 175cm (5' 9")
+ ///
+ ///
+ ///
+ public static string GetMetricAndImperialDisplayFromScale(float scale = 1)
+ {
+ var metricHeight = GetMetricHeightFromScale(scale);
+ return $"{metricHeight}cm ({GetImperialDisplayLength(metricHeight)})";
+ }
+
public static string GetImperialDisplayLength(int lengthCm)
{
- var heightIn = (int) Math.Round(lengthCm * 0.3937007874 /* cm to in*/);
- return $"({heightIn / 12}'{heightIn % 12}'')";
+ var heightIn = (int)Math.Round(lengthCm * 0.3937007874 /* cm to in*/);
+ return $"{heightIn / 12}'{heightIn % 12}\"";
}
public static string GetImperialDisplayMass(int massKg)
{
- var weightLbs = (int) Math.Round(massKg * 2.2046226218 /* kg to lbs */);
- return $"({weightLbs} lbs)";
+ var weightLbs = (int)Math.Round(massKg * 2.2046226218 /* kg to lbs */);
+ return $"{weightLbs} lbs";
}
}
diff --git a/Content.Client/_CD/Silicons/Borgs/BorgSwitchableSubtypeSystem.cs b/Content.Client/_CD/Silicons/Borgs/BorgSwitchableSubtypeSystem.cs
deleted file mode 100644
index b367c5c5354..00000000000
--- a/Content.Client/_CD/Silicons/Borgs/BorgSwitchableSubtypeSystem.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System.Linq;
-using Content.Client.Silicons.Borgs;
-using Content.Shared._CD.Silicons.Borgs;
-using Content.Shared.Movement.Components;
-using Content.Shared.Silicons.Borgs.Components;
-using Robust.Client.GameObjects;
-using Robust.Shared.Prototypes;
-
-namespace Content.Client._CD.Silicons.Borgs;
-
-///
-/// Primarily handles the appearance aspects of the borg subtype.
-///
-public sealed class BorgSwitchableSubtypeSystem : SharedBorgSwitchableSubtypeSystem
-{
- [Dependency] private readonly SpriteSystem _sprite = default!;
- [Dependency] private readonly BorgSystem _borg = default!;
- [Dependency] private readonly AppearanceSystem _appearance = default!;
-
- public override void Initialize()
- {
- base.Initialize();
-
- SubscribeLocalEvent(OnComponentStartup);
- SubscribeLocalEvent(OnAutoHandleEvent);
- }
-
- private void OnAutoHandleEvent(Entity ent, ref AfterAutoHandleStateEvent args)
- {
- SelectBorgSubtype(ent);
- }
-
- private void OnComponentStartup(Entity ent, ref ComponentStartup args)
- {
- SelectBorgSubtype(ent);
- }
-
- protected override void UpdateEntityAppearance(Entity entity, EntityPrototype borgSubtypePrototype)
- {
- // LOT of copy pasted code from BorgSwitchableTypeSystem, but is probably necessary unless the upstream code
- // is refactored
-
- if (!borgSubtypePrototype.TryGetComponent(out var borgSubtype, ComponentFactory))
- return;
-
- // get our required components
- var (owner, _) = entity;
- if (!TryComp(entity, out var chassisSprite))
- return;
-
- // remove all existing layers
- for (int i = chassisSprite.AllLayers.Count() - 1; i >= 0; i--)
- {
- _sprite.RemoveLayer((entity, chassisSprite), i);
- }
-
- for (int i = 0; i < borgSubtype.LayerData.Length; i++)
- {
- var layerData = borgSubtype.LayerData[i];
-
- layerData.RsiPath = borgSubtype.SpritePath?.ToString();
- if (borgSubtype.Offset != null)
- layerData.Offset = borgSubtype.Offset;
- _sprite.AddLayer((owner, chassisSprite), layerData, i);
- }
-
- if (TryComp(entity, out var chassis))
- {
- _borg.SetMindStates(
- (entity.Owner, chassis),
- borgSubtype.SpriteHasMindState,
- borgSubtype.SpriteNoMindState);
-
- if (TryComp(entity, out AppearanceComponent? appearance))
- {
- // Queue update so state changes apply.
- _appearance.QueueUpdate(entity, appearance);
- }
- }
-
- if (borgSubtype.SpriteBodyMovementState is { } movementState)
- {
- var spriteMovement = EnsureComp(entity);
- spriteMovement.NoMovementLayers.Clear();
- spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
- {
- State = borgSubtype.SpriteBodyState,
- };
- spriteMovement.MovementLayers.Clear();
- spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
- {
- State = movementState,
- };
- }
- else
- {
- RemComp(entity);
- }
-
- base.UpdateEntityAppearance(entity, borgSubtypePrototype);
- }
-}
diff --git a/Content.Client/_CD/Silicons/Borgs/UI/ChassisSpriteSelection.xaml b/Content.Client/_CD/Silicons/Borgs/UI/ChassisSpriteSelection.xaml
deleted file mode 100644
index 5727d95f4fc..00000000000
--- a/Content.Client/_CD/Silicons/Borgs/UI/ChassisSpriteSelection.xaml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Content.Client/_CD/Silicons/Borgs/UI/ChassisSpriteSelection.xaml.cs b/Content.Client/_CD/Silicons/Borgs/UI/ChassisSpriteSelection.xaml.cs
deleted file mode 100644
index c300dbcf2d0..00000000000
--- a/Content.Client/_CD/Silicons/Borgs/UI/ChassisSpriteSelection.xaml.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using Content.Shared.Silicons.Borgs;
-using Robust.Client.AutoGenerated;
-using Robust.Client.UserInterface;
-using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Prototypes;
-
-namespace Content.Client._CD.Silicons.Borgs.UI;
-
-[GenerateTypedNameReferences]
-public sealed partial class ChassisSpriteSelection : Control
-{
- [Dependency] private readonly IComponentFactory _componentFactory = default!;
- [Dependency] private readonly IPrototypeManager _prototype = default!;
-
- public EntityPrototype? SubtypePrototype;
- public event Action? SubtypeSelected;
-
- private const int PrototypeViewSize = 2;
- private static readonly ProtoId _borgSubtypeCategory = "BorgSubtype";
-
- public ChassisSpriteSelection()
- {
- RobustXamlLoader.Load(this);
- IoCManager.InjectDependencies(this);
- }
-
- public void Update(BorgTypePrototype borgTypePrototype)
- {
- MainContainer.Visible = true;
-
- OptionsContainer.RemoveAllChildren();
-
- var buttonGroup = new ButtonGroup();
- List