mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 18:31:17 +03:00
* Status-effect-cloning * review * Update tags.yml * TraitStatusEffectDebuff * different approach perhaps --------- Co-authored-by: ScarKy0 <scarky0@onet.eu>
173 lines
7 KiB
C#
173 lines
7 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using Content.Shared.Implants.Components;
|
|
using Content.Shared.Inventory;
|
|
using Content.Shared.StatusEffectNew.Components;
|
|
using Content.Shared.Storage;
|
|
using Content.Shared.Whitelist;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Shared.Cloning;
|
|
|
|
public abstract partial class SharedCloningSystem : EntitySystem
|
|
{
|
|
[Dependency] private StatusEffectNew.StatusEffectsSystem _statusEffects = default!; //TODO: This system has to support both the old and new status effect systems, until the old is able to be fully removed.
|
|
[Dependency] private EntityQuery<CloneableStatusEffectComponent> _cloneableEffectQuery = default!;
|
|
[Dependency] private EntityWhitelistSystem _whitelist = default!;
|
|
|
|
/// <summary>
|
|
/// Spawns a clone of the given humanoid mob at the specified location or in nullspace.
|
|
/// </summary>
|
|
public virtual bool TryCloning(
|
|
EntityUid original,
|
|
MapCoordinates? coords,
|
|
ProtoId<CloningSettingsPrototype> settingsId,
|
|
[NotNullWhen(true)] out EntityUid? clone)
|
|
{
|
|
clone = null;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy components from one entity to another based on a CloningSettingsPrototype.
|
|
/// </summary>
|
|
/// <param name="original">The orignal Entity to clone components from.</param>
|
|
/// <param name="clone">The target Entity to clone components to.</param>
|
|
/// <param name="settings">The clone settings prototype id containing the list of components to clone.</param>
|
|
public virtual void CloneComponents(
|
|
EntityUid original,
|
|
EntityUid clone,
|
|
ProtoId<CloningSettingsPrototype> settings)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy components from one entity to another based on a CloningSettingsPrototype.
|
|
/// </summary>
|
|
/// <param name="original">The orignal Entity to clone components from.</param>
|
|
/// <param name="clone">The target Entity to clone components to.</param>
|
|
/// <param name="settings">The clone settings prototype containing the list of components to clone.</param>
|
|
public virtual void CloneComponents(
|
|
EntityUid original,
|
|
EntityUid clone,
|
|
CloningSettingsPrototype settings)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copies the equipment the original has to the clone.
|
|
/// This uses the original prototype of the items, so any changes to components that are done after spawning are lost!
|
|
/// </summary>
|
|
public virtual void CopyEquipment(
|
|
Entity<InventoryComponent?> original,
|
|
Entity<InventoryComponent?> clone,
|
|
SlotFlags slotFlags,
|
|
EntityWhitelist? whitelist = null,
|
|
EntityWhitelist? blacklist = null)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copies an item and its storage recursively, placing all items at the same position in grid storage.
|
|
/// This uses the original prototype of the items, so any changes to components that are done after spawning are lost!
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This is not perfect and only considers item in storage containers.
|
|
/// Some components have their own additional spawn logic on map init, so we cannot just copy all containers.
|
|
/// </remarks>
|
|
public virtual EntityUid? CopyItem(
|
|
EntityUid original,
|
|
EntityCoordinates coords,
|
|
EntityWhitelist? whitelist = null,
|
|
EntityWhitelist? blacklist = null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copies an item's storage recursively to another storage.
|
|
/// The storage grids should have the same shape or it will drop on the floor.
|
|
/// Basically the same as CopyItem, but we don't copy the outermost container.
|
|
/// </summary>
|
|
public virtual void CopyStorage(
|
|
Entity<StorageComponent?> original,
|
|
Entity<StorageComponent?> target,
|
|
EntityWhitelist? whitelist = null,
|
|
EntityWhitelist? blacklist = null)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copies all implants from one mob to another.
|
|
/// Might result in duplicates if the target already has them.
|
|
/// Can copy the storage inside a storage implant according to a whitelist and blacklist.
|
|
/// </summary>
|
|
/// <param name="original">Entity to copy implants from.</param>
|
|
/// <param name="target">Entity to copy implants to.</param>
|
|
/// <param name="copyStorage">If true will copy storage of the implants (E.g storage implant)</param>
|
|
/// <param name="whitelist">Whitelist for the storage copy (If copyStorage is true)</param>
|
|
/// <param name="blacklist">Blacklist for the storage copy (If copyStorage is true)</param>
|
|
public virtual void CopyImplants(
|
|
Entity<ImplantedComponent?> original,
|
|
EntityUid target,
|
|
bool copyStorage = false,
|
|
EntityWhitelist? whitelist = null,
|
|
EntityWhitelist? blacklist = null)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scans all permanent status effects applied to the original entity and transfers them to the clone.
|
|
/// </summary>
|
|
/// <param name="original">The entity to take status effects from</param>
|
|
/// <param name="target">The entity to copy the status effects to.</param>
|
|
/// <param name="whitelist">The whitelist the status effects need to be in to get copied.</param>
|
|
/// <param name="blacklist">The blacklist the status effects cannot be in to get copied.</param>
|
|
/// <param name="removeMissing">Whether to remove clonable status effects from the target before applying new ones.</param>
|
|
public void CopyStatusEffects(
|
|
Entity<StatusEffectContainerComponent?> original,
|
|
Entity<StatusEffectContainerComponent?> target,
|
|
EntityWhitelist? whitelist = null,
|
|
EntityWhitelist? blacklist = null,
|
|
bool removeMissing = true)
|
|
{
|
|
if (removeMissing)
|
|
{
|
|
foreach (var effect in _statusEffects.EnumerateStatusEffects(target, _cloneableEffectQuery))
|
|
{
|
|
if (effect.Comp1.EndEffectTime is not null)
|
|
continue;
|
|
|
|
// Don't delete status effects that were never in the whitelist.
|
|
if (!_whitelist.CheckBoth(effect.Owner, blacklist, whitelist))
|
|
continue;
|
|
|
|
var effectProto = Prototype(effect);
|
|
|
|
if (effectProto is null)
|
|
continue;
|
|
|
|
// Remove all status effects we do not need anymore.
|
|
// We clone permanent ones, so we assume we replace them with a new set of permanent ones.
|
|
_statusEffects.TryRemoveStatusEffect(target, effectProto);
|
|
}
|
|
}
|
|
|
|
foreach (var effect in _statusEffects.EnumerateStatusEffects(original, _cloneableEffectQuery))
|
|
{
|
|
// We are not interested in temporary effects, only permanent ones.
|
|
if (effect.Comp1.EndEffectTime is not null)
|
|
continue;
|
|
|
|
if (!_whitelist.CheckBoth(effect.Owner, blacklist, whitelist))
|
|
continue;
|
|
|
|
var effectProto = Prototype(effect);
|
|
|
|
if (effectProto is null)
|
|
continue;
|
|
|
|
_statusEffects.TrySetStatusEffectDuration(target, effectProto);
|
|
}
|
|
}
|
|
}
|