This repository has been archived by the owner on Nov 1, 2024. It is now read-only.
forked from new-frontiers-14/frontier-station-14
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Medical recipe guidebook entries (new-frontiers-14#2331)
- Loading branch information
Showing
19 changed files
with
748 additions
and
3 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
Content.Client/_NF/Guidebook/Controls/GuideMedicalComposition.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<BoxContainer xmlns="https://spacestation14.io" | ||
Orientation="Horizontal" | ||
HorizontalAlignment="Stretch" | ||
HorizontalExpand="True" | ||
Margin="0 0 0 5"> | ||
<BoxContainer Name="ReactantsContainer" Orientation="Vertical" HorizontalExpand="True" VerticalAlignment="Center"> | ||
<Label Name="ReagentLabel" | ||
HorizontalExpand="True" | ||
HorizontalAlignment="Left" | ||
VerticalAlignment="Center" | ||
Access="Public" | ||
Margin="25 0 0 0"/> <!-- Frontier: left margin 2<25 - matches reagent plant metabolism's stacked margins with GuideFoodEmbed --> | ||
</BoxContainer> | ||
<BoxContainer Orientation="Vertical" VerticalAlignment="Center"> | ||
<Label Name="AmountLabel" | ||
HorizontalAlignment="Right" | ||
VerticalAlignment="Center" | ||
Access="Public" | ||
Margin="10 0 0 0"/> <!-- Frontier: left margin 2<10 --> | ||
</BoxContainer> | ||
</BoxContainer> |
32 changes: 32 additions & 0 deletions
32
Content.Client/_NF/Guidebook/Controls/GuideMedicalComposition.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using Content.Client.Guidebook.Controls; | ||
using Content.Client.UserInterface.ControlExtensions; | ||
using Content.Shared.Chemistry.Reagent; | ||
using Content.Shared.FixedPoint; | ||
using JetBrains.Annotations; | ||
using Robust.Client.AutoGenerated; | ||
using Robust.Client.UserInterface.Controls; | ||
using Robust.Client.UserInterface.XAML; | ||
|
||
namespace Content.Client._NF.Guidebook.Controls; // Frontier: add _EE | ||
|
||
[UsedImplicitly, GenerateTypedNameReferences] | ||
public sealed partial class GuideMedicalComposition : BoxContainer, ISearchableControl | ||
{ | ||
public GuideMedicalComposition(ReagentPrototype proto, FixedPoint2 quantity) | ||
{ | ||
RobustXamlLoader.Load(this); | ||
|
||
ReagentLabel.Text = proto.LocalizedName; | ||
AmountLabel.Text = quantity.ToString(); | ||
} | ||
|
||
public bool CheckMatchesSearch(string query) | ||
{ | ||
return this.ChildrenContainText(query); | ||
} | ||
|
||
public void SetHiddenState(bool state, string query) | ||
{ | ||
Visible = CheckMatchesSearch(query) ? state : !state; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
Content.Client/_NF/Guidebook/Controls/GuideMedicalDamage.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<BoxContainer xmlns="https://spacestation14.io" | ||
Orientation="Horizontal" | ||
HorizontalAlignment="Stretch" | ||
HorizontalExpand="True" | ||
Margin="0 0 0 5"> | ||
<BoxContainer Name="DamageContainer" Orientation="Vertical" HorizontalExpand="True" VerticalAlignment="Center"> | ||
<RichTextLabel Name="DamageLabel" | ||
HorizontalExpand="True" | ||
HorizontalAlignment="Left" | ||
VerticalAlignment="Center" | ||
Access="Public" | ||
Margin="25 0 0 0"/> <!-- Frontier: left margin 2<25 - matches reagent plant metabolism's stacked margins with GuideFoodEmbed --> | ||
</BoxContainer> | ||
<BoxContainer Orientation="Vertical" VerticalAlignment="Center"> | ||
<RichTextLabel Name="AmountLabel" | ||
HorizontalAlignment="Right" | ||
VerticalAlignment="Center" | ||
Access="Public" | ||
Margin="10 0 0 0"/> <!-- Frontier: left margin 2<10 --> | ||
</BoxContainer> | ||
</BoxContainer> |
40 changes: 40 additions & 0 deletions
40
Content.Client/_NF/Guidebook/Controls/GuideMedicalDamage.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using Content.Client.Guidebook.Controls; | ||
using Content.Client.UserInterface.ControlExtensions; | ||
using Content.Shared.Damage.Prototypes; | ||
using Content.Shared.FixedPoint; | ||
using JetBrains.Annotations; | ||
using Robust.Client.AutoGenerated; | ||
using Robust.Client.UserInterface.Controls; | ||
using Robust.Client.UserInterface.XAML; | ||
|
||
namespace Content.Client._NF.Guidebook.Controls; | ||
|
||
[UsedImplicitly, GenerateTypedNameReferences] | ||
public sealed partial class GuideMedicalDamage : BoxContainer, ISearchableControl | ||
{ | ||
public GuideMedicalDamage(DamageTypePrototype proto, FixedPoint2 quantity) | ||
{ | ||
RobustXamlLoader.Load(this); | ||
|
||
DamageLabel.Text = proto.LocalizedName; | ||
AmountLabel.Text = quantity.ToString(); | ||
} | ||
|
||
public GuideMedicalDamage(DamageGroupPrototype proto, FixedPoint2 quantity) | ||
{ | ||
RobustXamlLoader.Load(this); | ||
|
||
DamageLabel.Text = Loc.GetString("guidebook-medical-damage-group", ("name", proto.LocalizedName)); | ||
AmountLabel.Text = quantity.ToString(); | ||
} | ||
|
||
public bool CheckMatchesSearch(string query) | ||
{ | ||
return this.ChildrenContainText(query); | ||
} | ||
|
||
public void SetHiddenState(bool state, string query) | ||
{ | ||
Visible = CheckMatchesSearch(query) ? state : !state; | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
Content.Client/_NF/Guidebook/Controls/GuideMedicalEmbed.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<BoxContainer xmlns="https://spacestation14.io" | ||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client" | ||
Orientation="Vertical" | ||
Margin="5 5 5 5"> | ||
<PanelContainer HorizontalExpand="True"> | ||
<PanelContainer.PanelOverride> | ||
<gfx:StyleBoxFlat BorderThickness="1" BorderColor="#777777"/> | ||
</PanelContainer.PanelOverride> | ||
<BoxContainer Orientation="Vertical"> | ||
<PanelContainer Name="NameBackground" HorizontalExpand="True" VerticalExpand="False"> | ||
<RichTextLabel Name="ResultName" HorizontalAlignment="Center"/> | ||
</PanelContainer> | ||
<BoxContainer Name="RecipesContainer" HorizontalExpand="True" Visible="false"> | ||
<Collapsible HorizontalExpand="True"> | ||
<CollapsibleHeading Title="{Loc 'guidebook-food-recipes-header'}"/> | ||
<CollapsibleBody> | ||
<GridContainer Name="RecipesDescriptionContainer" | ||
Margin="10 0 10 0" | ||
Columns="1" | ||
HSeparationOverride="0" | ||
HorizontalAlignment="Stretch" | ||
HorizontalExpand="True"/> | ||
</CollapsibleBody> | ||
</Collapsible> | ||
</BoxContainer> | ||
<BoxContainer Name="CompositionContainer" HorizontalExpand="True" Visible="false"> | ||
<Collapsible> | ||
<CollapsibleHeading Title="{Loc 'guidebook-medical-reagents-header'}"/> | ||
<CollapsibleBody> | ||
<BoxContainer Name="CompositionDescriptionContainer" | ||
Orientation="Vertical" | ||
Margin="10 0 10 0" | ||
HorizontalExpand="True"/> | ||
</CollapsibleBody> | ||
</Collapsible> | ||
</BoxContainer> | ||
<BoxContainer Name="DamageContainer" HorizontalExpand="True" Visible="false"> | ||
<Collapsible> | ||
<CollapsibleHeading Title="{Loc 'guidebook-medical-damage-header'}"/> | ||
<CollapsibleBody> | ||
<BoxContainer Name="DamageDescriptionContainer" | ||
Orientation="Vertical" | ||
Margin="10 0 10 0" | ||
HorizontalExpand="True"/> | ||
</CollapsibleBody> | ||
</Collapsible> | ||
</BoxContainer> | ||
<BoxContainer Margin="10 5 10 10" HorizontalExpand="True"> | ||
<RichTextLabel Name="Description" HorizontalAlignment="Left"/> | ||
</BoxContainer> | ||
</BoxContainer> | ||
</PanelContainer> | ||
</BoxContainer> |
188 changes: 188 additions & 0 deletions
188
Content.Client/_NF/Guidebook/Controls/GuideMedicalEmbed.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using Content.Client._NF.Medical.EntitySystems; | ||
using Content.Client.Chemistry.EntitySystems; | ||
using Content.Client.Guidebook.Controls; | ||
using Content.Client.Guidebook.Richtext; | ||
using Content.Client.Message; | ||
using Content.Shared.Chemistry.Reagent; | ||
using Content.Shared.Damage.Prototypes; | ||
using Content.Shared.FixedPoint; | ||
using JetBrains.Annotations; | ||
using Robust.Client.AutoGenerated; | ||
using Robust.Client.Graphics; | ||
using Robust.Client.UserInterface; | ||
using Robust.Client.UserInterface.Controls; | ||
using Robust.Client.UserInterface.XAML; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Utility; | ||
|
||
namespace Content.Client._NF.Guidebook.Controls; | ||
|
||
/// <summary> | ||
/// Control for embedding a medical recipe into a guidebook. | ||
/// </summary> | ||
[UsedImplicitly, GenerateTypedNameReferences] | ||
public sealed partial class GuideMedicalEmbed : BoxContainer, IDocumentTag, ISearchableControl | ||
{ | ||
[Dependency] private readonly IEntitySystemManager _systemManager = default!; | ||
[Dependency] private readonly IPrototypeManager _prototype = default!; | ||
|
||
private readonly MedicalGuideDataSystem _medicalGuideData; | ||
private readonly ISawmill _logger = default!; | ||
|
||
public GuideMedicalEmbed() | ||
{ | ||
RobustXamlLoader.Load(this); | ||
IoCManager.InjectDependencies(this); | ||
_medicalGuideData = _systemManager.GetEntitySystem<MedicalGuideDataSystem>(); | ||
_logger = Logger.GetSawmill("medical guide"); | ||
MouseFilter = MouseFilterMode.Stop; | ||
} | ||
|
||
public GuideMedicalEmbed(MedicalGuideEntry entry) : this() | ||
{ | ||
GenerateControl(entry); | ||
} | ||
|
||
public bool CheckMatchesSearch(string query) | ||
{ | ||
return ResultName.GetMessage()?.Contains(query, StringComparison.InvariantCultureIgnoreCase) == true | ||
|| Description.GetMessage()?.Contains(query, StringComparison.InvariantCultureIgnoreCase) == true; | ||
} | ||
|
||
public void SetHiddenState(bool state, string query) | ||
{ | ||
Visible = CheckMatchesSearch(query) ? state : !state; | ||
} | ||
|
||
public bool TryParseTag(Dictionary<string, string> args, [NotNullWhen(true)] out Control? control) | ||
{ | ||
control = null; | ||
if (!args.TryGetValue("Result", out var id)) | ||
{ | ||
_logger.Error("Result embed tag is missing food prototype argument."); | ||
return false; | ||
} | ||
|
||
if (!_medicalGuideData.TryGetData(id, out var data)) | ||
{ | ||
_logger.Warning($"Specified result prototype \"{id}\" does not have any known sources."); | ||
return false; | ||
} | ||
|
||
GenerateControl(data); | ||
|
||
control = this; | ||
return true; | ||
} | ||
|
||
private void GenerateControl(MedicalGuideEntry data) | ||
{ | ||
_prototype.TryIndex(data.Result, out var proto); | ||
if (proto == null) | ||
{ | ||
ResultName.SetMarkup(Loc.GetString("guidebook-food-unknown-proto", ("id", data.Result))); | ||
return; | ||
} | ||
|
||
var composition = data.Composition | ||
.Select(it => _prototype.TryIndex<ReagentPrototype>(it.Reagent.Prototype, out var reagent) ? (reagent, it.Quantity) : (null, 0)) | ||
.Where(it => it.reagent is not null) | ||
.Cast<(ReagentPrototype, FixedPoint2)>() | ||
.ToList(); | ||
|
||
#region Colors | ||
|
||
CalculateColors(composition, out var textColor, out var backgroundColor); | ||
|
||
NameBackground.PanelOverride = new StyleBoxFlat | ||
{ | ||
BackgroundColor = backgroundColor | ||
}; | ||
ResultName.SetMarkup(Loc.GetString("guidebook-food-name", ("color", textColor), ("name", proto.Name))); | ||
|
||
#endregion | ||
|
||
#region Recipes | ||
if (data.Recipes.Length > 0) | ||
RecipesContainer.Visible = true; | ||
|
||
foreach (var recipe in data.Recipes.OrderBy(it => it.OutputCount)) | ||
{ | ||
var control = new GuideMedicalSource(proto, recipe, _prototype); | ||
RecipesDescriptionContainer.AddChild(control); | ||
} | ||
|
||
#endregion | ||
|
||
#region Composition | ||
if (composition.Count > 0) | ||
CompositionContainer.Visible = true; | ||
|
||
foreach (var (reagent, quantity) in composition) | ||
{ | ||
var control = new GuideMedicalComposition(reagent, quantity); | ||
CompositionDescriptionContainer.AddChild(control); | ||
} | ||
|
||
#endregion | ||
|
||
#region Damage | ||
var damageDict = data.Healing?.DamageDict ?? new(); | ||
if (damageDict.Count > 0) | ||
DamageContainer.Visible = true; | ||
|
||
foreach (var (damageType, damage) in damageDict) | ||
{ | ||
if (_prototype.TryIndex<DamageTypePrototype>(damageType, out var damageProto)) | ||
{ | ||
var control = new GuideMedicalDamage(damageProto, -damage); // Negative damage means positive healing | ||
DamageDescriptionContainer.AddChild(control); | ||
} | ||
else if (_prototype.TryIndex<DamageGroupPrototype>(damageType, out var groupProto)) | ||
{ | ||
var control = new GuideMedicalDamage(groupProto, -damage); // Negative damage means positive healing | ||
DamageDescriptionContainer.AddChild(control); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
FormattedMessage description = new(); | ||
description.AddText(proto?.Description ?? string.Empty); | ||
// Cannot describe food flavor or smth beause food is entirely server-side | ||
|
||
Description.SetMessage(description); | ||
} | ||
|
||
private void CalculateColors(List<(ReagentPrototype, FixedPoint2)> composition, out Color text, out Color background) | ||
{ | ||
// Background color is calculated as the weighted average of the colors of the composition. | ||
// Text color is determined based on background luminosity. | ||
float r = 0, g = 0, b = 0; | ||
FixedPoint2 weight = 0; | ||
|
||
foreach (var (proto, quantity) in composition) | ||
{ | ||
var tcolor = proto.SubstanceColor; | ||
var prevalence = | ||
quantity <= 0 ? 0f | ||
: weight == 0f ? 1f | ||
: (quantity / (weight + quantity)).Float(); | ||
|
||
r = r * (1 - prevalence) + tcolor.R * prevalence; | ||
g = g * (1 - prevalence) + tcolor.G * prevalence; | ||
b = b * (1 - prevalence) + tcolor.B * prevalence; | ||
|
||
if (quantity > 0) | ||
weight += quantity; | ||
} | ||
|
||
// Copied from GuideReagentEmbed which was probably copied from stackoverflow. This is the formula for color luminosity. | ||
var lum = 0.2126f * r + 0.7152f * g + 0.0722f; | ||
|
||
background = new Color(r, g, b); | ||
text = lum > 0.5f ? Color.Black : Color.White; | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
Content.Client/_NF/Guidebook/Controls/GuideMedicalGroupEmbed.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<BoxContainer xmlns="https://spacestation14.io" | ||
Orientation="Vertical"> | ||
<BoxContainer Name="GroupContainer" Orientation="Vertical"/> | ||
</BoxContainer> |
Oops, something went wrong.