diff --git a/Robust.Client/GameObjects/ClientEntityManager.Spawn.cs b/Robust.Client/GameObjects/ClientEntityManager.Spawn.cs index 46a97463b6b..a86fc19859e 100644 --- a/Robust.Client/GameObjects/ClientEntityManager.Spawn.cs +++ b/Robust.Client/GameObjects/ClientEntityManager.Spawn.cs @@ -76,6 +76,33 @@ public override bool PredictedTrySpawnInContainer( return true; } + public override bool PredictedTrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + ComponentRegistry? overrides = null) + { + if (!TrySpawnInContainer(protoName, container, out uid, overrides)) + return false; + + FlagPredicted(uid.Value); + return true; + } + + public override bool PredictedTrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + EntityUid? mapUid, + ComponentRegistry? overrides = null) + { + if (!TrySpawnInContainer(protoName, container, out uid, mapUid, overrides)) + return false; + + FlagPredicted(uid.Value); + return true; + } + public override EntityUid PredictedSpawnNextToOrDrop(string? protoName, EntityUid target, TransformComponent? xform = null, ComponentRegistry? overrides = null) { var ent = SpawnNextToOrDrop(protoName, target, xform, overrides); @@ -117,6 +144,38 @@ public override EntityUid PredictedSpawnInContainerOrDrop( return ent; } + public override EntityUid PredictedSpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + var ent = SpawnInContainerOrDrop(protoName, container, xform, containerComp, overrides); + + FlagPredicted(ent); + return ent; + } + + public override EntityUid PredictedSpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + out bool inserted, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + var ent = SpawnInContainerOrDrop(protoName, + container, + out inserted, + xform, + containerComp, + overrides); + + FlagPredicted(ent); + return ent; + } + public override void FlagPredicted(Entity ent) { if (!MetaQuery.Resolve(ent.Owner, ref ent.Comp)) diff --git a/Robust.Shared/Containers/SharedContainerSystem.Insert.cs b/Robust.Shared/Containers/SharedContainerSystem.Insert.cs index caf462d85e2..639ca56a61e 100644 --- a/Robust.Shared/Containers/SharedContainerSystem.Insert.cs +++ b/Robust.Shared/Containers/SharedContainerSystem.Insert.cs @@ -136,6 +136,17 @@ public bool Insert(Entity + public bool InsertOrDrop(Entity container, Entity toInsert, + string containerId) + { + if (TryGetContainer(container, containerId, out var baseContainer, container)) + return InsertOrDrop(toInsert, baseContainer, container.Comp2); + + _transform.DropNextTo(toInsert, (container.Owner, container.Comp2)); + return false; + } + /// /// Attempts to insert an entity into a container. If it fails, it will instead drop the entity next to the /// container entity. diff --git a/Robust.Shared/GameObjects/EntityManager.Spawn.cs b/Robust.Shared/GameObjects/EntityManager.Spawn.cs index 046cf3deab5..70679035d82 100644 --- a/Robust.Shared/GameObjects/EntityManager.Spawn.cs +++ b/Robust.Shared/GameObjects/EntityManager.Spawn.cs @@ -7,7 +7,6 @@ using Robust.Shared.Collections; using Robust.Shared.Containers; using Robust.Shared.Maths; -using Robust.Shared.Serialization; namespace Robust.Shared.GameObjects; @@ -145,20 +144,11 @@ public bool TrySpawnNextTo( if (!xform.ParentUid.IsValid()) return false; - if (!_containers.TryGetContainingContainer(target, out var container)) - { - uid = SpawnNextToOrDrop(protoName, target, xform, overrides); - return true; - } - - var doMapInit = _mapSystem.IsInitialized(xform.MapUid); - uid = Spawn(protoName, overrides, doMapInit); - if (_containers.Insert(uid.Value, container)) - return true; + if (_containers.TryGetContainingContainer(target, out var container)) + return TrySpawnInContainer(protoName, container, out uid, xform.MapUid, overrides); - DeleteEntity(uid.Value); - uid = null; - return false; + uid = SpawnNextToOrDrop(protoName, target, xform, overrides); + return true; } public bool TrySpawnInContainer( @@ -170,21 +160,45 @@ public bool TrySpawnInContainer( ComponentRegistry? overrides = null) { uid = null; - if (containerComp == null && !TryGetComponent(containerUid, out containerComp)) - return false; + return _containers.TryGetContainer(containerUid, containerId, out var container, containerComp) + && TrySpawnInContainer(protoName, container, out uid, overrides); + } - if (!containerComp.Containers.TryGetValue(containerId, out var container)) - return false; + public bool TrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + ComponentRegistry? overrides = null) + { + return TrySpawnInContainer(protoName, container, out uid, TransformQuery.Comp(container.Owner).MapUid, overrides); + } - var doMapInit = _mapSystem.IsInitialized(TransformQuery.GetComponent(containerUid).MapUid); - uid = Spawn(protoName, overrides, doMapInit); + /// + /// Attempts to spawn an entity prototype in a container then initialize it once it has been successfully inserted into the container. + /// Deletes the entity if it fails to insert. + /// + /// True if entity was spawned and inserted successfully + public bool TrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + EntityUid? mapUid, + ComponentRegistry? overrides = null) + { + uid = CreateEntityUninitialized(protoName, out var meta, overrides); + InitializeAndStartEntity((uid.Value, meta), doMapInit: false); - if (_containers.Insert(uid.Value, container)) - return true; + if (!_containers.Insert(uid.Value, container)) + { + DeleteEntity(uid); + uid = null; + return false; + } - DeleteEntity(uid.Value); - uid = null; - return false; + if (_mapSystem.IsInitialized(mapUid)) + RunMapInit(uid.Value, meta); + + return true; } public EntityUid SpawnNextToOrDrop(string? protoName, EntityUid target, TransformComponent? xform = null, ComponentRegistry? overrides = null) @@ -193,9 +207,13 @@ public EntityUid SpawnNextToOrDrop(string? protoName, EntityUid target, Transfor if (!xform.ParentUid.IsValid()) return Spawn(protoName); - var doMapInit = _mapSystem.IsInitialized(xform.MapUid); - var uid = Spawn(protoName, overrides, doMapInit); + var uid = CreateEntityUninitialized(protoName, out var meta, overrides); + InitializeAndStartEntity((uid, meta), doMapInit: false); _xforms.DropNextTo(uid, target); + + if (_mapSystem.IsInitialized(xform.MapUid)) + RunMapInit(uid, meta); + return uid; } @@ -219,19 +237,43 @@ public EntityUid SpawnInContainerOrDrop( ContainerManagerComponent? containerComp = null, ComponentRegistry? overrides = null) { - inserted = true; - xform ??= TransformQuery.GetComponent(containerUid); - var doMapInit = _mapSystem.IsInitialized(xform.MapUid); - var uid = Spawn(protoName, overrides, doMapInit); + xform ??= TransformQuery.Comp(containerUid); + var uid = CreateEntityUninitialized(protoName, out var meta, overrides); + InitializeAndStartEntity((uid, meta), doMapInit: false); - if ((containerComp == null && !TryGetComponent(containerUid, out containerComp)) - || !containerComp.Containers.TryGetValue(containerId, out var container) - || !_containers.Insert(uid, container)) - { - inserted = false; - if (xform.ParentUid.IsValid()) - _xforms.DropNextTo(uid, (containerUid, xform)); - } + inserted = _containers.InsertOrDrop((containerUid, containerComp, xform), uid, containerId); + + if (_mapSystem.IsInitialized(xform.MapUid)) + RunMapInit(uid, meta); + + return uid; + } + + public EntityUid SpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + return SpawnInContainerOrDrop(protoName, container, out _, xform, containerComp, overrides); + } + + public EntityUid SpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + out bool inserted, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + xform ??= TransformQuery.Comp(container.Owner); + var uid = CreateEntityUninitialized(protoName, out var meta, overrides); + InitializeAndStartEntity((uid, meta), doMapInit: false); + + inserted = _containers.InsertOrDrop(uid, container); + if (_mapSystem.IsInitialized(xform.MapUid)) + RunMapInit(uid, meta); return uid; } @@ -284,6 +326,25 @@ public virtual bool PredictedTrySpawnInContainer( return TrySpawnInContainer(protoName, containerUid, containerId, out uid, containerComp, overrides); } + public virtual bool PredictedTrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + ComponentRegistry? overrides = null) + { + return TrySpawnInContainer(protoName, container, out uid, overrides); + } + + public virtual bool PredictedTrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + EntityUid? mapUid, + ComponentRegistry? overrides = null) + { + return TrySpawnInContainer(protoName, container, out uid, mapUid, overrides); + } + public virtual EntityUid PredictedSpawnNextToOrDrop(string? protoName, EntityUid target, TransformComponent? xform = null, ComponentRegistry? overrides = null) { return SpawnNextToOrDrop(protoName, target, xform, overrides); @@ -318,6 +379,32 @@ public virtual EntityUid PredictedSpawnInContainerOrDrop( overrides); } + public virtual EntityUid PredictedSpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + return SpawnInContainerOrDrop(protoName, container, xform, containerComp, overrides); + } + + public virtual EntityUid PredictedSpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + out bool inserted, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + return SpawnInContainerOrDrop(protoName, + container, + out inserted, + xform, + containerComp, + overrides); + } + /// /// Flags an entity as being a predicted spawn and should be deleted when its corresponding tick comes in. /// diff --git a/Robust.Shared/GameObjects/EntitySystem.Proxy.cs b/Robust.Shared/GameObjects/EntitySystem.Proxy.cs index 8a8c7d380f6..ec9760661e8 100644 --- a/Robust.Shared/GameObjects/EntitySystem.Proxy.cs +++ b/Robust.Shared/GameObjects/EntitySystem.Proxy.cs @@ -1004,7 +1004,7 @@ protected EntityUid SpawnAttachedTo(string? prototype, EntityCoordinates coordin protected EntityUid SpawnAtPosition(string? prototype, EntityCoordinates coordinates, ComponentRegistry? overrides = null) => EntityManager.SpawnAtPosition(prototype, coordinates, overrides); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [ProxyFor(typeof(EntityManager))] protected bool TrySpawnInContainer( @@ -1018,6 +1018,18 @@ protected bool TrySpawnInContainer( return EntityManager.TrySpawnInContainer(protoName, containerUid, containerId, out uid, containerComp, overrides); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected bool TrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null) + { + return EntityManager.TrySpawnInContainer(protoName, container, out uid, overrides); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [ProxyFor(typeof(EntityManager))] @@ -1043,7 +1055,7 @@ protected EntityUid SpawnNextToOrDrop( return EntityManager.SpawnNextToOrDrop(protoName, target, xform, overrides); } - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [ProxyFor(typeof(EntityManager))] protected EntityUid SpawnInContainerOrDrop( @@ -1057,6 +1069,18 @@ protected EntityUid SpawnInContainerOrDrop( return EntityManager.SpawnInContainerOrDrop(protoName, containerUid, containerId, xform, container, overrides); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected EntityUid SpawnInContainerOrDrop( + string? protoName, + BaseContainer baseContainer, + TransformComponent? xform = null, + ContainerManagerComponent? container = null, + ComponentRegistry? overrides = null) + { + return EntityManager.SpawnInContainerOrDrop(protoName, baseContainer, xform, container, overrides); + } + #endregion #region PredictedSpawning @@ -1079,7 +1103,7 @@ protected EntityUid PredictedSpawnAttachedTo(string? prototype, EntityCoordinate protected EntityUid PredictedSpawnAtPosition(string? prototype, EntityCoordinates coordinates, ComponentRegistry? overrides = null) => EntityManager.PredictedSpawnAtPosition(prototype, coordinates, overrides); - /// + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [ProxyFor(typeof(EntityManager))] protected bool PredictedTrySpawnInContainer( @@ -1093,6 +1117,29 @@ protected bool PredictedTrySpawnInContainer( return EntityManager.PredictedTrySpawnInContainer(protoName, containerUid, containerId, out uid, containerComp, overrides); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected bool PredictedTrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + ComponentRegistry? overrides = null) + { + return EntityManager.PredictedTrySpawnInContainer(protoName, container, out uid, overrides); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected bool PredictedTrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + EntityUid? mapUid, + ComponentRegistry? overrides = null) + { + return EntityManager.PredictedTrySpawnInContainer(protoName, container, out uid, mapUid, overrides); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [ProxyFor(typeof(EntityManager))] @@ -1132,6 +1179,18 @@ protected EntityUid PredictedSpawnInContainerOrDrop( return EntityManager.PredictedSpawnInContainerOrDrop(protoName, containerUid, containerId, xform, container, overrides); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected EntityUid PredictedSpawnInContainerOrDrop( + string? protoName, + BaseContainer baseContainer, + TransformComponent? xform = null, + ContainerManagerComponent? container = null, + ComponentRegistry? overrides = null) + { + return EntityManager.PredictedSpawnInContainerOrDrop(protoName, baseContainer, xform, container, overrides); + } + #endregion #region Utils diff --git a/Robust.Shared/GameObjects/IEntityManager.Spawn.cs b/Robust.Shared/GameObjects/IEntityManager.Spawn.cs index 9a973cb4f94..2b537523386 100644 --- a/Robust.Shared/GameObjects/IEntityManager.Spawn.cs +++ b/Robust.Shared/GameObjects/IEntityManager.Spawn.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using Robust.Shared.Collections; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Maths; @@ -60,6 +59,21 @@ bool TrySpawnInContainer( ContainerManagerComponent? containerComp = null, ComponentRegistry? overrides = null); + /// + bool TrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + ComponentRegistry? overrides = null); + + /// + bool TrySpawnInContainer( + string? protoName, + BaseContainer container, + [NotNullWhen(true)] out EntityUid? uid, + EntityUid? mapUid, + ComponentRegistry? overrides = null); + /// /// Attempts to spawn an entity inside of a container. If it fails to insert into the container, it will /// instead drop the entity next to the target (see ). @@ -82,6 +96,23 @@ EntityUid SpawnInContainerOrDrop( ContainerManagerComponent? containerComp = null, ComponentRegistry? overrides = null); + /// + EntityUid SpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null); + + /// + EntityUid SpawnInContainerOrDrop( + string? protoName, + BaseContainer container, + out bool inserted, + TransformComponent? xform = null, + ContainerManagerComponent? containerComp = null, + ComponentRegistry? overrides = null); + /// /// Attempts to spawn an entity adjacent to some other target entity. If the target entity is in /// a container, this will attempt to insert the spawned entity into the same container. If the insertion fails, diff --git a/Robust.Shared/GameObjects/MapInitEvent.cs b/Robust.Shared/GameObjects/MapInitEvent.cs index dcb3ac249b6..a823872dd14 100644 --- a/Robust.Shared/GameObjects/MapInitEvent.cs +++ b/Robust.Shared/GameObjects/MapInitEvent.cs @@ -1,7 +1,7 @@ namespace Robust.Shared.GameObjects; /// -/// Raised directed on an entity when the map is initialized. +/// Raised directed on an entity when the map has been initialized and the entity has been successfully reparented. /// [ComponentEvent(Exclusive = false)] public sealed class MapInitEvent : EntityEventArgs