* WantedListCartridge has been added * WantedListCartridge user interface works * WantedListCartridge is added as standard in some PDAs * The CriminalRecordsSystem can now also take into account who created the record * Added offense history table * Fix of missing loaderUid for a cartridge without installing the program * Added personalized information about the target * The crime history has been finalized * Added StatusList * The officer's name has been added to the automatic history * WantedListCartridge has been added to the HOS locker * WantedListCartridge has been removed from brigmedic's preset programs * The StealConditionSystem now takes into account whether a cartridge is inserted or installed * Added target to thief on WantedListCartridge * Merge fix * Removing copypaste * Fix merge 2 * The sprite of WantedListCartridge has been changed * Update pda.yml * Fix scrollbar in the history table * Upstream localization fix * `StatusList` has been replaced by `ListContainer` with `TextureRect` * Margin fix
241 lines
7.9 KiB
C#
241 lines
7.9 KiB
C#
using System.Linq;
|
|
using Content.Client.UserInterface.Controls;
|
|
using Content.Shared.CriminalRecords.Systems;
|
|
using Content.Shared.Security;
|
|
using Content.Shared.StatusIcon;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.ResourceManagement;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Input;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Client.CartridgeLoader.Cartridges;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class WantedListUiFragment : BoxContainer
|
|
{
|
|
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
private readonly SpriteSystem _spriteSystem;
|
|
|
|
private string? _selectedTargetName;
|
|
private List<WantedRecord> _wantedRecords = new();
|
|
|
|
public WantedListUiFragment()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
|
|
|
|
SearchBar.OnTextChanged += OnSearchBarTextChanged;
|
|
}
|
|
|
|
private void OnSearchBarTextChanged(LineEdit.LineEditEventArgs args)
|
|
{
|
|
var found = !String.IsNullOrWhiteSpace(args.Text)
|
|
? _wantedRecords.FindAll(r =>
|
|
r.TargetInfo.Name.Contains(args.Text) ||
|
|
r.Status.ToString().Contains(args.Text, StringComparison.OrdinalIgnoreCase))
|
|
: _wantedRecords;
|
|
|
|
UpdateState(found, false);
|
|
}
|
|
|
|
public void UpdateState(List<WantedRecord> records, bool refresh = true)
|
|
{
|
|
if (records.Count == 0)
|
|
{
|
|
NoRecords.Visible = true;
|
|
RecordsList.Visible = false;
|
|
RecordUnselected.Visible = false;
|
|
PersonContainer.Visible = false;
|
|
|
|
_selectedTargetName = null;
|
|
if (refresh)
|
|
_wantedRecords.Clear();
|
|
|
|
RecordsList.PopulateList(new List<ListData>());
|
|
|
|
return;
|
|
}
|
|
|
|
NoRecords.Visible = false;
|
|
RecordsList.Visible = true;
|
|
RecordUnselected.Visible = true;
|
|
PersonContainer.Visible = false;
|
|
|
|
var dataList = records.Select(r => new StatusListData(r)).ToList();
|
|
|
|
RecordsList.GenerateItem = GenerateItem;
|
|
RecordsList.ItemPressed = OnItemSelected;
|
|
RecordsList.PopulateList(dataList);
|
|
|
|
if (refresh)
|
|
_wantedRecords = records;
|
|
}
|
|
|
|
private void OnItemSelected(BaseButton.ButtonEventArgs args, ListData data)
|
|
{
|
|
if (data is not StatusListData(var record))
|
|
return;
|
|
|
|
FormattedMessage GetLoc(string fluentId, params (string,object)[] args)
|
|
{
|
|
var msg = new FormattedMessage();
|
|
var fluent = Loc.GetString(fluentId, args);
|
|
msg.AddMarkupPermissive(fluent);
|
|
return msg;
|
|
}
|
|
|
|
// Set personal info
|
|
PersonName.Text = record.TargetInfo.Name;
|
|
TargetAge.SetMessage(GetLoc(
|
|
"wanted-list-age-label",
|
|
("age", record.TargetInfo.Age)
|
|
));
|
|
TargetJob.SetMessage(GetLoc(
|
|
"wanted-list-job-label",
|
|
("job", record.TargetInfo.JobTitle.ToLower())
|
|
));
|
|
TargetSpecies.SetMessage(GetLoc(
|
|
"wanted-list-species-label",
|
|
("species", record.TargetInfo.Species.ToLower())
|
|
));
|
|
TargetGender.SetMessage(GetLoc(
|
|
"wanted-list-gender-label",
|
|
("gender", record.TargetInfo.Gender)
|
|
));
|
|
|
|
// Set reason
|
|
WantedReason.SetMessage(GetLoc(
|
|
"wanted-list-reason-label",
|
|
("reason", record.Reason ?? Loc.GetString("wanted-list-unknown-reason-label"))
|
|
));
|
|
|
|
// Set status
|
|
PersonState.SetMessage(GetLoc(
|
|
"wanted-list-status-label",
|
|
("status", record.Status.ToString().ToLower())
|
|
));
|
|
|
|
// Set initiator
|
|
InitiatorName.SetMessage(GetLoc(
|
|
"wanted-list-initiator-label",
|
|
("initiator", record.Initiator ?? Loc.GetString("wanted-list-unknown-initiator-label"))
|
|
));
|
|
|
|
// History table
|
|
// Clear table if it exists
|
|
HistoryTable.RemoveAllChildren();
|
|
|
|
HistoryTable.AddChild(new Label()
|
|
{
|
|
Text = Loc.GetString("wanted-list-history-table-time-col"),
|
|
StyleClasses = { "LabelSmall" },
|
|
HorizontalAlignment = HAlignment.Center,
|
|
});
|
|
HistoryTable.AddChild(new Label()
|
|
{
|
|
Text = Loc.GetString("wanted-list-history-table-reason-col"),
|
|
StyleClasses = { "LabelSmall" },
|
|
HorizontalAlignment = HAlignment.Center,
|
|
HorizontalExpand = true,
|
|
});
|
|
|
|
HistoryTable.AddChild(new Label()
|
|
{
|
|
Text = Loc.GetString("wanted-list-history-table-initiator-col"),
|
|
StyleClasses = { "LabelSmall" },
|
|
HorizontalAlignment = HAlignment.Center,
|
|
});
|
|
|
|
if (record.History.Count > 0)
|
|
{
|
|
HistoryTable.Visible = true;
|
|
|
|
foreach (var history in record.History.OrderByDescending(h => h.AddTime))
|
|
{
|
|
HistoryTable.AddChild(new Label()
|
|
{
|
|
Text = $"{history.AddTime.Hours:00}:{history.AddTime.Minutes:00}:{history.AddTime.Seconds:00}",
|
|
StyleClasses = { "LabelSmall" },
|
|
VerticalAlignment = VAlignment.Top,
|
|
});
|
|
|
|
HistoryTable.AddChild(new RichTextLabel()
|
|
{
|
|
Text = $"[color=white]{history.Crime}[/color]",
|
|
HorizontalExpand = true,
|
|
VerticalAlignment = VAlignment.Top,
|
|
StyleClasses = { "LabelSubText" },
|
|
Margin = new(10f, 0f),
|
|
});
|
|
|
|
HistoryTable.AddChild(new RichTextLabel()
|
|
{
|
|
Text = $"[color=white]{history.InitiatorName}[/color]",
|
|
StyleClasses = { "LabelSubText" },
|
|
VerticalAlignment = VAlignment.Top,
|
|
});
|
|
}
|
|
}
|
|
|
|
RecordUnselected.Visible = false;
|
|
PersonContainer.Visible = true;
|
|
|
|
// Save selected item
|
|
_selectedTargetName = record.TargetInfo.Name;
|
|
}
|
|
|
|
private void GenerateItem(ListData data, ListContainerButton button)
|
|
{
|
|
if (data is not StatusListData(var record))
|
|
return;
|
|
|
|
var box = new BoxContainer() { Orientation = LayoutOrientation.Horizontal, HorizontalExpand = true };
|
|
var label = new Label() { Text = record.TargetInfo.Name };
|
|
var rect = new TextureRect()
|
|
{
|
|
TextureScale = new(2.2f),
|
|
VerticalAlignment = VAlignment.Center,
|
|
HorizontalAlignment = HAlignment.Center,
|
|
Margin = new(0f, 0f, 6f, 0f),
|
|
};
|
|
|
|
if (record.Status is not SecurityStatus.None)
|
|
{
|
|
var proto = "SecurityIcon" + record.Status switch
|
|
{
|
|
SecurityStatus.Detained => "Incarcerated",
|
|
_ => record.Status.ToString(),
|
|
};
|
|
|
|
if (_prototypeManager.TryIndex<SecurityIconPrototype>(proto, out var prototype))
|
|
{
|
|
rect.Texture = _spriteSystem.Frame0(prototype.Icon);
|
|
}
|
|
}
|
|
|
|
box.AddChild(rect);
|
|
box.AddChild(label);
|
|
button.AddChild(box);
|
|
button.AddStyleClass(ListContainer.StyleClassListContainerButton);
|
|
|
|
if (record.TargetInfo.Name.Equals(_selectedTargetName))
|
|
{
|
|
button.Pressed = true;
|
|
// For some reason the event is not called when `Pressed` changed, call it manually.
|
|
OnItemSelected(
|
|
new(button, new(new(), BoundKeyState.Down, new(), false, new(), new())),
|
|
data);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal record StatusListData(WantedRecord Record) : ListData;
|