Skip to content

Commit a236172

Browse files
authored
Cyberpsychosis and a admeme (ss14Starlight#2791)
## Short description smth smth "weakness of the flesh" and a implementation is in need of testing. look it for in your local admin vote. ## Why we need to add this <!-- What is the reason for adding these changes? Please post links to Discussions as well as Bug Reports here. Please describe how this will change the game balance. --> ## Media (Video/Screenshots) <!-- If your PR contains in-game changes you must provide screenshots/videos of the changes. --> ## Checks <!-- check boxes for faster reviewing of your PR --> - [ ] I do not require assistance to complete the PR. - [ ] Before posting/requesting review of a PR, I have verified that the changes work. - [ ] I have added screenshots/videos of the changes, or this PR does not change in-game mechanics. - [ ] I affirm that my changes are licensed under the [Starlight Fork License](https://github.com/ss14Starlight/space-station-14/blob/Starlight/LICENSE-Starlight.TXT) and grant permission for use in this repository under its conditions. **Changelog** <!-- If you want the players to know about changes made in this PR, specify them using the template outside the comment. Short and informative. :cl: STARLIGHT TEAM - add: Added Starlight. - remove: Removed SS13. - tweak: Changed SS14. - fix: Fixed Rinary. -->
2 parents fa53096 + b9beb60 commit a236172

339 files changed

Lines changed: 10090 additions & 363 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<controls:FancyWindow
22
xmlns="https://spacestation14.io"
33
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
4-
MaxHeight="525"
54
MinWidth="300">
5+
<!-- Starlight
66
<ScrollContainer
77
Margin="5 5 5 5"
88
ReturnMeasure="True"
99
VerticalExpand="True">
10+
-->
1011
<BoxContainer
1112
Name="RootContainer"
13+
Margin="5 5 5 5"
1214
VerticalExpand="True"
1315
Orientation="Vertical">
1416
<Label
@@ -22,11 +24,17 @@
2224
<BoxContainer Orientation="Horizontal" Margin="0 0 0 5">
2325
<SpriteView OverrideDirection="South" Scale="2 2" Name="SpriteView" Access="Public" SetSize="64 64" />
2426
<TextureRect Name="NoDataTex" Access="Public" SetSize="64 64" Visible="false" Stretch="KeepAspectCentered" TexturePath="/Textures/Interface/Misc/health_analyzer_out_of_range.png"/>
25-
<BoxContainer Margin="5 0 0 0" Orientation="Vertical" VerticalAlignment="Top">
26-
<RichTextLabel Name="NameLabel" SetWidth="150" />
27-
<Label Name="SpeciesLabel" VerticalAlignment="Top" StyleClasses="LabelSubText" />
27+
<!-- Starlight begin - changed to fix species and name labels overlapping -->
28+
<BoxContainer Margin="5 0 0 0" Orientation="Vertical" VerticalAlignment="Top" SetWidth="155">
29+
<BoxContainer Orientation="Vertical" Margin="0 0 0 4">
30+
<RichTextLabel Name="NameLabel" SetWidth="150" />
31+
</BoxContainer>
32+
<BoxContainer Orientation="Vertical">
33+
<Label Name="SpeciesLabel" StyleClasses="LabelSubText" />
34+
</BoxContainer>
2835
</BoxContainer>
29-
<Label Margin="0 0 5 0" HorizontalExpand="True" HorizontalAlignment="Right" VerticalExpand="True"
36+
<!-- Starlight end -->
37+
<Label Margin="0 0 5 0" HorizontalExpand="True" HorizontalAlignment="Right"
3038
VerticalAlignment="Top" Name="ScanModeLabel"
3139
Text="{Loc 'health-analyzer-window-entity-unknown-text'}" />
3240
</BoxContainer>
@@ -59,6 +67,17 @@
5967
Orientation="Vertical">
6068
</BoxContainer>
6169

70+
<!-- Starlight begin - metabolizing chems section of ui -->
71+
<PanelContainer Name="ChemicalsDivider" Visible="False" StyleClasses="LowDivider" />
72+
73+
<BoxContainer
74+
Name="ChemicalsContainer"
75+
Visible="False"
76+
Margin="0 5 0 5"
77+
Orientation="Vertical">
78+
</BoxContainer>
79+
<!-- Starlight end -->
80+
6281
</BoxContainer>
63-
</ScrollContainer>
82+
<!-- </ScrollContainer> Starlight -->
6483
</controls:FancyWindow>

Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs

Lines changed: 214 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Numerics;
33
using Content.Shared.Atmos;
44
using Content.Client.UserInterface.Controls;
5+
using Content.Shared.Chemistry.Reagent; // Starlight
56
using Content.Shared.Damage.Components;
67
using Content.Shared.Damage.Prototypes;
78
using Content.Shared.FixedPoint;
@@ -25,6 +26,9 @@ namespace Content.Client.HealthAnalyzer.UI
2526
[GenerateTypedNameReferences]
2627
public sealed partial class HealthAnalyzerWindow : FancyWindow
2728
{
29+
private static readonly Color Green = Color.FromHex("#00FF00"); // Starlight
30+
private static readonly Color Red = Color.FromHex("#FF0000"); // Starlight
31+
2832
private readonly IEntityManager _entityManager;
2933
private readonly SpriteSystem _spriteSystem;
3034
private readonly IPrototypeManager _prototypes;
@@ -90,9 +94,32 @@ public void Populate(HealthAnalyzerScannedUserMessage msg)
9094
? $"{msg.Temperature - Atmospherics.T0C:F1} °C ({msg.Temperature:F1} K)"
9195
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
9296

93-
BloodLabel.Text = !float.IsNaN(msg.BloodLevel)
94-
? $"{msg.BloodLevel * 100:F1} %"
95-
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
97+
// Starlight begin - blood level color gradient and exclaimation marks to show severity
98+
if (!float.IsNaN(msg.BloodLevel))
99+
{
100+
var bloodPercent = msg.BloodLevel;
101+
var exclamations = bloodPercent switch {
102+
<= 0f => "!!!!",
103+
<= 0.25f => "!!!",
104+
<= 0.5f => "!!",
105+
<= 0.75f => "!",
106+
_ => ""
107+
};
108+
109+
BloodLabel.Text = $"{bloodPercent * 100:F1} %{exclamations}";
110+
111+
// Color gradient: Goes from green at 100% to red at 50% then stays red.
112+
var clampedPercent = Math.Max(bloodPercent, 0.5f);
113+
var scaled = (clampedPercent - 0.5f) / 0.5f;
114+
115+
BloodLabel.FontColorOverride = Color.InterpolateBetween(Red, Green, scaled);
116+
}
117+
// Starlight end
118+
else
119+
{
120+
BloodLabel.Text = Loc.GetString("health-analyzer-window-entity-unknown-value-text");
121+
BloodLabel.FontColorOverride = null;
122+
}
96123

97124
StatusLabel.Text =
98125
_entityManager.TryGetComponent<MobStateComponent>(target.Value, out var mobStateComponent)
@@ -138,6 +165,8 @@ public void Populate(HealthAnalyzerScannedUserMessage msg)
138165
IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
139166

140167
DrawDiagnosticGroups(damageSortedGroups, damagePerType);
168+
169+
DrawMetabolizingChemicals(msg.MetabolizingReagents); // Starlight - Metabolizing Chemicals Section
141170
}
142171

143172
private static string GetStatus(MobState mobState)
@@ -151,55 +180,185 @@ private static string GetStatus(MobState mobState)
151180
};
152181
}
153182

183+
// Starlight begin - Draw Damage Groups in a two column grid in their own boxes.
154184
private void DrawDiagnosticGroups(
155185
Dictionary<string, FixedPoint2> groups,
156186
IReadOnlyDictionary<string, FixedPoint2> damageDict)
157187
{
158188
GroupsContainer.RemoveAllChildren();
159189

160-
foreach (var (damageGroupId, damageAmount) in groups)
190+
var gridContainer = new GridContainer
161191
{
162-
if (damageAmount == 0)
163-
continue;
192+
Columns = 2,
193+
};
164194

195+
GroupsContainer.AddChild(gridContainer);
196+
197+
var columnIndex = 0;
198+
foreach (var (damageGroupId, damageAmount) in groups)
199+
{
165200
var groupTitleText = $"{Loc.GetString(
166201
"health-analyzer-window-damage-group-text",
167202
("damageGroup", _prototypes.Index<DamageGroupPrototype>(damageGroupId).LocalizedName),
168203
("amount", damageAmount)
169204
)}";
170205

206+
// Create a bordered box for each damage group
207+
var groupBox = new PanelContainer
208+
{
209+
Margin = new Thickness(2),
210+
MinWidth = 155,
211+
};
212+
213+
// Boxes in the second column get right aligned
214+
if (columnIndex % 2 == 1)
215+
{
216+
groupBox.HorizontalAlignment = HAlignment.Right;
217+
}
218+
219+
groupBox.PanelOverride = new StyleBoxFlat
220+
{
221+
BorderColor = Color.Gray,
222+
BorderThickness = new Thickness(1),
223+
ContentMarginLeftOverride = 4,
224+
ContentMarginRightOverride = 4,
225+
ContentMarginTopOverride = 4,
226+
ContentMarginBottomOverride = 4,
227+
};
228+
171229
var groupContainer = new BoxContainer
172230
{
173231
Align = BoxContainer.AlignMode.Begin,
174232
Orientation = BoxContainer.LayoutOrientation.Vertical,
175233
};
176234

177-
groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId));
235+
var titleRow = CreateDiagnosticGroupTitleRow(groupTitleText, (float)damageAmount, damageGroupId);
236+
groupContainer.AddChild(titleRow);
178237

179-
GroupsContainer.AddChild(groupContainer);
238+
// Add divider line under the title row
239+
var divider = new PanelContainer
240+
{
241+
MinHeight = 1,
242+
Margin = new Thickness(0, 0, 0, 4),
243+
};
244+
divider.PanelOverride = new StyleBoxFlat(Color.Gray);
245+
groupContainer.AddChild(divider);
180246

181-
// Show the damage for each type in that group.
182247
var group = _prototypes.Index<DamageGroupPrototype>(damageGroupId);
183248

184249
foreach (var type in group.DamageTypes)
185250
{
186251
if (!damageDict.TryGetValue(type, out var typeAmount) || typeAmount <= 0)
187252
continue;
188253

189-
var damageString = Loc.GetString(
190-
"health-analyzer-window-damage-type-text",
191-
("damageType", _prototypes.Index<DamageTypePrototype>(type).LocalizedName),
192-
("amount", typeAmount)
193-
);
254+
var damageTypeName = _prototypes.Index<DamageTypePrototype>(type).LocalizedName;
255+
var typeId = type.ToString().ToLowerInvariant();
256+
257+
var damageRow = new BoxContainer
258+
{
259+
Orientation = BoxContainer.LayoutOrientation.Horizontal,
260+
Margin = new Thickness(0, 2),
261+
};
262+
263+
// Add damage type icon
264+
damageRow.AddChild(new TextureRect
265+
{
266+
SetSize = new Vector2(15, 15),
267+
Texture = GetTexture(typeId),
268+
Margin = new Thickness(0, 0, 4, 0),
269+
});
270+
271+
var typeLabel = new Label
272+
{
273+
Text = damageTypeName,
274+
HorizontalExpand = true,
275+
HorizontalAlignment = HAlignment.Left,
276+
};
277+
278+
var amountLabel = new Label
279+
{
280+
Text = typeAmount.ToString(),
281+
HorizontalAlignment = HAlignment.Right,
282+
};
283+
284+
damageRow.AddChild(typeLabel);
285+
damageRow.AddChild(amountLabel);
286+
groupContainer.AddChild(damageRow);
287+
}
288+
289+
groupBox.AddChild(groupContainer);
290+
gridContainer.AddChild(groupBox);
291+
columnIndex++;
292+
}
293+
}
294+
295+
// Metabolizing chemicals display
296+
private void DrawMetabolizingChemicals(List<(string ReagentId, FixedPoint2 Quantity)>? reagents)
297+
{
298+
ChemicalsContainer.RemoveAllChildren();
299+
300+
var hasChemicals = reagents != null && reagents.Count > 0;
301+
302+
ChemicalsDivider.Visible = hasChemicals;
303+
ChemicalsContainer.Visible = hasChemicals;
304+
305+
if (!hasChemicals || reagents == null)
306+
return;
307+
308+
// Sort by quantity descending
309+
var sortedReagents = reagents.OrderByDescending(r => r.Quantity).ToList();
310+
311+
foreach (var reagent in sortedReagents)
312+
{
313+
var reagentName = reagent.ReagentId;
314+
var reagentColor = Color.White;
194315

195-
groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, " · ")));
316+
if (_prototypes.TryIndex<ReagentPrototype>(reagent.ReagentId, out var reagentProto))
317+
{
318+
reagentName = reagentProto.LocalizedName;
319+
reagentColor = reagentProto.SubstanceColor;
320+
196321
}
322+
323+
var rowContainer = new BoxContainer
324+
{
325+
Orientation = BoxContainer.LayoutOrientation.Horizontal,
326+
Margin = new Thickness(0, 2),
327+
};
328+
329+
// Color bar
330+
var colorBar = new PanelContainer
331+
{
332+
MinWidth = 10,
333+
MinHeight = 16,
334+
Margin = new Thickness(0, 0, 6, 0),
335+
};
336+
colorBar.PanelOverride = new StyleBoxFlat(reagentColor);
337+
338+
var nameLabel = new Label
339+
{
340+
Text = reagentName,
341+
HorizontalExpand = true,
342+
HorizontalAlignment = HAlignment.Left,
343+
};
344+
345+
var quantityLabel = new Label
346+
{
347+
Text = $"{reagent.Quantity}u",
348+
HorizontalAlignment = HAlignment.Right,
349+
};
350+
351+
rowContainer.AddChild(colorBar);
352+
rowContainer.AddChild(nameLabel);
353+
rowContainer.AddChild(quantityLabel);
354+
ChemicalsContainer.AddChild(rowContainer);
197355
}
198356
}
357+
// Starlight end
199358

200359
private Texture GetTexture(string texture)
201360
{
202-
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
361+
var rsiPath = new ResPath("/Textures/_Starlight/Objects/Devices/health_analyzer.rsi"); // Starlight - new rsi for new icons :)
203362
var rsiSprite = new SpriteSpecifier.Rsi(rsiPath, texture);
204363

205364
var rsi = _cache.GetResource<RSIResource>(rsiSprite.RsiPath).RSI;
@@ -219,24 +378,51 @@ private static Label CreateDiagnosticItemLabel(string text)
219378
};
220379
}
221380

222-
private BoxContainer CreateDiagnosticGroupTitle(string text, string id)
381+
// Starlight begin - damage group titles get a color gradient and exclamations to indicate severity
382+
private BoxContainer CreateDiagnosticGroupTitleRow(string text, float damageAmount, string damageGroupId)
223383
{
224-
var rootContainer = new BoxContainer
384+
// Color gradient: green (0) -> red (100+)
385+
var clampedDamage = Math.Min(damageAmount, 100f);
386+
var damagePercent = clampedDamage / 100f;
387+
388+
var titleColor = Color.InterpolateBetween(Green, Red, damagePercent);
389+
390+
var exclamations = damageAmount switch {
391+
> 200f => " !!!!",
392+
> 100f => " !!!",
393+
> 75f => " !!",
394+
> 50f => " !",
395+
_ => ""
396+
};
397+
var titleRow = new BoxContainer
225398
{
226-
Margin = new Thickness(0, 6, 0, 0),
227-
VerticalAlignment = VAlignment.Bottom,
228399
Orientation = BoxContainer.LayoutOrientation.Horizontal,
400+
Margin = new Thickness(0, 0, 0, 4),
229401
};
230-
231-
rootContainer.AddChild(new TextureRect
402+
403+
var groupId = damageGroupId.ToLowerInvariant();
404+
405+
// Add damage group icon
406+
titleRow.AddChild(new TextureRect
232407
{
233-
SetSize = new Vector2(30, 30),
234-
Texture = GetTexture(id.ToLower())
408+
SetSize = new Vector2(15, 15),
409+
Texture = GetTexture(groupId),
410+
Margin = new Thickness(0, 0, 4, 0),
411+
VerticalAlignment = VAlignment.Center,
235412
});
236-
237-
rootContainer.AddChild(CreateDiagnosticItemLabel(text));
238-
239-
return rootContainer;
413+
414+
var titleLabel = new Label
415+
{
416+
Text = text + exclamations,
417+
HorizontalExpand = true,
418+
HorizontalAlignment = HAlignment.Center,
419+
FontColorOverride = titleColor,
420+
};
421+
422+
titleRow.AddChild(titleLabel);
423+
424+
return titleRow;
240425
}
426+
// Starlight end
241427
}
242428
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using Content.Shared._Starlight.Actions.InherentAction;
2+
3+
namespace Content.Client._Starlight.InherentAction;
4+
public sealed class InherentActionSystem : SharedInherentActionSystem
5+
{
6+
}

0 commit comments

Comments
 (0)