Content update for NetEntities (#18935)

This commit is contained in:
metalgearsloth
2023-09-11 09:42:41 +10:00
committed by GitHub
parent 389c8d1a2c
commit 5a0fc68be2
526 changed files with 3058 additions and 2215 deletions

View File

@@ -1,4 +1,7 @@
using Content.Server.DeviceNetwork.Systems;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.PDA;
using Content.Shared.CartridgeLoader;
using Content.Shared.Interaction;
using Robust.Server.Containers;
@@ -6,7 +9,6 @@ using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using System.Diagnostics.CodeAnalysis;
namespace Content.Server.CartridgeLoader;
@@ -14,8 +16,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
{
[Dependency] private readonly ContainerSystem _containerSystem = default!;
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
private const string ContainerName = "program-container";
[Dependency] private readonly PdaSystem _pda = default!;
public override void Initialize()
{
@@ -29,6 +30,66 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
SubscribeLocalEvent<CartridgeLoaderComponent, CartridgeUiMessage>(OnUiMessage);
}
public IReadOnlyList<EntityUid> GetInstalled(EntityUid uid, ContainerManagerComponent? comp = null)
{
if (_containerSystem.TryGetContainer(uid, InstalledContainerId, out var container, comp))
return container.ContainedEntities;
return Array.Empty<EntityUid>();
}
public bool TryGetProgram<T>(
EntityUid uid,
[NotNullWhen(true)] out EntityUid? programUid,
[NotNullWhen(true)] out T? program,
bool installedOnly = false,
CartridgeLoaderComponent? loader = null,
ContainerManagerComponent? containerManager = null)
{
program = default;
programUid = null;
if (!_containerSystem.TryGetContainer(uid, InstalledContainerId, out var container, containerManager))
return false;
foreach (var prog in container.ContainedEntities)
{
if (!TryComp(prog, out program))
continue;
programUid = prog;
return true;
}
if (installedOnly)
return false;
if (!Resolve(uid, ref loader) || !TryComp(loader.CartridgeSlot.Item, out program))
return false;
programUid = loader.CartridgeSlot.Item;
return true;
}
public bool TryGetProgram<T>(
EntityUid uid,
[NotNullWhen(true)] out EntityUid? programUid,
bool installedOnly = false,
CartridgeLoaderComponent? loader = null,
ContainerManagerComponent? containerManager = null)
{
return TryGetProgram<T>(uid, out programUid, out _, installedOnly, loader, containerManager);
}
public bool HasProgram<T>(
EntityUid uid,
bool installedOnly = false,
CartridgeLoaderComponent? loader = null,
ContainerManagerComponent? containerManager = null)
{
return TryGetProgram<T>(uid, out _, out _, installedOnly, loader, containerManager);
}
/// <summary>
/// Updates the cartridge loaders ui state.
/// </summary>
@@ -37,16 +98,17 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// and use this method to update its state so the cartridge loaders state can be added to it.
/// </remarks>
/// <seealso cref="PDA.PdaSystem.UpdatePdaUserInterface"/>
public void UpdateUiState(EntityUid loaderUid, CartridgeLoaderUiState state, IPlayerSession? session = default!, CartridgeLoaderComponent? loader = default!)
public void UpdateUiState(EntityUid loaderUid, IPlayerSession? session, CartridgeLoaderComponent? loader)
{
if (!Resolve(loaderUid, ref loader))
return;
state.ActiveUI = loader.ActiveProgram;
state.Programs = GetAvailablePrograms(loaderUid, loader);
if (!_userInterfaceSystem.TryGetUi(loaderUid, loader.UiKey, out var ui))
return;
if (_userInterfaceSystem.TryGetUi(loaderUid, loader.UiKey, out var ui))
UserInterfaceSystem.SetUiState(ui, state, session);
var programs = GetAvailablePrograms(loaderUid, loader);
var state = new CartridgeLoaderUiState(programs, GetNetEntity(loader.ActiveProgram));
_userInterfaceSystem.SetUiState(ui, state, session);
}
/// <summary>
@@ -66,7 +128,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
return;
if (_userInterfaceSystem.TryGetUi(loaderUid, loader.UiKey, out var ui))
UserInterfaceSystem.SetUiState(ui, state, session);
_userInterfaceSystem.SetUiState(ui, state, session);
}
/// <summary>
@@ -75,21 +137,18 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// <param name="uid">The cartridge loaders uid</param>
/// <param name="loader">The cartridge loader component</param>
/// <returns>A list of all the available program entity ids</returns>
public List<EntityUid> GetAvailablePrograms(EntityUid uid, CartridgeLoaderComponent? loader = default!)
public List<NetEntity> GetAvailablePrograms(EntityUid uid, CartridgeLoaderComponent? loader = default!)
{
if (!Resolve(uid, ref loader))
return new List<EntityUid>();
return new List<NetEntity>();
//Don't count a cartridge that has already been installed as available to avoid confusion
if (loader.CartridgeSlot.HasItem && TryFindInstalled(Prototype(loader.CartridgeSlot.Item!.Value)?.ID, loader, out _))
return loader.InstalledPrograms;
var available = GetNetEntityList(GetInstalled(uid));
var available = new List<EntityUid>();
available.AddRange(loader.InstalledPrograms);
if (loader.CartridgeSlot.HasItem)
available.Add(loader.CartridgeSlot.Item!.Value);
if (loader.CartridgeSlot.Item is not { } cartridge)
return available;
// TODO exclude duplicate programs. Or something I dunno I CBF fixing this mess.
available.Add(GetNetEntity(cartridge));
return available;
}
@@ -102,11 +161,13 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// <returns>Whether installing the cartridge was successful</returns>
public bool InstallCartridge(EntityUid loaderUid, EntityUid cartridgeUid, CartridgeLoaderComponent? loader = default!)
{
if (!Resolve(loaderUid, ref loader) || loader.InstalledPrograms.Count >= loader.DiskSpace)
if (!Resolve(loaderUid, ref loader))
return false;
//This will eventually be replaced by serializing and deserializing the cartridge to copy it when something needs
//the data on the cartridge to carry over when installing
// For anyone stumbling onto this: Do not do this or I will cut you.
var prototypeId = Prototype(cartridgeUid)?.ID;
return prototypeId != null && InstallProgram(loaderUid, prototypeId, loader: loader);
}
@@ -121,16 +182,16 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// <returns>Whether installing the cartridge was successful</returns>
public bool InstallProgram(EntityUid loaderUid, string prototype, bool deinstallable = true, CartridgeLoaderComponent? loader = default!)
{
if (!Resolve(loaderUid, ref loader) || loader.InstalledPrograms.Count >= loader.DiskSpace)
if (!Resolve(loaderUid, ref loader))
return false;
if (!_containerSystem.TryGetContainer(loaderUid, ContainerName, out var container))
if (!_containerSystem.TryGetContainer(loaderUid, InstalledContainerId, out var container))
return false;
//Prevent installing cartridges that have already been installed
if (TryFindInstalled(prototype, loader, out _))
if (container.Count >= loader.DiskSpace)
return false;
// TODO cancel duplicate program installations
var ev = new ProgramInstallationAttempt(loaderUid, prototype);
RaiseLocalEvent(ref ev);
@@ -138,32 +199,15 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
return false;
var installedProgram = Spawn(prototype, new EntityCoordinates(loaderUid, 0, 0));
container?.Insert(installedProgram);
container.Insert(installedProgram);
UpdateCartridgeInstallationStatus(installedProgram, deinstallable ? InstallationStatus.Installed : InstallationStatus.Readonly);
loader.InstalledPrograms.Add(installedProgram);
RaiseLocalEvent(installedProgram, new CartridgeAddedEvent(loaderUid));
UpdateUserInterfaceState(loaderUid, loader);
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>
@@ -173,14 +217,16 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// <returns>Whether uninstalling the program was successful</returns>
public bool UninstallProgram(EntityUid loaderUid, EntityUid programUid, CartridgeLoaderComponent? loader = default!)
{
if (!Resolve(loaderUid, ref loader) || !ContainsCartridge(programUid, loader, true))
if (!Resolve(loaderUid, ref loader))
return false;
if (!GetInstalled(loaderUid).Contains(programUid))
return false;
if (loader.ActiveProgram == programUid)
loader.ActiveProgram = null;
loader.BackgroundPrograms.Remove(programUid);
loader.InstalledPrograms.Remove(programUid);
EntityManager.QueueDeleteEntity(programUid);
UpdateUserInterfaceState(loaderUid, loader);
return true;
@@ -194,7 +240,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
if (!Resolve(loaderUid, ref loader))
return;
if (!ContainsCartridge(programUid, loader))
if (!HasProgram(loaderUid, programUid, loader))
return;
if (loader.ActiveProgram.HasValue)
@@ -215,7 +261,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
if (!Resolve(loaderUid, ref loader))
return;
if (!ContainsCartridge(programUid, loader) || loader.ActiveProgram != programUid)
if (!HasProgram(loaderUid, programUid, loader) || loader.ActiveProgram != programUid)
return;
if (!loader.BackgroundPrograms.Contains(programUid))
@@ -236,7 +282,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
if (!Resolve(loaderUid, ref loader))
return;
if (!ContainsCartridge(cartridgeUid, loader))
if (!HasProgram(loaderUid, cartridgeUid, loader))
return;
if (loader.ActiveProgram != cartridgeUid)
@@ -253,7 +299,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
if (!Resolve(loaderUid, ref loader))
return;
if (!ContainsCartridge(cartridgeUid, loader))
if (!HasProgram(loaderUid, cartridgeUid, loader))
return;
if (loader.ActiveProgram != cartridgeUid)
@@ -264,12 +310,18 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
protected override void OnItemInserted(EntityUid uid, CartridgeLoaderComponent loader, EntInsertedIntoContainerMessage args)
{
if (args.Container.ID != InstalledContainerId && args.Container.ID != loader.CartridgeSlot.ID)
return;
RaiseLocalEvent(args.Entity, new CartridgeAddedEvent(uid));
base.OnItemInserted(uid, loader, args);
}
protected override void OnItemRemoved(EntityUid uid, CartridgeLoaderComponent loader, EntRemovedFromContainerMessage args)
{
if (args.Container.ID != InstalledContainerId && args.Container.ID != loader.CartridgeSlot.ID)
return;
var deactivate = loader.BackgroundPrograms.Remove(args.Entity);
if (loader.ActiveProgram == args.Entity)
@@ -283,6 +335,8 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
RaiseLocalEvent(args.Entity, new CartridgeRemovedEvent(uid));
base.OnItemRemoved(uid, loader, args);
_pda.UpdatePdaUi(uid);
}
/// <summary>
@@ -290,6 +344,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// </summary>
private void OnMapInit(EntityUid uid, CartridgeLoaderComponent component, MapInitEvent args)
{
// TODO remove this and use container fill.
foreach (var prototype in component.PreinstalledPrograms)
{
InstallProgram(uid, prototype, deinstallable: false);
@@ -308,19 +363,21 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
private void OnLoaderUiMessage(EntityUid loaderUid, CartridgeLoaderComponent component, CartridgeLoaderUiMessage message)
{
var cartridge = GetEntity(message.CartridgeUid);
switch (message.Action)
{
case CartridgeUiMessageAction.Activate:
ActivateProgram(loaderUid, message.CartridgeUid, component);
ActivateProgram(loaderUid, cartridge, component);
break;
case CartridgeUiMessageAction.Deactivate:
DeactivateProgram(loaderUid, message.CartridgeUid, component);
DeactivateProgram(loaderUid, cartridge, component);
break;
case CartridgeUiMessageAction.Install:
InstallCartridge(loaderUid, message.CartridgeUid, component);
InstallCartridge(loaderUid, cartridge, component);
break;
case CartridgeUiMessageAction.Uninstall:
UninstallProgram(loaderUid, message.CartridgeUid, component);
UninstallProgram(loaderUid, cartridge, component);
break;
case CartridgeUiMessageAction.UIReady:
if (component.ActiveProgram.HasValue)
@@ -337,7 +394,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
private void OnUiMessage(EntityUid uid, CartridgeLoaderComponent component, CartridgeUiMessage args)
{
var cartridgeEvent = args.MessageEvent;
cartridgeEvent.LoaderUid = uid;
cartridgeEvent.LoaderUid = GetNetEntity(uid);
RelayEvent(component, cartridgeEvent, true);
}
@@ -367,24 +424,6 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
}
}
/// <summary>
/// Searches for a program by its prototype name in the list of installed programs
/// </summary>
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;
}
/// <summary>
/// Shortcut for updating the loaders user interface state without passing in a subtype of <see cref="CartridgeLoaderUiState"/>
/// like the <see cref="PDA.PdaSystem"/> does when updating its ui state
@@ -392,7 +431,7 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
/// <seealso cref="PDA.PdaSystem.UpdatePdaUserInterface"/>
private void UpdateUserInterfaceState(EntityUid loaderUid, CartridgeLoaderComponent loader)
{
UpdateUiState(loaderUid, new CartridgeLoaderUiState(), null, loader);
UpdateUiState(loaderUid, null, loader);
}
private void UpdateCartridgeInstallationStatus(EntityUid cartridgeUid, InstallationStatus installationStatus, CartridgeComponent? cartridgeComponent = default!)
@@ -400,13 +439,13 @@ public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem
if (Resolve(cartridgeUid, ref cartridgeComponent))
{
cartridgeComponent.InstallationStatus = installationStatus;
Dirty(cartridgeComponent);
Dirty(cartridgeUid, cartridgeComponent);
}
}
private static bool ContainsCartridge(EntityUid cartridgeUid, CartridgeLoaderComponent loader, bool onlyInstalled = false)
private bool HasProgram(EntityUid loader, EntityUid program, CartridgeLoaderComponent component)
{
return !onlyInstalled && loader.CartridgeSlot.Item?.Equals(cartridgeUid) == true || loader.InstalledPrograms.Contains(cartridgeUid);
return component.CartridgeSlot.Item == program || GetInstalled(loader).Contains(program);
}
}