* init * мать масштаба тарабанил * fix * upd * upd * upd * upd * upd * console spam fix * hohohohohohohooooonkeeeeeeeeeeeeeerrrrrrrrrrrsssssssss........ * fix * fix * upd * upd * some fixes * fix * upd * upd translation for steal obj * teg translate * upd * fix locale + add advertisements * translate configurator * Fully translate * upd * Я манал это переводить, позже переведу * upd en-US * fix Linter * upd * fix * upd * fix * fix * fix * Возврат ПНТ * remove agent non silent equipment * add acid to uplink * carrySystem new popups * fix * fix * fix disease locale * add Disease Guide * upd locale * upd * Revert "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 4130d241fc47fb80924c0dd3b9c9a2db85af8a25, reversing changes made to 30abf7341ecce404f61f64e2000ad327964fcb00. * Revert "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 4e5a50d21c29be8482f31e49db253b1ed17a0ae4, reversing changes made to 449cd7bfd50f29eb653e68ba60e3f0b9310f0443. * Revert "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit a4679665ef441d4b63a92dc3c4e217e2cdedbc16, reversing changes made to a80ef96cfbbc3cc737045e41a2f063a0910bf1ce. * Revert "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 94f585756bb27d10a1be7fab1f340d79b7c0a213, reversing changes made to 906d18a3f66eaed73f3a894d70971872904fad4e. * Revert "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit d0a7c6436ba5c175b0e00d69f495ba51f9aac645, reversing changes made to e7933332274b336af1fc2a960264bc546c95d208. # Conflicts: # Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml # Resources/Prototypes/Roles/Jobs/departments.yml * fix * upd * upd * Reapply "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 042a3f112bbc32a622108475ac28081eb0bbbf9f. # Conflicts: # Content.Server/Dragon/DragonRiftSystem.cs # Content.Server/GameTicking/GameTicker.Spawning.cs # Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs # Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs # Content.Server/Spawners/EntitySystems/ContainerSpawnPointSystem.cs # Content.Server/Zombies/ZombieSystem.cs # Content.Server/_Sunrise/NPCSleep/NPCSleepSystem.cs # Resources/Changelog/Changelog.yml # Resources/Locale/en-US/_strings/store/uplink-catalog.ftl # Resources/Prototypes/Catalog/VendingMachines/Inventories/secdrobe.yml # Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml # Resources/Prototypes/Entities/Clothing/Head/helmets.yml # Resources/Prototypes/Entities/Mobs/Player/silicon.yml # Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml # Resources/Prototypes/Entities/Stations/base.yml # Resources/Prototypes/Loadouts/Jobs/Security/security_officer.yml # Resources/Prototypes/Loadouts/loadout_groups.yml # Resources/Prototypes/Maps/box.yml # Resources/Prototypes/Maps/core.yml # Resources/Prototypes/Maps/fland.yml # Resources/Prototypes/Maps/marathon.yml # Resources/Prototypes/Maps/meta.yml # Resources/Prototypes/Maps/packed.yml # Resources/Prototypes/Roles/Jobs/departments.yml # Resources/Prototypes/Store/categories.yml # Resources/ServerInfo/Guidebook/Engineering/PortableGenerator.xml # Resources/ServerInfo/Guidebook/Security/Defusal.xml # Resources/ServerInfo/Guidebook/Security/Forensics.xml # Resources/migration.yml * Reapply "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 2860e1d217a71be0c29684e020b2278c3f08685f. # Conflicts: # Resources/Changelog/Changelog.yml * Reapply "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 0dc7ea17e23d844ce93118db7812b844e36dda4f. # Conflicts: # Resources/Changelog/Changelog.yml # Resources/Prototypes/Hydroponics/randomMutations.yml * Reapply "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 439926b3c60e95cc2e701d84a032b17471a7c18e. * Reapply "Merge branch 'master' of https://github.com/space-wizards/space-station-14 into misc" This reverts commit 14160ab99909bf6b6f996f415d9dcfd5d4addbba. # Conflicts: # Resources/Changelog/Changelog.yml * fix * upd * upd uplink * upd * fix linter
362 lines
14 KiB
C#
362 lines
14 KiB
C#
using Content.Shared.Administration;
|
|
using Content.Shared.Chemistry.Components;
|
|
using Content.Shared.Chemistry.Reagent;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.Console;
|
|
using Robust.Client.Timing;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.CustomControls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Client.Administration.UI.ManageSolutions
|
|
{
|
|
/// <summary>
|
|
/// A simple window that displays solutions and their contained reagents. Allows you to edit the reagent quantities and add new reagents.
|
|
/// </summary>
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class EditSolutionsWindow : DefaultWindow
|
|
{
|
|
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
|
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
|
[Dependency] private readonly IClientGameTiming _timing = default!;
|
|
|
|
private NetEntity _target = NetEntity.Invalid;
|
|
private string? _selectedSolution;
|
|
private AddReagentWindow? _addReagentWindow;
|
|
private Dictionary<string, EntityUid>? _solutions;
|
|
private EditSolutionsEuiState? _nextState;
|
|
|
|
public EditSolutionsWindow()
|
|
{
|
|
IoCManager.InjectDependencies(this);
|
|
RobustXamlLoader.Load(this);
|
|
|
|
SolutionOption.OnItemSelected += SolutionSelected;
|
|
AddButton.OnPressed += OpenAddReagentWindow;
|
|
}
|
|
|
|
public override void Close()
|
|
{
|
|
base.Close();
|
|
_addReagentWindow?.Close();
|
|
_addReagentWindow?.Dispose();
|
|
}
|
|
|
|
public void SetTargetEntity(NetEntity target)
|
|
{
|
|
_target = target;
|
|
var uid = _entityManager.GetEntity(target);
|
|
|
|
var targetName = _entityManager.EntityExists(uid)
|
|
? _entityManager.GetComponent<MetaDataComponent>(uid).EntityName
|
|
: string.Empty;
|
|
|
|
Title = Loc.GetString("admin-solutions-window-title", ("targetName", targetName));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the capacity label and re-create the reagent list
|
|
/// </summary>
|
|
public void UpdateReagents()
|
|
{
|
|
ReagentList.DisposeAllChildren();
|
|
|
|
if (_selectedSolution == null || _solutions == null)
|
|
return;
|
|
|
|
if (!_solutions.TryGetValue(_selectedSolution, out var solutionId) ||
|
|
!_entityManager.TryGetComponent(solutionId, out SolutionComponent? solutionComp))
|
|
return;
|
|
|
|
var solution = solutionComp.Solution;
|
|
UpdateVolumeBox(solution);
|
|
UpdateThermalBox(solution);
|
|
|
|
foreach (var reagent in solution)
|
|
{
|
|
AddReagentEntry(reagent);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the entry displaying the current and maximum volume of the selected solution.
|
|
/// </summary>
|
|
/// <param name="solution">The selected solution.</param>
|
|
private void UpdateVolumeBox(Solution solution)
|
|
{
|
|
VolumeBox.DisposeAllChildren();
|
|
|
|
var volumeLabel = new Label();
|
|
volumeLabel.HorizontalExpand = true;
|
|
volumeLabel.Margin = new Thickness(0, 4);
|
|
volumeLabel.Text = Loc.GetString("admin-solutions-window-volume-label",
|
|
("currentVolume", solution.Volume),
|
|
("maxVolume", solution.MaxVolume));
|
|
|
|
var capacityBox = new BoxContainer();
|
|
capacityBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
|
capacityBox.HorizontalExpand = true;
|
|
capacityBox.Margin = new Thickness(0, 4);
|
|
|
|
var capacityLabel = new Label();
|
|
capacityLabel.HorizontalExpand = true;
|
|
capacityLabel.Margin = new Thickness(0, 1);
|
|
capacityLabel.Text = Loc.GetString("admin-solutions-window-capacity-label");
|
|
|
|
var capacitySpin = new FloatSpinBox(1, 2);
|
|
capacitySpin.HorizontalExpand = true;
|
|
capacitySpin.Margin = new Thickness(0, 1);
|
|
capacitySpin.Value = (float) solution.MaxVolume;
|
|
capacitySpin.OnValueChanged += SetCapacity;
|
|
|
|
capacityBox.AddChild(capacityLabel);
|
|
capacityBox.AddChild(capacitySpin);
|
|
|
|
VolumeBox.AddChild(volumeLabel);
|
|
VolumeBox.AddChild(capacityBox);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the entry displaying the current specific heat, heat capacity, temperature, and thermal energy
|
|
/// of the selected solution.
|
|
/// </summary>
|
|
/// <param name="solution">The selected solution.</param>
|
|
private void UpdateThermalBox(Solution solution)
|
|
{
|
|
ThermalBox.DisposeAllChildren();
|
|
var heatCap = solution.GetHeatCapacity(null);
|
|
var specificHeatLabel = new Label();
|
|
specificHeatLabel.HorizontalExpand = true;
|
|
specificHeatLabel.Margin = new Thickness(0, 1);
|
|
specificHeatLabel.Text = Loc.GetString("admin-solutions-window-specific-heat-label", ("specificHeat", heatCap.ToString("G3")));
|
|
|
|
var heatCapacityLabel = new Label();
|
|
heatCapacityLabel.HorizontalExpand = true;
|
|
heatCapacityLabel.Margin = new Thickness(0, 1);
|
|
heatCapacityLabel.Text = Loc.GetString("admin-solutions-window-heat-capacity-label", ("heatCapacity", (heatCap/solution.Volume.Float()).ToString("G3")));
|
|
|
|
// Temperature entry:
|
|
var temperatureBox = new BoxContainer();
|
|
temperatureBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
|
temperatureBox.HorizontalExpand = true;
|
|
temperatureBox.Margin = new Thickness(0, 1);
|
|
|
|
var temperatureLabel = new Label();
|
|
temperatureLabel.HorizontalExpand = true;
|
|
temperatureLabel.Margin = new Thickness(0, 1);
|
|
temperatureLabel.Text = Loc.GetString("admin-solutions-window-temperature-label");
|
|
|
|
var temperatureSpin = new FloatSpinBox(1, 2);
|
|
temperatureSpin.HorizontalExpand = true;
|
|
temperatureSpin.Margin = new Thickness(0, 1);
|
|
temperatureSpin.Value = solution.Temperature;
|
|
temperatureSpin.OnValueChanged += SetTemperature;
|
|
|
|
temperatureBox.AddChild(temperatureLabel);
|
|
temperatureBox.AddChild(temperatureSpin);
|
|
|
|
// Thermal energy entry:
|
|
var thermalEnergyBox = new BoxContainer();
|
|
thermalEnergyBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
|
thermalEnergyBox.HorizontalExpand = true;
|
|
thermalEnergyBox.Margin = new Thickness(0, 1);
|
|
|
|
var thermalEnergyLabel = new Label();
|
|
thermalEnergyLabel.HorizontalExpand = true;
|
|
thermalEnergyLabel.Margin = new Thickness(0, 1);
|
|
thermalEnergyLabel.Text = Loc.GetString("admin-solutions-window-thermal-energy-label");
|
|
|
|
var thermalEnergySpin = new FloatSpinBox(1, 2);
|
|
thermalEnergySpin.HorizontalExpand = true;
|
|
thermalEnergySpin.Margin = new Thickness(0, 1);
|
|
thermalEnergySpin.Value = solution.Temperature * heatCap;
|
|
thermalEnergySpin.OnValueChanged += SetThermalEnergy;
|
|
|
|
thermalEnergyBox.AddChild(thermalEnergyLabel);
|
|
thermalEnergyBox.AddChild(thermalEnergySpin);
|
|
|
|
ThermalBox.AddChild(specificHeatLabel);
|
|
ThermalBox.AddChild(heatCapacityLabel);
|
|
ThermalBox.AddChild(temperatureBox);
|
|
ThermalBox.AddChild(thermalEnergyBox);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a single reagent entry to the list
|
|
/// </summary>
|
|
private void AddReagentEntry(ReagentQuantity reagentQuantity)
|
|
{
|
|
var box = new BoxContainer();
|
|
var spin = new FloatSpinBox(1, 2);
|
|
|
|
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
|
var reagentPrototype = prototypeManager.Index<ReagentPrototype>(reagentQuantity.Reagent.Prototype);
|
|
|
|
spin.Value = reagentQuantity.Quantity.Float();
|
|
spin.OnValueChanged += (args) => SetReagent(args, reagentQuantity.Reagent.Prototype);
|
|
spin.HorizontalExpand = true;
|
|
|
|
box.AddChild(new Label() { Text = reagentPrototype.LocalizedName , HorizontalExpand = true});
|
|
box.AddChild(spin);
|
|
|
|
ReagentList.AddChild(box);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Execute a command to modify the reagents in the solution.
|
|
/// </summary>
|
|
private void SetReagent(FloatSpinBox.FloatSpinBoxEventArgs args, string prototype)
|
|
{
|
|
if (_solutions == null || _selectedSolution == null ||
|
|
!_solutions.TryGetValue(_selectedSolution, out var solutionId) ||
|
|
!_entityManager.TryGetComponent(solutionId, out SolutionComponent? solutionComp))
|
|
return;
|
|
|
|
var solution = solutionComp.Solution;
|
|
var current = solution.GetTotalPrototypeQuantity(prototype);
|
|
var delta = args.Value - current.Float();
|
|
|
|
if (MathF.Abs(delta) < 0.01)
|
|
return;
|
|
|
|
var command = $"addreagent {_target} {_selectedSolution} {prototype} {delta}";
|
|
_consoleHost.ExecuteCommand(command);
|
|
}
|
|
|
|
private void SetCapacity(FloatSpinBox.FloatSpinBoxEventArgs args)
|
|
{
|
|
if (_solutions == null || _selectedSolution == null)
|
|
return;
|
|
|
|
var command = $"setsolutioncapacity {_target} {_selectedSolution} {args.Value}";
|
|
_consoleHost.ExecuteCommand(command);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the temperature of the selected solution to a value.
|
|
/// </summary>
|
|
/// <param name="args">An argument struct containing the value to set the temperature to.</param>
|
|
private void SetTemperature(FloatSpinBox.FloatSpinBoxEventArgs args)
|
|
{
|
|
if (_solutions == null || _selectedSolution == null)
|
|
return;
|
|
|
|
var command = $"setsolutiontemperature {_target} {_selectedSolution} {args.Value}";
|
|
_consoleHost.ExecuteCommand(command);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the thermal energy of the selected solution to a value.
|
|
/// </summary>
|
|
/// <param name="args">An argument struct containing the value to set the thermal energy to.</param>
|
|
private void SetThermalEnergy(FloatSpinBox.FloatSpinBoxEventArgs args)
|
|
{
|
|
if (_solutions == null || _selectedSolution == null)
|
|
return;
|
|
|
|
var command = $"setsolutionthermalenergy {_target} {_selectedSolution} {args.Value}";
|
|
_consoleHost.ExecuteCommand(command);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open a new window that has options to add new reagents to the solution.
|
|
/// </summary>
|
|
private void OpenAddReagentWindow(BaseButton.ButtonEventArgs obj)
|
|
{
|
|
if (string.IsNullOrEmpty(_selectedSolution))
|
|
return;
|
|
|
|
_addReagentWindow?.Close();
|
|
_addReagentWindow?.Dispose();
|
|
|
|
_addReagentWindow = new AddReagentWindow(_target, _selectedSolution);
|
|
_addReagentWindow.OpenCentered();
|
|
}
|
|
|
|
/// <summary>
|
|
/// When a new solution is selected, set _selectedSolution and update the reagent list.
|
|
/// </summary>
|
|
private void SolutionSelected(OptionButton.ItemSelectedEventArgs args)
|
|
{
|
|
SolutionOption.SelectId(args.Id);
|
|
_selectedSolution = (string?) SolutionOption.SelectedMetadata;
|
|
_addReagentWindow?.UpdateSolution(_selectedSolution);
|
|
UpdateReagents();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the solution options.
|
|
/// </summary>
|
|
public void UpdateSolutions(List<(string, NetEntity)>? solutions)
|
|
{
|
|
SolutionOption.Clear();
|
|
|
|
if (solutions is { Count: > 0 })
|
|
{
|
|
if (_solutions is { Count: > 0 })
|
|
_solutions.Clear();
|
|
else
|
|
_solutions = new(solutions.Count);
|
|
|
|
foreach (var (name, netSolution) in solutions)
|
|
{
|
|
if (_entityManager.TryGetEntity(netSolution, out var solution))
|
|
_solutions.Add(name, solution.Value);
|
|
}
|
|
}
|
|
else
|
|
_solutions = null;
|
|
|
|
if (_solutions == null)
|
|
return;
|
|
|
|
int i = 0;
|
|
int selectedIndex = 0; // Default to the first solution if none are found.
|
|
foreach (var (name, _) in _solutions)
|
|
{
|
|
SolutionOption.AddItem(name, i);
|
|
SolutionOption.SetItemMetadata(i, name);
|
|
|
|
if (name == _selectedSolution)
|
|
selectedIndex = i;
|
|
|
|
i++;
|
|
}
|
|
|
|
if (SolutionOption.ItemCount == 0)
|
|
{
|
|
// No applicable solutions
|
|
Close();
|
|
Dispose();
|
|
return;
|
|
}
|
|
|
|
SolutionOption.Select(selectedIndex);
|
|
_selectedSolution = (string?) SolutionOption.SelectedMetadata;
|
|
}
|
|
|
|
protected override void FrameUpdate(FrameEventArgs args)
|
|
{
|
|
// TODO: THIS IS FUCKING TERRIBLE.
|
|
// Ok so the problem is that this shouldn't be via an EUI at all. Why?
|
|
// The EUI update notification comes in *before* the game state it updates from.
|
|
// So the UI doesn't update properly. Heck.
|
|
// I didn't wanna completely rewrite this thing to work properly so instead you get terrible hacks.
|
|
|
|
if (_nextState != null && _timing.LastRealTick >= _nextState.Tick)
|
|
{
|
|
SetTargetEntity(_nextState.Target);
|
|
UpdateSolutions(_nextState.Solutions);
|
|
UpdateReagents();
|
|
_nextState = null;
|
|
}
|
|
}
|
|
|
|
public void SetState(EditSolutionsEuiState state)
|
|
{
|
|
_nextState = state;
|
|
}
|
|
}
|
|
}
|