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(); _prototypeManager = dependencies.Resolve(); _gameTiming = dependencies.Resolve(); } 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(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; } }