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

Add history tab to bounty console #2473

Merged
merged 7 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ protected override void UpdateState(BoundUserInterfaceState message)
if (message is not CargoBountyConsoleState state)
return;

_menu?.UpdateEntries(state.Bounties, state.UntilNextSkip);
_menu?.UpdateEntries(state.Bounties, state.History, state.UntilNextSkip);
}
}
23 changes: 23 additions & 0 deletions Content.Client/Cargo/UI/BountyHistoryEntry.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<BoxContainer xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
Margin="10 10 10 0"
HorizontalExpand="True"
Visible="True">
<PanelContainer StyleClasses="AngleRect" HorizontalExpand="True">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True">
<BoxContainer Orientation="Horizontal">
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<RichTextLabel Name="RewardLabel"/>
<RichTextLabel Name="ManifestLabel"/>
<RichTextLabel Name="NoticeLabel"/>
</BoxContainer>
<Control MinWidth="10"/>
<BoxContainer Orientation="Vertical" MinWidth="120">
<RichTextLabel Name="StatusLabel" HorizontalAlignment="Right" Margin="0 0 5 0"/>
<RichTextLabel Name="IdLabel" HorizontalAlignment="Right" Margin="0 0 5 0"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</PanelContainer>
</BoxContainer>
54 changes: 54 additions & 0 deletions Content.Client/Cargo/UI/BountyHistoryEntry.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Content.Client.Message;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Prototypes;
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.Cargo.UI;

[GenerateTypedNameReferences]
public sealed partial class BountyHistoryEntry : BoxContainer
{
[Dependency] private readonly IPrototypeManager _prototype = default!;

public BountyHistoryEntry(CargoBountyHistoryData bounty)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

if (!_prototype.TryIndex<CargoBountyPrototype>(bounty.Bounty, out var bountyPrototype))
return;

var items = new List<string>();
foreach (var entry in bountyPrototype.Entries)
{
items.Add(Loc.GetString("bounty-console-manifest-entry",
("amount", entry.Amount),
("item", Loc.GetString(entry.Name))));
}
ManifestLabel.SetMarkup(Loc.GetString("bounty-console-manifest-label", ("item", string.Join(", ", items))));
RewardLabel.SetMarkup(Loc.GetString("bounty-console-reward-label", ("reward", bountyPrototype.Reward)));
IdLabel.SetMarkup(Loc.GetString("bounty-console-id-label", ("id", bounty.Id)));

var stationTime = bounty.Timestamp.ToString("hh\\:mm\\:ss");
if (bounty.ActorName == null)
{
StatusLabel.SetMarkup(Loc.GetString("bounty-console-history-completed-label"));
NoticeLabel.SetMarkup(Loc.GetString("bounty-console-history-notice-completed-label", ("time", stationTime)));
}
else
{
StatusLabel.SetMarkup(Loc.GetString("bounty-console-history-skipped-label"));
NoticeLabel.SetMarkup(Loc.GetString("bounty-console-history-notice-skipped-label",
("id", bounty.ActorName),
("time", stationTime)));
}
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
}
}
29 changes: 20 additions & 9 deletions Content.Client/Cargo/UI/CargoBountyMenu.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,26 @@
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
</PanelContainer.PanelOverride>
<ScrollContainer HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer Name="BountyEntriesContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True">
</BoxContainer>
</ScrollContainer>
<TabContainer Name="MasterTabContainer" VerticalExpand="True" HorizontalExpand="True">
<ScrollContainer HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer Name="BountyEntriesContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True">
</BoxContainer>
</ScrollContainer>
<ScrollContainer HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer Name="BountyHistoryContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True">
</BoxContainer>
</ScrollContainer>
</TabContainer>
</PanelContainer>
<!-- Footer -->
<BoxContainer Orientation="Vertical">
Expand Down
12 changes: 11 additions & 1 deletion Content.Client/Cargo/UI/CargoBountyMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ public CargoBountyMenu()
RobustXamlLoader.Load(this);
}

public void UpdateEntries(List<CargoBountyData> bounties, TimeSpan untilNextSkip)
public void UpdateEntries(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
{
MasterTabContainer.SetTabTitle(0, Loc.GetString("bounty-console-tab-available-label"));
MasterTabContainer.SetTabTitle(1, Loc.GetString("bounty-console-tab-history-label"));

BountyEntriesContainer.Children.Clear();
foreach (var b in bounties)
{
Expand All @@ -32,5 +35,12 @@ public void UpdateEntries(List<CargoBountyData> bounties, TimeSpan untilNextSkip
{
MinHeight = 10
});

BountyHistoryContainer.Children.Clear();
foreach (var h in history)
{
var entry = new BountyHistoryEntry(h);
BountyHistoryContainer.AddChild(entry);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public sealed partial class StationCargoBountyDatabaseComponent : Component
[DataField, ViewVariables(VVAccess.ReadWrite)]
public List<CargoBountyData> Bounties = new();

/// <summary>
/// A list of all the bounties that have been completed or
/// skipped for a station.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public List<CargoBountyHistoryData> History = new();

/// <summary>
/// Used to determine unique order IDs
/// </summary>
Expand Down
26 changes: 19 additions & 7 deletions Content.Server/Cargo/Systems/CargoSystem.Bounty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.Database;
using Content.Shared.IdentityManagement;
using Content.Shared.NameIdentifier;
using Content.Shared.Paper;
using Content.Shared.Stacks;
Expand All @@ -16,6 +17,7 @@
using Robust.Server.Containers;
using Robust.Shared.Containers;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Server.Cargo.Systems;
Expand All @@ -25,6 +27,7 @@ public sealed partial class CargoSystem
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly NameIdentifierSystem _nameIdentifier = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSys = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;

[ValidatePrototypeId<NameIdentifierGroupPrototype>]
private const string BountyNameIdentifierGroup = "Bounty";
Expand Down Expand Up @@ -54,7 +57,7 @@ private void OnBountyConsoleOpened(EntityUid uid, CargoBountyConsoleComponent co
return;

var untilNextSkip = bountyDb.NextSkipTime - _timing.CurTime;
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDb.Bounties, untilNextSkip));
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDb.Bounties, bountyDb.History, untilNextSkip));
}

private void OnPrintLabelMessage(EntityUid uid, CargoBountyConsoleComponent component, BountyPrintLabelMessage args)
Expand Down Expand Up @@ -95,13 +98,13 @@ private void OnSkipBountyMessage(EntityUid uid, CargoBountyConsoleComponent comp
return;
}

if (!TryRemoveBounty(station, bounty.Value))
if (!TryRemoveBounty(station, bounty.Value, null, args.Actor))
return;

FillBountyDatabase(station);
db.NextSkipTime = _timing.CurTime + db.SkipDelay;
var untilNextSkip = db.NextSkipTime - _timing.CurTime;
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, untilNextSkip));
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, db.History, untilNextSkip));
_audio.PlayPvs(component.SkipSound, uid);
}

Expand Down Expand Up @@ -434,15 +437,15 @@ public bool TryAddBounty(EntityUid uid, CargoBountyPrototype bounty, StationCarg
}

[PublicAPI]
public bool TryRemoveBounty(EntityUid uid, string dataId, StationCargoBountyDatabaseComponent? component = null)
public bool TryRemoveBounty(EntityUid uid, string dataId, StationCargoBountyDatabaseComponent? component = null, EntityUid? actor = null)
{
if (!TryGetBountyFromId(uid, dataId, out var data, component))
return false;

return TryRemoveBounty(uid, data.Value, component);
return TryRemoveBounty(uid, data.Value, component, actor);
}

public bool TryRemoveBounty(EntityUid uid, CargoBountyData data, StationCargoBountyDatabaseComponent? component = null)
public bool TryRemoveBounty(EntityUid uid, CargoBountyData data, StationCargoBountyDatabaseComponent? component = null, EntityUid? actor = null)
{
if (!Resolve(uid, ref component))
return false;
Expand All @@ -451,6 +454,15 @@ public bool TryRemoveBounty(EntityUid uid, CargoBountyData data, StationCargoBou
{
if (component.Bounties[i].Id == data.Id)
{
string? actorName = default;
if (actor != null)
{
var getIdentityEvent = new TryGetIdentityShortInfoEvent(uid, actor.Value);
RaiseLocalEvent(getIdentityEvent);
actorName = getIdentityEvent.Title;
}

component.History.Add(new CargoBountyHistoryData(data, _gameTiming.CurTime, actorName));
component.Bounties.RemoveAt(i);
return true;
}
Expand Down Expand Up @@ -492,7 +504,7 @@ public void UpdateBountyConsoles()
}

var untilNextSkip = db.NextSkipTime - _timing.CurTime;
_uiSystem.SetUiState((uid, ui), CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, untilNextSkip));
_uiSystem.SetUiState((uid, ui), CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, db.History, untilNextSkip));
}
}

Expand Down
46 changes: 46 additions & 0 deletions Content.Shared/Cargo/CargoBountyHistoryData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Robust.Shared.Serialization;
using Content.Shared.Cargo.Prototypes;
using Robust.Shared.Prototypes;

namespace Content.Shared.Cargo;

/// <summary>
/// A data structure for storing historical information about bounties.
/// </summary>
[DataDefinition, NetSerializable, Serializable]
public readonly partial record struct CargoBountyHistoryData
{
/// <summary>
/// A unique id used to identify the bounty
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public string Id { get; init; } = string.Empty;

/// <summary>
/// Optional name of the actor that skipped the bounty.
/// Only set when the bounty has been skipped.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public string? ActorName { get; init; } = default;

/// <summary>
/// Time when this bounty was completed or skipped
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public TimeSpan Timestamp { get; init; } = TimeSpan.MinValue;

/// <summary>
/// The prototype containing information about the bounty.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField(required: true)]
public ProtoId<CargoBountyPrototype> Bounty { get; init; } = string.Empty;

public CargoBountyHistoryData(CargoBountyData bounty, TimeSpan timestamp, string? actorName)
{
Bounty = bounty.Bounty;
Id = bounty.Id;
ActorName = actorName;
Timestamp = timestamp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ public sealed partial class CargoBountyConsoleComponent : Component
public sealed class CargoBountyConsoleState : BoundUserInterfaceState
{
public List<CargoBountyData> Bounties;
public List<CargoBountyHistoryData> History;
public TimeSpan UntilNextSkip;

public CargoBountyConsoleState(List<CargoBountyData> bounties, TimeSpan untilNextSkip)
public CargoBountyConsoleState(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
{
Bounties = bounties;
History = history;
UntilNextSkip = untilNextSkip;
}
}
Expand Down
7 changes: 7 additions & 0 deletions Resources/Locale/en-US/cargo/cargo-bounty-console.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ bounty-console-flavor-right = v1.4

bounty-manifest-header = [font size=14][bold]Official cargo bounty manifest[/bold] (ID#{$id})[/font]
bounty-manifest-list-start = Item manifest:

bounty-console-tab-available-label = Available
bounty-console-tab-history-label = History
bounty-console-history-notice-completed-label = {$time} - Completed
bounty-console-history-notice-skipped-label = {$time} - Skipped by {$id}
bounty-console-history-completed-label = [color=limegreen]Completed[/color]
bounty-console-history-skipped-label = [color=red]Skipped[/color]
Loading