From a988edc0ea754952727bef74920e8fa35435b35c Mon Sep 17 00:00:00 2001 From: Checkraze <71046427+Cheackraze@users.noreply.github.com> Date: Wed, 5 Mar 2025 13:48:49 -0500 Subject: [PATCH 1/4] PDA bounty contracts rework (#2967) * proof of concept * WIP * Access utility, bounty contract progress * tabbed controls * minor cleanup and nullability fixes * change notifications style * allow removals * NetEntity/EntityUid conversion * More NetEntity conversion * bool bugfix * delete comments * max vessel/name/desc length, UI fiddling * consistent collection order, speso string * timeout, minor bugfix * mute notifications * different bounty notification types per collection * Hide unpopulated fields, category-specific message * No extra colon in PDA announcement * Admin logging, add/remove cleanup * admin logging, set author via Actor --------- Co-authored-by: Whatstone Co-authored-by: Whatstone <166147148+whatston3@users.noreply.github.com> --- .../BountyContracts/UI/BountyContractUi.cs | 87 ++++-- .../UI/BountyContractUiFragmentCreate.xaml | 10 +- .../UI/BountyContractUiFragmentCreate.xaml.cs | 91 ++++-- .../UI/BountyContractUiFragmentList.xaml | 6 + .../UI/BountyContractUiFragmentList.xaml.cs | 12 +- .../UI/BountyContractUiFragmentListEntry.xaml | 18 +- .../BountyContractUiFragmentListEntry.xaml.cs | 31 +- ...untyContractUiFragmentListPlaceholder.xaml | 4 + ...yContractUiFragmentListPlaceholder.xaml.cs | 9 + .../UI/BountyContractUiFragmentTabSet.xaml | 3 + .../UI/BountyContractUiFragmentTabSet.xaml.cs | 38 +++ .../_NF/Access/NFAccessUtilities.cs | 52 ++++ .../BountyContractDataComponent.cs | 16 +- .../BountyContractSystem.Ui.cs | 160 +++++----- .../BountyContracts/BountyContractSystem.cs | 277 ++++++++++++++---- Content.Shared.Database/LogType.cs | 8 + .../BountyContractCollectionPrototype.cs | 85 ++++++ .../BountyContractsCartridgeComponent.cs | 20 +- .../SharedBountyContractSystem.cs | 94 +++--- .../_NF/bounty-contracts/bounty-contracts.ftl | 26 +- .../Entities/Objects/Devices/cartridges.yml | 2 - .../_NF/SectorServices/services.yml | 5 + .../_NF/bounty_contract_collections.yml | 31 ++ 23 files changed, 832 insertions(+), 253 deletions(-) create mode 100644 Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentListPlaceholder.xaml create mode 100644 Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentListPlaceholder.xaml.cs create mode 100644 Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentTabSet.xaml create mode 100644 Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentTabSet.xaml.cs create mode 100644 Content.Server/_NF/Access/NFAccessUtilities.cs create mode 100644 Content.Shared/_NF/BountyContracts/BountyContractCollectionPrototype.cs create mode 100644 Resources/Prototypes/_NF/bounty_contract_collections.yml diff --git a/Content.Client/_NF/BountyContracts/UI/BountyContractUi.cs b/Content.Client/_NF/BountyContracts/UI/BountyContractUi.cs index 5f2c2d0fc1..5109ab8b45 100644 --- a/Content.Client/_NF/BountyContracts/UI/BountyContractUi.cs +++ b/Content.Client/_NF/BountyContracts/UI/BountyContractUi.cs @@ -1,8 +1,10 @@ +using System.Linq; using Content.Client.UserInterface.Fragments; using Content.Shared._NF.BountyContracts; +using Content.Shared.CartridgeLoader; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.UserInterface; +using Robust.Shared.Prototypes; namespace Content.Client._NF.BountyContracts.UI; @@ -11,6 +13,8 @@ public sealed partial class BountyContractUi : UIFragment { private BountyContractUiFragment? _fragment; private BoundUserInterface? _userInterface; + private ProtoId _lastCollection = "Command"; //FIXME: nasty. + private BoundUserInterfaceState? _lastState = null; public override Control GetUIFragmentRoot() { @@ -21,6 +25,7 @@ public sealed partial class BountyContractUi : UIFragment { _fragment = new BountyContractUiFragment(); _userInterface = userInterface; + _lastState = null; } @@ -30,13 +35,10 @@ public sealed partial class BountyContractUi : UIFragment return; if (state is BountyContractListUiState listState) - { ShowListState(listState); - } else if (state is BountyContractCreateUiState createState) - { ShowCreateState(createState); - } + _lastState = state; } private void UnloadPreviousState() @@ -46,9 +48,13 @@ public sealed partial class BountyContractUi : UIFragment private void ShowCreateState(BountyContractCreateUiState state) { + // If the previous state is already a create state, do not destroy our old state. + if (_lastState is BountyContractCreateUiState) + return; + UnloadPreviousState(); - var create = new BountyContractUiFragmentCreate(); + var create = new BountyContractUiFragmentCreate(state.Collection); create.OnCancelPressed += OnCancelCreatePressed; create.OnCreatePressed += OnTryCreatePressed; @@ -61,40 +67,83 @@ public sealed partial class BountyContractUi : UIFragment private void ShowListState(BountyContractListUiState state) { UnloadPreviousState(); + var tabs = new BountyContractUiFragmentTabSet(); + tabs.OnSelectCollection += OnSelectCollection; + state.Collections.Reverse(); // invert order, show latest first + foreach (var collection in state.Collections) + { + int newTabIndex = tabs.Children.Count(); + if (collection == state.Collection) + { + var list = new BountyContractUiFragmentList(); + list.OnCreateButtonPressed += OnOpenCreateUiPressed; + list.OnRefreshButtonPressed += OnRefreshListPressed; + list.OnRemoveButtonPressed += OnRemovePressed; + list.OnToggleNotificationPressed += OnToggleNotificationPressed; + list.SetContracts(state.Contracts, state.IsAllowedRemoveBounties, state.AuthorUid); + list.SetCanCreate(state.IsAllowedCreateBounties); + list.SetNotificationsEnabled(state.NotificationsEnabled); + tabs.Children.Add(list); - var list = new BountyContractUiFragmentList(); - list.OnCreateButtonPressed += OnOpenCreateUiPressed; - list.OnRefreshButtonPressed += OnRefreshListPressed; - list.OnRemoveButtonPressed += OnRemovePressed; + tabs.CurrentTab = newTabIndex; + tabs.SetTabCollection(newTabIndex, collection); + } + else + { + var placeholder = new BountyContractUiFragmentListPlaceholder(); + tabs.Children.Add(placeholder); + tabs.SetTabCollection(newTabIndex, collection); + } + } - list.SetContracts(state.Contracts, state.IsAllowedRemoveBounties); - list.SetCanCreate(state.IsAllowedCreateBounties); - - _fragment?.AddChild(list); + _fragment?.AddChild(tabs); + _lastCollection = state.Collection; } + // UI event handlers private void OnRemovePressed(BountyContract obj) { - _userInterface?.SendMessage(new BountyContractTryRemoveUiMsg(obj.ContractId)); + SendMessage(new BountyContractTryRemoveMessageEvent(obj.ContractId)); + } + + private void OnSelectCollection(ProtoId collection) + { + SendMessage(MakeCommand(BountyContractCommand.RefreshList, collection)); } private void OnRefreshListPressed() { - _userInterface?.SendMessage(new BountyContractRefreshListUiMsg()); + SendMessage(MakeCommand(BountyContractCommand.RefreshList, _lastCollection)); } private void OnOpenCreateUiPressed() { - _userInterface?.SendMessage(new BountyContractOpenCreateUiMsg()); + SendMessage(MakeCommand(BountyContractCommand.OpenCreateUi, _lastCollection)); } private void OnCancelCreatePressed() { - _userInterface?.SendMessage(new BountyContractCloseCreateUiMsg()); + SendMessage(MakeCommand(BountyContractCommand.CloseCreateUi, _lastCollection)); + } + + private void OnToggleNotificationPressed() + { + SendMessage(MakeCommand(BountyContractCommand.ToggleNotifications, _lastCollection)); } private void OnTryCreatePressed(BountyContractRequest contract) { - _userInterface?.SendMessage(new BountyContractTryCreateMsg(contract)); + SendMessage(new BountyContractTryCreateMessageEvent(contract)); + } + + // Convenience functions for message creation + private BountyContractCommandMessageEvent MakeCommand(BountyContractCommand command, ProtoId collection) + { + return new BountyContractCommandMessageEvent(command, collection); + } + + private void SendMessage(CartridgeMessageEvent msg) + { + _userInterface?.SendMessage(new CartridgeUiMessage(msg)); } } diff --git a/Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentCreate.xaml b/Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentCreate.xaml index 9427dd4199..000fb7af40 100644 --- a/Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentCreate.xaml +++ b/Content.Client/_NF/BountyContracts/UI/BountyContractUiFragmentCreate.xaml @@ -24,18 +24,18 @@