From fdba05d96fe05ef8fa0f3a611e531d4a933481dc Mon Sep 17 00:00:00 2001 From: Milon Date: Mon, 10 Feb 2025 03:01:42 +0100 Subject: [PATCH] maybe works? --- .../GameObjects/EntityManager.Components.cs | 37 ++++++++++++------- .../GameObjects/IEntityManager.Components.cs | 12 +++--- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Robust.Shared/GameObjects/EntityManager.Components.cs b/Robust.Shared/GameObjects/EntityManager.Components.cs index 71016d49b7e..6e52e0450e6 100644 --- a/Robust.Shared/GameObjects/EntityManager.Components.cs +++ b/Robust.Shared/GameObjects/EntityManager.Components.cs @@ -1029,47 +1029,56 @@ public bool TryGetComponent([NotNullWhen(true)] EntityUid? uid, ushort netId, } /// - public bool CopyComponent(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? metadataTarget = null) where T : IComponent + public bool CopyComponent(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? meta = null) where T : IComponent { component = default; - if (!MetaQuery.Resolve(target, ref metadataTarget, false)) - throw new ArgumentException($"Entity {target} is not valid.", nameof(target)); + if (!MetaQuery.Resolve(target, ref meta)) + return false; - if (!HasComponent(source)) + if (!TryGetComponent(source, out var sourceComp)) return false; - var sourceComp = GetComponent(source); var compReg = ComponentFactory.GetRegistration(typeof(T)); component = (T)ComponentFactory.GetComponent(compReg); _serManager.CopyTo(sourceComp, ref component, notNullableOverride: true); - AddComponentInternal(target, component, compReg, true, false, metadataTarget); + AddComponentInternal(target, component, compReg, true, false, meta); return true; } /// - public bool CopyComponent(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? metadataTarget = null) + public bool CopyComponent(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? meta = null) { - DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type), $"Type {type} is not a component"); + DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type) && type != typeof(IComponent), $"Invalid component type: {type}"); + + var method = GetType() + .GetMethod(nameof(CopyComponent), [typeof(EntityUid), typeof(EntityUid), type, typeof(MetaDataComponent) + ]); + + var genericMethod = method!.MakeGenericMethod(); - var success = CopyComponent(source, target, out var baseComponent, metadataTarget); - component = baseComponent; + if (method == null) + throw new InvalidOperationException($"Could not create generic method for type {type}"); + + var parameters = new object?[] { source, target, null, meta }; + var success = (bool)genericMethod.Invoke(this, [source, target, type, meta])!; + component = (IComponent?)parameters[2]; return success; } /// - public bool CopyComponents(EntityUid source, EntityUid target, MetaDataComponent? metadataTarget = null, params Type[] types) + public bool CopyComponents(EntityUid source, EntityUid target, MetaDataComponent? meta = null, params Type[] types) { - if (!MetaQuery.Resolve(target, ref metadataTarget, false)) - throw new ArgumentException($"Entity {target} is not valid.", nameof(target)); + if (!MetaQuery.Resolve(target, ref meta)) + return false; var allSuccessful = true; foreach (var type in types) { - if (!CopyComponent(source, target, type, out _, metadataTarget)) + if (!CopyComponent(source, target, type, out _, meta)) allSuccessful = false; } diff --git a/Robust.Shared/GameObjects/IEntityManager.Components.cs b/Robust.Shared/GameObjects/IEntityManager.Components.cs index 7c9e77aab7d..d2fe4a214bb 100644 --- a/Robust.Shared/GameObjects/IEntityManager.Components.cs +++ b/Robust.Shared/GameObjects/IEntityManager.Components.cs @@ -349,9 +349,9 @@ public partial interface IEntityManager /// The source entity to copy from /// The target entity to copy to /// The copied component if successful - /// Optional metadata of the target entity + /// Optional metadata of the target entity /// Whether the component was successfully copied - bool CopyComponent(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? metadataTarget = null) where T : IComponent; + bool CopyComponent(EntityUid source, EntityUid target, [NotNullWhen(true)] out T? component, MetaDataComponent? meta = null) where T : IComponent; /// /// Copy a single component from source to target entity and return a reference to the copied component. @@ -360,19 +360,19 @@ public partial interface IEntityManager /// The target entity to copy the component to /// The type of component to copy /// The copied component if successful - /// Optional metadata of the target entity + /// Optional metadata of the target entity /// Whether the component was successfully copied - bool CopyComponent(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? metadataTarget = null); + bool CopyComponent(EntityUid source, EntityUid target, Type type, [NotNullWhen(true)] out IComponent? component, MetaDataComponent? meta = null); /// /// Copy multiple components from source to target entity. /// /// The source entity to copy from /// The target entity to copy to - /// Optional metadata of the target entity + /// Optional metadata of the target entity /// Array of component types to copy /// Whether all components were successfully copied - bool CopyComponents(EntityUid source, EntityUid target, MetaDataComponent? metadataTarget = null, params Type[] types); + bool CopyComponents(EntityUid source, EntityUid target, MetaDataComponent? meta = null, params Type[] types); /// /// Returns a cached struct enumerator with the specified component.