CatStation/Content.Shared/EntityEffects/Effects/Body/RemoveOrgansEntityEffectSystem.cs
AndrewFenriz 53e29ab962
Move admin smites to prototypes (#45550)
* Add prototype-backed admin verb framework

* Add reusable admin verb operations

* Add smite-specific admin operations

* Migrate admin smites to prototypes

* More docs for god of docs

* We dont have prediction here, so...

* Final cleanup

* Fix adminSmite

* Add segment display control

* Add generic thermoregulator

* Add thermobath systems

* Replace hotplate with thermobath

* Refine thermobath layout

* move simple smites to effects

* move comps to effects

* move add action to effect

* move add mind role to effect

* move add user interfaces to effect

* move godmode to effect

* move eye zoom to effect

* move speed swap to effect

* move spill bloodstream to effect

* move remove organs to effect

* move cream pie to effect

* move slip to effect

* fix server effect usings

* move homing rod to effect

* move locker stuff to effect

* move tabletop dimension to effect

* move pinball to effect

* move yeet to effect

* move silicon laws to effect

* move ghost kick to effect

* remove admin operations

* revert sht

* remove BOM

* use admin verb prototypes for smites

* add heart attack smite prototype

* docs update

* fix AdminSmiteVomitOrgans

* split and move to shared

* move to shared

* move to shared and predict

* PredictedQueueDel

* fix Popup

* fix HomingRod

* port DeleteEntityEntityEffectSystem

* fix StuffIntoLockerEntityEffectSystem

* upd

* fix eye

* fix movement

* fix!!

* fix and doc

* Add admin verb category prototype

* upd AdminVerbPrototype

* split verbs

* SuperSuperSuperBonk

* Update PopupMessageEntityEffectSystem.cs

* fields

---------

Co-authored-by: Pok245 <113675512+Pok27@users.noreply.github.com>
2026-09-18 19:01:16 +00:00

93 lines
2.9 KiB
C#

using Content.Shared.Body;
using Content.Shared.Whitelist;
using Robust.Shared.Prototypes;
namespace Content.Shared.EntityEffects.Effects.Body;
/// <summary>
/// Drops or deletes organs matching the category and entity filters.
/// </summary>
/// <inheritdoc cref="EntityEffectSystem{T, TEffect}"/>
public sealed partial class RemoveOrgansEntityEffectSystem : EntityEffectSystem<BodyComponent, RemoveOrgans>
{
[Dependency] private BodySystem _body = default!;
[Dependency] private SharedTransformSystem _transform = default!;
[Dependency] private EntityWhitelistSystem _whitelist = default!;
protected override void Effect(Entity<BodyComponent> entity, ref EntityEffectEvent<RemoveOrgans> args)
{
var categories = args.Effect.Categories;
var excludedCategories = args.Effect.ExcludedCategories;
var maxCount = args.Effect.MaxCount;
var delete = args.Effect.Delete;
if (maxCount is <= 0)
return;
var selected = new List<EntityUid>();
foreach (var organ in _body.EnumerateOrgans<TransformComponent>(entity.AsNullable()))
{
if (!_whitelist.CheckBoth(organ, args.Effect.Blacklist, args.Effect.Whitelist))
continue;
var category = organ.Comp1.Category;
if (categories != null && (category == null || !categories.Contains(category.Value)))
continue;
if (category != null && excludedCategories.Contains(category.Value))
continue;
selected.Add(organ);
if (selected.Count == maxCount)
break;
}
foreach (var organ in selected)
{
if (delete)
PredictedQueueDel(organ);
else
_transform.AttachToGridOrMap(organ);
}
}
}
/// <inheritdoc cref="EntityEffect"/>
public sealed partial class RemoveOrgans : EntityEffectBase<RemoveOrgans>
{
/// <summary>
/// Categories to remove. Null allows any category, including uncategorized organs.
/// </summary>
[DataField]
public HashSet<ProtoId<OrganCategoryPrototype>>? Categories;
/// <summary>
/// Categories to keep, even if included in Categories.
/// </summary>
[DataField]
public HashSet<ProtoId<OrganCategoryPrototype>> ExcludedCategories = [];
/// <summary>
/// Additional filter for the organs, not the body.
/// </summary>
[DataField]
public EntityWhitelist? Whitelist;
/// <summary>
/// Organs to keep regardless of the other filters.
/// </summary>
[DataField]
public EntityWhitelist? Blacklist;
/// <summary>
/// Delete selected organs instead of dropping them.
/// </summary>
[DataField]
public bool Delete;
/// <summary>
/// Maximum number to remove in body enumeration order. Null removes all matches; zero or less removes none.
/// </summary>
[DataField]
public int? MaxCount;
}