Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Erisfiregamer1 committed Mar 2, 2025
2 parents 8d67d6f + ffaf99c commit 091a412
Show file tree
Hide file tree
Showing 816 changed files with 220,088 additions and 185,874 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Content.Shared.Botany.PlantAnalyzer;
using JetBrains.Annotations;
using Robust.Client.UserInterface;

namespace Content.Client.Botany.PlantAnalyzer;

[UsedImplicitly]
public sealed class PlantAnalyzerBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private PlantAnalyzerWindow? _window;

public PlantAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}

protected override void Open()
{
base.Open();
_window = this.CreateWindow<PlantAnalyzerWindow>();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
_window.Print.OnPressed += _ => Print();
}

protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
if (_window is null
|| message is not PlantAnalyzerScannedUserMessage cast)
return;

_window.Populate(cast);
}

private void Print()
{
SendMessage(new PlantAnalyzerPrintMessage());
if (_window is null)
return;

_window.Print.Disabled = true;
}
}
121 changes: 121 additions & 0 deletions Content.Client/Botany/PlantAnalyzer/PlantAnalyzerWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinWidth="320"
MaxWidth="320">
<ScrollContainer
Margin="5 5 5 5"
ReturnMeasure="True"
VerticalExpand="True"
HorizontalExpand="False">
<BoxContainer
Name="RootContainer"
VerticalExpand="True"
Orientation="Vertical">
<BoxContainer
Name="DataContainer"
Margin="0 0 0 5"
Orientation="Vertical">
<BoxContainer Orientation="Horizontal" Margin="0 0 0 5">
<SpriteView OverrideDirection="South" Scale="2 2" Name="SpriteView" Access="Public" SetSize="64 64" />
<TextureRect Name="NoDataIcon" Access="Public" SetSize="64 64" Visible="false" Stretch="KeepAspectCentered" TexturePath="/Textures/Interface/Misc/health_analyzer_out_of_range.png"/>
<BoxContainer Margin="5 0 0 0" Orientation="Vertical" VerticalAlignment="Top">
<RichTextLabel Name="SeedLabel" SetWidth="150"
Text="{Loc 'generic-unknown'}"/>
<Label Name="ContainerLabel" VerticalAlignment="Top" StyleClasses="LabelSubText"
Text="{Loc 'generic-unknown'}"/>
</BoxContainer>
<Label Margin="0 0 5 0" HorizontalExpand="True" HorizontalAlignment="Right" VerticalExpand="True"
VerticalAlignment="Top" Name="ScanModeLabel"
Text="{Loc 'health-analyzer-window-entity-unknown-text'}" />
</BoxContainer>
<PanelContainer StyleClasses="LowDivider" />
<BoxContainer Name="PlantDataTags" Margin="5 5 0 0" Orientation="Horizontal" Visible="false">
<RichTextLabel Margin="0 0 8 0" Name="Alive" Visible="false" Text="{Loc 'plant-analyzer-component-alive'}" />
<RichTextLabel Margin="0 0 8 0" Name="Dead" Visible="false" Text="{Loc 'plant-analyzer-component-dead'}" />
<RichTextLabel Margin="0 0 8 0" Name="Unviable" Visible="false" Text="{Loc 'plant-analyzer-component-unviable'}" />
<RichTextLabel Margin="0 0 8 0" Name="Kudzu" Visible="false" Text="{Loc 'plant-analyzer-component-kudzu'}" />
<RichTextLabel Margin="0 0 8 0" Name="Mutating" Visible="false" Text="{Loc 'plant-analyzer-component-mutating'}" />
</BoxContainer>
<GridContainer Name="PlantDataGrid" Margin="0 0 0 5" Columns="6" Visible="false">
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-health'}" />
<Label SetWidth="8" />
<Label HorizontalAlignment="Right" Name="Health" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Name="Endurance" />
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-age'}" />
<Label SetWidth="8" />
<Label HorizontalAlignment="Right" Name="Age" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Name="Lifespan" />
</GridContainer>
<PanelContainer Name="PlantDataDivider" Visible="false" StyleClasses="LowDivider" />
<GridContainer Name="ContainerGrid" Margin="0 5" Columns="8" Visible="false">
<!-- Max values from `PlantHolderSystem.CheckLevelSanity` -->
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-water'}" />
<Label SetWidth="8" />
<Label FontColorOverride="cyan" HorizontalAlignment="Right" Name="WaterLevelLabel" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Text="100.00" />
<Label Margin="12 0 0 0" Name="GtFieldIfTolerances1" />
<Label HorizontalAlignment="Right" Name="WaterConsumptionLabel" />
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-nutrition'}" />
<Label SetWidth="8" />
<Label FontColorOverride="orange" HorizontalAlignment="Right" Name="NutritionLevelLabel" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Text="100.00" />
<Label Margin="12 0 0 0" Name="GtFieldIfTolerances2" />
<Label HorizontalAlignment="Right" Name="NutritionConsumptionLabel" />
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-toxins'}" />
<Label SetWidth="8" />
<Label FontColorOverride="yellowgreen" HorizontalAlignment="Right" Name="ToxinsLabel" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Text="100.00" />
<Label Margin="12 0 0 0" Name="LtFieldIfTolerances1" />
<Label HorizontalAlignment="Right" Name="ToxinsResistanceLabel" />
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-pests'}" />
<Label SetWidth="8" />
<Label FontColorOverride="magenta" HorizontalAlignment="Right" Name="PestLevelLabel" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Text="10.00" />
<Label Margin="12 0 0 0" Name="LtFieldIfTolerances2" />
<Label HorizontalAlignment="Right" Name="PestResistanceLabel" />
<Label Text=" · " />
<Label Text="{Loc 'plant-analyzer-component-weeds'}" />
<Label SetWidth="8" />
<Label FontColorOverride="red" HorizontalAlignment="Right" Name="WeedLevelLabel" />
<Label Text=" / " />
<Label HorizontalAlignment="Right" Text="10.00" />
<Label Margin="12 0 0 0" Name="LtFieldIfTolerances3" />
<Label HorizontalAlignment="Right" Name="WeedResistanceLabel" />
</GridContainer>
<PanelContainer Name="ContainerDivider" Visible="false" StyleClasses="LowDivider" />
<BoxContainer Name="ChemicalsInWaterBox" Visible="false" Orientation="Horizontal" Margin="5">
<RichTextLabel Name="ChemicalsInWaterLabel" SetWidth="290" />
</BoxContainer>
<PanelContainer Name="ChemicalsInWaterDivider" Visible="false" StyleClasses="LowDivider" />
<BoxContainer Name="EnvironmentBox" Visible="false" Orientation="Horizontal" Margin="5">
<RichTextLabel Name="EnvironmentLabel" SetWidth="290" />
</BoxContainer>
<PanelContainer Name="EnvironmentDivider" Visible="false" StyleClasses="LowDivider" />
<BoxContainer Name="ProduceBox" Visible="false" Orientation="Horizontal" Margin="5">
<RichTextLabel Name="ProduceLabel" SetWidth="290" />
</BoxContainer>
<PanelContainer Name="ProduceDivider" Visible="false" StyleClasses="LowDivider" />
<Button Name="Print"
TextAlign="Center"
HorizontalExpand="True"
Access="Public"
Disabled="True"
Margin="0 5 0 0"
Text="{Loc 'plant-analyzer-print'}" />
</BoxContainer>
</BoxContainer>
</ScrollContainer>
</controls:FancyWindow>
207 changes: 207 additions & 0 deletions Content.Client/Botany/PlantAnalyzer/PlantAnalyzerWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
using System.Linq;
using Content.Client.UserInterface.Controls;
using Content.Shared.Botany.PlantAnalyzer;
using Content.Shared.IdentityManagement;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;

namespace Content.Client.Botany.PlantAnalyzer;

[GenerateTypedNameReferences]
public sealed partial class PlantAnalyzerWindow : FancyWindow
{
private readonly IEntityManager _entityManager;
private readonly IPrototypeManager _prototypeManager;
private readonly IGameTiming _gameTiming;

public PlantAnalyzerWindow()
{
RobustXamlLoader.Load(this);

var dependencies = IoCManager.Instance!;
_entityManager = dependencies.Resolve<IEntityManager>();
_prototypeManager = dependencies.Resolve<IPrototypeManager>();
_gameTiming = dependencies.Resolve<IGameTiming>();
}

public void Populate(PlantAnalyzerScannedUserMessage msg)
{
Print.Disabled = !msg.ScanMode.GetValueOrDefault(false)
|| msg.PrintReadyAt.GetValueOrDefault(TimeSpan.MaxValue) > _gameTiming.CurTime
|| msg.PlantData is null;

if (!_entityManager.TryGetEntity(msg.TargetEntity, out var target) || target is null)
return;

// Section 1: Icon and basic information.
SpriteView.SetEntity(target.Value);
SpriteView.Visible = msg.ScanMode.HasValue && msg.ScanMode.Value;
NoDataIcon.Visible = !SpriteView.Visible;

ScanModeLabel.Text = msg.ScanMode.HasValue
? msg.ScanMode.Value
? Loc.GetString("plant-analyzer-window-scan-mode-active")
: Loc.GetString("plant-analyzer-window-scan-mode-inactive")
: Loc.GetString("plant-analyzer-window-entity-unknown-text");
ScanModeLabel.FontColorOverride = msg.ScanMode.HasValue && msg.ScanMode.Value ? Color.Green : Color.Red;

SeedLabel.Text = msg.PlantData == null
? Loc.GetString("plant-analyzer-component-no-seed")
: Loc.GetString(msg.PlantData.SeedDisplayName);

ContainerLabel.Text = _entityManager.HasComponent<MetaDataComponent>(target.Value)
? Identity.Name(target.Value, _entityManager)
: Loc.GetString("generic-unknown");

// Section 2: Information regarding the plant.
if (msg.PlantData is not null)
{
Health.Text = msg.PlantData.Health.ToString("0.00");
Endurance.Text = msg.PlantData.Endurance.ToString("0.00");
Age.Text = msg.PlantData.Age.ToString("0.00");
Lifespan.Text = msg.PlantData.Lifespan.ToString("0.00");

// These mostly exists to prevent shifting of the text.
Dead.Visible = msg.PlantData.Dead;
Alive.Visible = !Dead.Visible;

Unviable.Visible = !msg.PlantData.Viable;
Mutating.Visible = msg.PlantData.Mutating;
Kudzu.Visible = msg.PlantData.Kudzu;

PlantDataGrid.Visible = true;
}
else
{
PlantDataGrid.Visible = false;
}
PlantDataTags.Visible = PlantDataGrid.Visible;
PlantDataDivider.Visible = PlantDataGrid.Visible;

// Section 3: Input
if (msg.TrayData is not null)
{
WaterLevelLabel.Text = msg.TrayData.WaterLevel.ToString("0.00");
NutritionLevelLabel.Text = msg.TrayData.NutritionLevel.ToString("0.00");
ToxinsLabel.Text = msg.TrayData.Toxins.ToString("0.00");
PestLevelLabel.Text = msg.TrayData.PestLevel.ToString("0.00");
WeedLevelLabel.Text = msg.TrayData.WeedLevel.ToString("0.00");

// Section 3.1: Tolerances part 1.
if (msg.TolerancesData is not null)
{
GtFieldIfTolerances1.Text = ">";
LtFieldIfTolerances1.Text = "<";

WaterConsumptionLabel.Text = msg.TolerancesData.WaterConsumption.ToString("0.00");
NutritionConsumptionLabel.Text = msg.TolerancesData.NutrientConsumption.ToString("0.00");
// Technically would be "x + epsilon" for toxin and pest.
// But it makes no difference here since I only display two digits.
ToxinsResistanceLabel.Text = msg.TolerancesData.ToxinsTolerance.ToString("0.00");
PestResistanceLabel.Text = msg.TolerancesData.PestTolerance.ToString("0.00");
WeedResistanceLabel.Text = msg.TolerancesData.WeedTolerance.ToString("0.00");
}
else
{
GtFieldIfTolerances1.Text = "";
LtFieldIfTolerances1.Text = "";

WaterConsumptionLabel.Text = "";
NutritionConsumptionLabel.Text = "";
ToxinsResistanceLabel.Text = "";
PestResistanceLabel.Text = "";
WeedResistanceLabel.Text = "";
}
GtFieldIfTolerances2.Text = GtFieldIfTolerances1.Text;
LtFieldIfTolerances2.Text = LtFieldIfTolerances1.Text;
LtFieldIfTolerances3.Text = LtFieldIfTolerances1.Text;

ContainerGrid.Visible = true;
}
else
{
ContainerGrid.Visible = false;
}
ContainerDivider.Visible = ContainerGrid.Visible;


// Section 3.5: They are putting chemicals in the water!
if (msg.TrayData?.Chemicals != null)
{
var count = msg.TrayData.Chemicals.Count;
var holder = ContainerLabel.Text;
var chemicals = PlantAnalyzerLocalizationHelper.ChemicalsToLocalizedStrings(msg.TrayData.Chemicals, _prototypeManager);
if (count == 0)
ChemicalsInWaterLabel.Text = Loc.GetString("plant-analyzer-soil-empty", ("holder", holder));
else
ChemicalsInWaterLabel.Text = Loc.GetString("plant-analyzer-soil", ("count", count), ("holder", holder), ("chemicals", chemicals));

ChemicalsInWaterBox.Visible = true;
}
else
{
ChemicalsInWaterBox.Visible = false;
}
ChemicalsInWaterDivider.Visible = ChemicalsInWaterBox.Visible;

// Section 4: Tolerances part 2.
if (msg.TolerancesData is not null)
{
(string, string)[] parameters = [
("seedName", SeedLabel.Text),
("gases", PlantAnalyzerLocalizationHelper.GasesToLocalizedStrings(msg.TolerancesData.ConsumeGasses, _prototypeManager)),
("kpa", msg.TolerancesData.IdealPressure.ToString("0.00")),
("kpaTolerance", msg.TolerancesData.PressureTolerance.ToString("0.00")),
("temp", msg.TolerancesData.IdealHeat.ToString("0.00")),
("tempTolerance", msg.TolerancesData.HeatTolerance.ToString("0.00")),
("lightLevel", msg.TolerancesData.IdealLight.ToString("0.00")),
("lightTolerance", msg.TolerancesData.LightTolerance.ToString("0.00"))
];
EnvironmentLabel.Text = msg.TolerancesData.ConsumeGasses.Count == 0
? msg.TolerancesData.IdealHeat - msg.TolerancesData.HeatTolerance <= 0f && msg.TolerancesData.IdealPressure - msg.TolerancesData.PressureTolerance <= 0f
? Loc.GetString("plant-analyzer-component-environment-void", [.. parameters])
: Loc.GetString("plant-analyzer-component-environment", [.. parameters])
: Loc.GetString("plant-analyzer-component-environment-gas", [.. parameters]);

EnvironmentBox.Visible = true;
}
else
{
EnvironmentBox.Visible = false;
}
EnvironmentDivider.Visible = EnvironmentBox.Visible;

// Section 5: Output
if (msg.ProduceData is not null)
{
var gases = PlantAnalyzerLocalizationHelper.GasesToLocalizedStrings(msg.ProduceData.ExudeGasses, _prototypeManager);
var (produce, producePlural) = PlantAnalyzerLocalizationHelper.ProduceToLocalizedStrings(msg.ProduceData.Produce, _prototypeManager);
var chemicals = PlantAnalyzerLocalizationHelper.ChemicalsToLocalizedStrings(msg.ProduceData.Chemicals, _prototypeManager);

(string, object)[] parameters = [
("yield", msg.ProduceData.Yield),
("gasCount", msg.ProduceData.ExudeGasses.Count),
("gases", gases),
("potency", Loc.GetString(msg.ProduceData.Potency)),
("seedless", msg.ProduceData.Seedless),
("firstProduce", msg.ProduceData.Produce.FirstOrDefault() ?? ""),
("produce", produce),
("producePlural", producePlural),
("chemCount", msg.ProduceData.Chemicals.Count),
("chemicals", chemicals),
("nothing", "")
];

ProduceLabel.Text = Loc.GetString("plant-analyzer-output", [.. parameters]);
ProduceBox.Visible = true;
}
else
{
ProduceBox.Visible = false;
}
ProduceDivider.Visible = ProduceBox.Visible;
}
}
Loading

0 comments on commit 091a412

Please sign in to comment.