Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chemprentice #2646

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7310a80
Barely functional mini chemmaster
Temoffy Jan 2, 2025
72c9929
Merge branch 'chemprentice' of https://github.com/Temoffy/frontier-st…
Temoffy Jan 2, 2025
5dacf8e
temp commit, need to reset IDE
Temoffy Jan 2, 2025
baebb59
completed namespace swap
Temoffy Jan 2, 2025
75f144a
unduplicate duplicated code baby step 1
Temoffy Jan 2, 2025
30f8504
Undupicating code... done maybe?
Temoffy Jan 2, 2025
b31b338
strip pill, bottle, and output code. Limit volume and allow reactions…
Temoffy Jan 3, 2025
e91f7cb
sprite added, and I fixed the currently unused loaded chemmaster spri…
Temoffy Jan 4, 2025
65b4816
Final touches making it player-accessible? We'll find out.
Temoffy Jan 4, 2025
5a417aa
Merge branch 'master' into chemprentice
Temoffy Jan 4, 2025
8cd9d70
relax liscence
Temoffy Jan 4, 2025
bae4436
Merge branch 'chemprentice' of https://github.com/Temoffy/frontier-st…
Temoffy Jan 4, 2025
ae6d1f4
woe, horizontal line height, and woe
Temoffy Jan 4, 2025
8352f6e
bottles fit in (thank Dusty not me)
Temoffy Jan 4, 2025
843a6e8
Merge branch 'master' into chemprentice
Temoffy Jan 6, 2025
6c18746
spill on destroyed
Temoffy Jan 9, 2025
3614c9a
Merge branch 'chemprentice' of https://github.com/Temoffy/frontier-st…
Temoffy Jan 9, 2025
e128682
clean up, clean up, everybody everywhere!
Temoffy Jan 10, 2025
850fb34
unclean up unclean up, nobody, nowhere!
Temoffy Jan 12, 2025
62d0829
Merge branch 'chemprentice' of https://github.com/Temoffy/frontier-st…
Temoffy Jan 12, 2025
b2d2512
Revert "clean up, clean up, everybody everywhere!"
Temoffy Jan 12, 2025
9400677
discard args
Temoffy Jan 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Content.Client/_NF/Chemistry/UI/ChemPrenticeBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Content.Client.Chemistry.UI;
using Content.Shared._NF.Chemistry;
using Content.Shared.Chemistry;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;

namespace Content.Client._NF.Chemistry.UI
{
/// <summary>
/// Initializes a <see cref="ChemPrenticeWindow"/> and updates it when new server messages are received.
/// </summary>
[UsedImplicitly]
public sealed class ChemPrenticeBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private ChemPrenticeWindow? _window;

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

/// <summary>
/// Called each time a chem master UI instance is opened. Generates the window and fills it with
/// relevant info. Sets the actions for static buttons.
/// </summary>
protected override void Open()
{
base.Open();

// Setup window layout/elements
_window = this.CreateWindow<ChemPrenticeWindow>();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;

// Setup static button actions.
_window.InputEjectButton.OnPressed += _ => SendMessage(
new ItemSlotButtonPressedEvent(SharedChemMaster.InputSlotName));
_window.BufferTransferButton.OnPressed += _ => SendMessage(
new ChemMasterSetModeMessage(ChemMasterMode.Transfer));
_window.BufferDiscardButton.OnPressed += _ => SendMessage(
new ChemMasterSetModeMessage(ChemMasterMode.Discard));

_window.OnReagentButtonPressed += (_, button) => SendMessage(new ChemMasterReagentAmountButtonMessage(button.Id, button.Amount, button.IsBuffer));
}

/// <summary>
/// Update the ui each time new state data is sent from the server.
/// </summary>
/// <param name="state">
/// Data of the <see cref="SharedReagentDispenserComponent"/> that this ui represents.
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
/// Sent from the server.
/// </param>
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

var castState = (ChemPrenticeBoundUserInterfaceState)state;

_window?.UpdateState(castState); // Update window state
}
}
}
53 changes: 53 additions & 0 deletions Content.Client/_NF/Chemistry/UI/ChemPrenticeWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
MinSize="512 256"
Title="{Loc 'chem-master-bound-user-interface-title'}">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="5" SeparationOverride="10">
<!-- Input container info -->
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'chem-master-window-container-label'}" />
<Control HorizontalExpand="True" />
<Button MinSize="80 0" Name="InputEjectButton" Access="Public" Text="{Loc 'chem-master-window-eject-button'}" />
</BoxContainer>

<PanelContainer VerticalExpand="True" MinSize="0 100">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1E1B" />
</PanelContainer.PanelOverride>

<ScrollContainer HorizontalExpand="True" MinSize="0 100">
<!-- Initially empty, when server sends state data this will have container contents and fill volume.-->
<BoxContainer Name="InputContainerInfo" Orientation="Vertical" Margin="4" HorizontalExpand="True">
<Label Text="{Loc 'chem-master-window-no-container-loaded-text'}" />
</BoxContainer>
</ScrollContainer>
</PanelContainer>

<!-- Padding -->
<Control MinSize="0 10" />

<!-- Buffer -->
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'chem-master-window-buffer-text'}" />
<Control HorizontalExpand="True" />
<Button MinSize="80 0" Name="BufferTransferButton" Access="Public" Text="{Loc 'chem-master-window-transfer-button'}" ToggleMode="True" StyleClasses="OpenRight" />
<Button MinSize="80 0" Name="BufferDiscardButton" Access="Public" Text="{Loc 'chem-master-window-discard-button'}" ToggleMode="True" StyleClasses="OpenLeft" />
</BoxContainer>

<!-- Buffer info -->
<PanelContainer VerticalExpand="True" MinSize="0 150">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1E1B" />
</PanelContainer.PanelOverride>

<ScrollContainer HorizontalExpand="True" MinSize="0 150">
<!-- Buffer reagent list -->
<BoxContainer Name="BufferInfo" Orientation="Vertical" Margin="4" HorizontalExpand="True">
<Label Text="{Loc 'chem-master-window-buffer-empty-text'}" />
</BoxContainer>
</ScrollContainer>
</PanelContainer>
</BoxContainer>
</controls:FancyWindow>
247 changes: 247 additions & 0 deletions Content.Client/_NF/Chemistry/UI/ChemPrenticeWindow.xaml.cs
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Shared.Chemistry;
using Content.Shared._NF.Chemistry;
using Content.Shared.Chemistry.Reagent;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
using System.Linq;
using System.Numerics;
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
using Content.Shared.FixedPoint;
using static Robust.Client.UserInterface.Controls.BoxContainer;
using Content.Client.Chemistry.UI;
using Content.Client.Info;
Temoffy marked this conversation as resolved.
Show resolved Hide resolved

namespace Content.Client._NF.Chemistry.UI
{
/// <summary>
/// Client-side UI used to control a <see cref="SharedChemPrenticeComponent"/>
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class ChemPrenticeWindow : FancyWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
public event Action<BaseButton.ButtonEventArgs, ReagentButton>? OnReagentButtonPressed;

/// <summary>
/// Create and initialize the chem master UI client-side. Creates the basic layout,
/// actual data isn't filled in until the server sends data about the chem master.
/// </summary>
public ChemPrenticeWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
}

private ReagentButton MakeReagentButton(string text, ChemMasterReagentAmount amount, ReagentId id, bool isBuffer, string styleClass)
{
var button = new ReagentButton(text, amount, id, isBuffer, styleClass);
button.OnPressed += args
=> OnReagentButtonPressed?.Invoke(args, button);
return button;
}

/// <summary>
/// Update the UI state when new state data is received from the server.
/// </summary>
/// <param name="state">State data sent by the server.</param>
public void UpdateState(BoundUserInterfaceState state)
{
var castState = (ChemPrenticeBoundUserInterfaceState)state;
UpdatePanelInfo(castState);

//BufferCurrentVolume.Text = $" {castState.BufferCurrentVolume?.Int() ?? 0}u";

InputEjectButton.Disabled = castState.InputContainerInfo is null;

}

/// <summary>
/// Generate a product label based on reagents in the buffer.
/// </summary>
/// <param name="state">State data sent by the server.</param>
private string GenerateLabel(ChemPrenticeBoundUserInterfaceState state)
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
{
if (state.BufferCurrentVolume == 0)
return "";

var reagent = state.BufferReagents.OrderBy(r => r.Quantity).First().Reagent;
_prototypeManager.TryIndex(reagent.Prototype, out ReagentPrototype? proto);
return proto?.LocalizedName ?? "";
}

/// <summary>
/// Update the container, buffer, and packaging panels.
/// </summary>
/// <param name="state">State data for the dispenser.</param>
private void UpdatePanelInfo(ChemPrenticeBoundUserInterfaceState state)
{
BufferTransferButton.Pressed = state.Mode == ChemMasterMode.Transfer;
BufferDiscardButton.Pressed = state.Mode == ChemMasterMode.Discard;

BuildContainerUI(InputContainerInfo, state.InputContainerInfo, true);

BufferInfo.Children.Clear();

if (!state.BufferReagents.Any())
{
BufferInfo.Children.Add(new Label { Text = Loc.GetString("chem-master-window-buffer-empty-text") });

return;
}

var bufferHBox = new BoxContainer
{
Orientation = LayoutOrientation.Horizontal
};
BufferInfo.AddChild(bufferHBox);

var bufferLabel = new Label { Text = $"{Loc.GetString("chem-master-window-buffer-label")} " };
bufferHBox.AddChild(bufferLabel);
var bufferVol = new Label
{
Text = $"{state.BufferCurrentVolume}/{state.BufferMaxVolume}",
StyleClasses = { StyleNano.StyleClassLabelSecondaryColor }
};
bufferHBox.AddChild(bufferVol);

foreach (var (reagent, quantity) in state.BufferReagents.OrderBy(x => x.Reagent.Prototype)) // Frontier: add OrderBy
{
// Try to get the prototype for the given reagent. This gives us its name.
_prototypeManager.TryIndex(reagent.Prototype, out ReagentPrototype? proto);
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");

if (proto != null)
{
BufferInfo.Children.Add(new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
Children =
{
new Label {Text = $"{name}: "},
new Label
{
Text = $"{quantity}u",
StyleClasses = {StyleNano.StyleClassLabelSecondaryColor}
},

// Padding
new Control {HorizontalExpand = true},

MakeReagentButton("1", ChemMasterReagentAmount.U1, reagent, true, StyleBase.ButtonOpenRight),
MakeReagentButton("5", ChemMasterReagentAmount.U5, reagent, true, StyleBase.ButtonOpenBoth),
MakeReagentButton("10", ChemMasterReagentAmount.U10, reagent, true, StyleBase.ButtonOpenBoth),
MakeReagentButton("25", ChemMasterReagentAmount.U25, reagent, true, StyleBase.ButtonOpenBoth),
MakeReagentButton("50", ChemMasterReagentAmount.U50, reagent, true, StyleBase.ButtonOpenBoth),
MakeReagentButton("100", ChemMasterReagentAmount.U100, reagent, true, StyleBase.ButtonOpenBoth),
MakeReagentButton(Loc.GetString("chem-master-window-buffer-all-amount"), ChemMasterReagentAmount.All, reagent, true, StyleBase.ButtonOpenLeft),
}
});
}
}
}
Comment on lines +78 to +147
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like at least some of this could be defined in xaml instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it can it's beyond my knowledge, and any changes here should probably be mirrored to the chemmaster xaml


private void BuildContainerUI(Control control, ContainerInfo? info, bool addReagentButtons)
{
control.Children.Clear();

if (info is null)
{
control.Children.Add(new Label
{
Text = Loc.GetString("chem-master-window-no-container-loaded-text")
});
}
else
{
// Name of the container and its fill status (Ex: 44/100u)
control.Children.Add(new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
Children =
{
new Label {Text = $"{info.DisplayName}: "},
new Label
{
Text = $"{info.CurrentVolume}/{info.MaxVolume}",
StyleClasses = {StyleNano.StyleClassLabelSecondaryColor}
}
}
});

IEnumerable<(string Name, ReagentId Id, FixedPoint2 Quantity)> contents;

if (info.Entities != null)
{
contents = info.Entities.Select(x => (x.Id, default(ReagentId), x.Quantity));
}
else if (info.Reagents != null)
{
contents = info.Reagents.Select(x =>
{
_prototypeManager.TryIndex(x.Reagent.Prototype, out ReagentPrototype? proto);
var name = proto?.LocalizedName
?? Loc.GetString("chem-master-window-unknown-reagent-text");

return (name, Id: x.Reagent, x.Quantity);
})
.OrderBy(r => r.Item1);
}
else
{
return;
}


foreach (var (name, id, quantity) in contents)
{
var inner = new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
Children =
{
new Label { Text = $"{name}: " },
new Label
{
Text = $"{quantity}u",
StyleClasses = { StyleNano.StyleClassLabelSecondaryColor },
}
}
};

if (addReagentButtons)
{
var cs = inner.Children;

// Padding
cs.Add(new Control { HorizontalExpand = true });

cs.Add(MakeReagentButton(
"1", ChemMasterReagentAmount.U1, id, false, StyleBase.ButtonOpenRight));
cs.Add(MakeReagentButton(
"5", ChemMasterReagentAmount.U5, id, false, StyleBase.ButtonOpenBoth));
cs.Add(MakeReagentButton(
"10", ChemMasterReagentAmount.U10, id, false, StyleBase.ButtonOpenBoth));
cs.Add(MakeReagentButton(
"25", ChemMasterReagentAmount.U25, id, false, StyleBase.ButtonOpenBoth));
cs.Add(MakeReagentButton(
"50", ChemMasterReagentAmount.U50, id, false, StyleBase.ButtonOpenBoth));
cs.Add(MakeReagentButton(
"100", ChemMasterReagentAmount.U100, id, false, StyleBase.ButtonOpenBoth));
cs.Add(MakeReagentButton(
Loc.GetString("chem-master-window-buffer-all-amount"),
ChemMasterReagentAmount.All, id, false, StyleBase.ButtonOpenLeft));
}

control.Children.Add(inner);
}

}
}
}
}
2 changes: 2 additions & 0 deletions Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public sealed class ChemMasterSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; //Frontier
Temoffy marked this conversation as resolved.
Show resolved Hide resolved
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
Expand Down Expand Up @@ -70,6 +71,7 @@ private void UpdateUiState(Entity<ChemMasterComponent> ent, bool updateLabel = f
if (!_solutionContainerSystem.TryGetSolution(owner, SharedChemMaster.BufferSolutionName, out _, out var bufferSolution))
return;
var inputContainer = _itemSlotsSystem.GetItemOrNull(owner, SharedChemMaster.InputSlotName);
_appearanceSystem.SetData(owner, ChemMasterVisualState.BeakerInserted, inputContainer.HasValue); //Frontier
var outputContainer = _itemSlotsSystem.GetItemOrNull(owner, SharedChemMaster.OutputSlotName);

var bufferReagents = bufferSolution.Contents;
Expand Down
Loading
Loading