Crew manifest as a PDA cartridge program (#18498)
Co-authored-by: Phill101 <holypics4@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Map;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Content.Server.CartridgeLoader;
|
||||
|
||||
@@ -80,7 +81,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
|
||||
return new List<EntityUid>();
|
||||
|
||||
//Don't count a cartridge that has already been installed as available to avoid confusion
|
||||
if (loader.CartridgeSlot.HasItem && IsInstalled(Prototype(loader.CartridgeSlot.Item!.Value)?.ID, loader))
|
||||
if (loader.CartridgeSlot.HasItem && TryFindInstalled(Prototype(loader.CartridgeSlot.Item!.Value)?.ID, loader, out _))
|
||||
return loader.InstalledPrograms;
|
||||
|
||||
var available = new List<EntityUid>();
|
||||
@@ -127,7 +128,13 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
|
||||
return false;
|
||||
|
||||
//Prevent installing cartridges that have already been installed
|
||||
if (IsInstalled(prototype, loader))
|
||||
if (TryFindInstalled(prototype, loader, out _))
|
||||
return false;
|
||||
|
||||
var ev = new ProgramInstallationAttempt(loaderUid, prototype);
|
||||
RaiseLocalEvent(ref ev);
|
||||
|
||||
if (ev.Cancelled)
|
||||
return false;
|
||||
|
||||
var installedProgram = Spawn(prototype, new EntityCoordinates(loaderUid, 0, 0));
|
||||
@@ -141,6 +148,22 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uninstalls a program using its prototype
|
||||
/// </summary>
|
||||
/// <param name="loaderUid">The cartridge loader uid</param>
|
||||
/// <param name="prototype">The prototype name of the program to be uninstalled</param>
|
||||
/// <param name="loader">The cartridge loader component</param>
|
||||
/// <returns>Whether uninstalling the program was successful</returns>
|
||||
public bool UninstallProgram(EntityUid loaderUid, string prototype, CartridgeLoaderComponent? loader = default!)
|
||||
{
|
||||
if (!Resolve(loaderUid, ref loader))
|
||||
return false;
|
||||
|
||||
return TryFindInstalled(prototype, loader, out var programUid) &&
|
||||
UninstallProgram(loaderUid, programUid.Value, loader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uninstalls a program using its uid
|
||||
/// </summary>
|
||||
@@ -345,16 +368,20 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a program is already installed by searching for its prototype name in the list of installed programs
|
||||
/// Searches for a program by its prototype name in the list of installed programs
|
||||
/// </summary>
|
||||
private bool IsInstalled(string? prototype, CartridgeLoaderComponent loader)
|
||||
private bool TryFindInstalled(string? prototype, CartridgeLoaderComponent loader, [NotNullWhen(true)] out EntityUid? programUid)
|
||||
{
|
||||
foreach (var program in loader.InstalledPrograms)
|
||||
{
|
||||
if (Prototype(program)?.ID == prototype)
|
||||
{
|
||||
programUid = program;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
programUid = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -414,3 +441,9 @@ public sealed class CartridgeAfterInteractEvent : EntityEventArgs
|
||||
InteractEvent = interactEvent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an attempt of program installation.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct ProgramInstallationAttempt(EntityUid LoaderUid, string Prototype, bool Cancelled = false);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server.CartridgeLoader.Cartridges;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class CrewManifestCartridgeComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using Content.Server.CrewManifest;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.CartridgeLoader.Cartridges;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Server.CartridgeLoader.Cartridges;
|
||||
|
||||
public sealed class CrewManifestCartridgeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly CartridgeLoaderSystem _cartridgeLoader = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
[Dependency] private readonly CrewManifestSystem _crewManifest = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
|
||||
private const string CartridgePrototypeName = "CrewManifestCartridge";
|
||||
|
||||
/// <summary>
|
||||
/// Flag that shows that if crew manifest is allowed to be viewed from 'unsecure' entities,
|
||||
/// which is the keys for the cartridge.
|
||||
/// </summary>
|
||||
private bool _unsecureViewersAllowed = true;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<CrewManifestCartridgeComponent, CartridgeMessageEvent>(OnUiMessage);
|
||||
SubscribeLocalEvent<CrewManifestCartridgeComponent, CartridgeUiReadyEvent>(OnUiReady);
|
||||
SubscribeLocalEvent<ProgramInstallationAttempt>(OnInstallationAttempt);
|
||||
_configManager.OnValueChanged(CCVars.CrewManifestUnsecure, OnCrewManifestUnsecureChanged, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ui messages received here get wrapped by a CartridgeMessageEvent and are relayed from the <see cref="CartridgeLoaderSystem"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The cartridge specific ui message event needs to inherit from the CartridgeMessageEvent
|
||||
/// </remarks>
|
||||
private void OnUiMessage(EntityUid uid, CrewManifestCartridgeComponent component, CartridgeMessageEvent args)
|
||||
{
|
||||
UpdateUiState(uid, args.LoaderUid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This gets called when the ui fragment needs to be updated for the first time after activating
|
||||
/// </summary>
|
||||
private void OnUiReady(EntityUid uid, CrewManifestCartridgeComponent component, CartridgeUiReadyEvent args)
|
||||
{
|
||||
UpdateUiState(uid, args.Loader, component);
|
||||
}
|
||||
|
||||
private void UpdateUiState(EntityUid uid, EntityUid loaderUid, CrewManifestCartridgeComponent? component)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
var owningStation = _stationSystem.GetOwningStation(uid);
|
||||
|
||||
if (owningStation is null)
|
||||
return;
|
||||
|
||||
var (stationName, entries) = _crewManifest.GetCrewManifest(owningStation.Value);
|
||||
|
||||
var state = new CrewManifestUiState(stationName, entries);
|
||||
_cartridgeLoader.UpdateCartridgeUiState(loaderUid, state);
|
||||
}
|
||||
|
||||
private void OnInstallationAttempt(ref ProgramInstallationAttempt args)
|
||||
{
|
||||
if (args.Prototype == CartridgePrototypeName && !_unsecureViewersAllowed)
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnCrewManifestUnsecureChanged(bool unsecureViewersAllowed)
|
||||
{
|
||||
_unsecureViewersAllowed = unsecureViewersAllowed;
|
||||
|
||||
var allCartridgeLoaders = AllEntityQuery<CartridgeLoaderComponent>();
|
||||
|
||||
while (allCartridgeLoaders.MoveNext(out EntityUid loaderUid, out CartridgeLoaderComponent? comp))
|
||||
{
|
||||
if (_unsecureViewersAllowed)
|
||||
_cartridgeLoader?.InstallProgram(loaderUid, CartridgePrototypeName, false, comp);
|
||||
else
|
||||
_cartridgeLoader?.UninstallProgram(loaderUid, CartridgePrototypeName, comp);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
_configManager.UnsubValueChanged(CCVars.CrewManifestUnsecure, OnCrewManifestUnsecureChanged);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user