Wanted list cartridge (#31223)

* 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
This commit is contained in:
Эдуард
2024-09-19 13:22:02 +03:00
committed by GitHub
parent 75ff65d108
commit 1468cbdb8a
22 changed files with 579 additions and 34 deletions

View File

@@ -1,10 +1,15 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.CartridgeLoader;
using Content.Server.CartridgeLoader.Cartridges;
using Content.Server.StationRecords.Systems;
using Content.Shared.CriminalRecords;
using Content.Shared.CriminalRecords.Systems;
using Content.Shared.Security;
using Content.Shared.StationRecords;
using Content.Server.GameTicking;
using Content.Server.Station.Systems;
using Content.Shared.CartridgeLoader;
using Content.Shared.CartridgeLoader.Cartridges;
namespace Content.Server.CriminalRecords.Systems;
@@ -20,12 +25,18 @@ public sealed class CriminalRecordsSystem : SharedCriminalRecordsSystem
{
[Dependency] private readonly GameTicker _ticker = default!;
[Dependency] private readonly StationRecordsSystem _records = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly CartridgeLoaderSystem _cartridge = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AfterGeneralRecordCreatedEvent>(OnGeneralRecordCreated);
SubscribeLocalEvent<WantedListCartridgeComponent, CriminalRecordChangedEvent>(OnRecordChanged);
SubscribeLocalEvent<WantedListCartridgeComponent, CartridgeUiReadyEvent>(OnCartridgeUiReady);
SubscribeLocalEvent<WantedListCartridgeComponent, CriminalHistoryAddedEvent>(OnHistoryAdded);
SubscribeLocalEvent<WantedListCartridgeComponent, CriminalHistoryRemovedEvent>(OnHistoryRemoved);
}
private void OnGeneralRecordCreated(AfterGeneralRecordCreatedEvent ev)
@@ -39,14 +50,14 @@ public sealed class CriminalRecordsSystem : SharedCriminalRecordsSystem
/// Reason should only be passed if status is Wanted, nullability isn't checked.
/// </summary>
/// <returns>True if the status is changed, false if not</returns>
public bool TryChangeStatus(StationRecordKey key, SecurityStatus status, string? reason)
public bool TryChangeStatus(StationRecordKey key, SecurityStatus status, string? reason, string? initiatorName = null)
{
// don't do anything if its the same status
if (!_records.TryGetRecord<CriminalRecord>(key, out var record)
|| status == record.Status)
return false;
OverwriteStatus(key, record, status, reason);
OverwriteStatus(key, record, status, reason, initiatorName);
return true;
}
@@ -54,16 +65,24 @@ public sealed class CriminalRecordsSystem : SharedCriminalRecordsSystem
/// <summary>
/// Sets the status without checking previous status or reason nullability.
/// </summary>
public void OverwriteStatus(StationRecordKey key, CriminalRecord record, SecurityStatus status, string? reason)
public void OverwriteStatus(StationRecordKey key, CriminalRecord record, SecurityStatus status, string? reason, string? initiatorName = null)
{
record.Status = status;
record.Reason = reason;
record.InitiatorName = initiatorName;
var name = _records.RecordName(key);
if (name != string.Empty)
UpdateCriminalIdentity(name, status);
_records.Synchronize(key);
var args = new CriminalRecordChangedEvent(record);
var query = EntityQueryEnumerator<WantedListCartridgeComponent>();
while (query.MoveNext(out var readerUid, out _))
{
RaiseLocalEvent(readerUid, ref args);
}
}
/// <summary>
@@ -76,15 +95,23 @@ public sealed class CriminalRecordsSystem : SharedCriminalRecordsSystem
return false;
record.History.Add(entry);
var args = new CriminalHistoryAddedEvent(entry);
var query = EntityQueryEnumerator<WantedListCartridgeComponent>();
while (query.MoveNext(out var readerUid, out _))
{
RaiseLocalEvent(readerUid, ref args);
}
return true;
}
/// <summary>
/// Creates and tries to add a history entry using the current time.
/// </summary>
public bool TryAddHistory(StationRecordKey key, string line)
public bool TryAddHistory(StationRecordKey key, string line, string? initiatorName = null)
{
var entry = new CrimeHistory(_ticker.RoundDuration(), line);
var entry = new CrimeHistory(_ticker.RoundDuration(), line, initiatorName);
return TryAddHistory(key, entry);
}
@@ -100,7 +127,58 @@ public sealed class CriminalRecordsSystem : SharedCriminalRecordsSystem
if (index >= record.History.Count)
return false;
var history = record.History[(int)index];
record.History.RemoveAt((int) index);
var args = new CriminalHistoryRemovedEvent(history);
var query = EntityQueryEnumerator<WantedListCartridgeComponent>();
while (query.MoveNext(out var readerUid, out _))
{
RaiseLocalEvent(readerUid, ref args);
}
return true;
}
private void OnRecordChanged(Entity<WantedListCartridgeComponent> ent, ref CriminalRecordChangedEvent args) =>
StateChanged(ent);
private void OnHistoryAdded(Entity<WantedListCartridgeComponent> ent, ref CriminalHistoryAddedEvent args) =>
StateChanged(ent);
private void OnHistoryRemoved(Entity<WantedListCartridgeComponent> ent, ref CriminalHistoryRemovedEvent args) =>
StateChanged(ent);
private void StateChanged(Entity<WantedListCartridgeComponent> ent)
{
if (Comp<CartridgeComponent>(ent).LoaderUid is not { } loaderUid)
return;
UpdateReaderUi(ent, loaderUid);
}
private void OnCartridgeUiReady(Entity<WantedListCartridgeComponent> ent, ref CartridgeUiReadyEvent args)
{
UpdateReaderUi(ent, args.Loader);
}
private void UpdateReaderUi(Entity<WantedListCartridgeComponent> ent, EntityUid loaderUid)
{
if (_station.GetOwningStation(ent) is not { } station)
return;
var records = _records.GetRecordsOfType<CriminalRecord>(station)
.Where(cr => cr.Item2.Status is not SecurityStatus.None || cr.Item2.History.Count > 0)
.Select(cr =>
{
var (i, r) = cr;
var key = new StationRecordKey(i, station);
// Hopefully it will work smoothly.....
_records.TryGetRecord(key, out GeneralStationRecord? generalRecord);
return new WantedRecord(generalRecord!, r.Status, r.Reason, r.InitiatorName, r.History);
});
var state = new WantedListUiState(records.ToList());
_cartridge.UpdateCartridgeUiState(loaderUid, state);
}
}