Files
tbd-station-14/Content.Server/Devour/DevourSystem.cs
Sparlight 2c3c510fe9 Fix non-humanoid mobs being destroyed on devour (#38087)
* Allow non-preference living things to be added to a devourer's stomach

* Fix ordering of devour logic

* Minor refactor for whitelist on storage and food preference

* Fix linter issue

* Coerce workflow to run again; also fix bad indenting error

* Code review changes
2025-07-09 14:43:35 +02:00

63 lines
2.5 KiB
C#

using Content.Server.Body.Systems;
using Content.Shared.Body.Events;
using Content.Shared.Chemistry.Components;
using Content.Shared.Devour;
using Content.Shared.Devour.Components;
using Content.Shared.Whitelist;
namespace Content.Server.Devour;
public sealed class DevourSystem : SharedDevourSystem
{
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
[Dependency] private readonly EntityWhitelistSystem _entityWhitelistSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DevourerComponent, DevourDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<DevourerComponent, BeingGibbedEvent>(OnGibContents);
}
private void OnDoAfter(EntityUid uid, DevourerComponent component, DevourDoAfterEvent args)
{
if (args.Handled || args.Cancelled)
return;
var ichorInjection = new Solution(component.Chemical, component.HealRate);
// Grant ichor if the devoured thing meets the dragon's food preference
if (args.Args.Target != null && _entityWhitelistSystem.IsWhitelistPassOrNull(component.FoodPreferenceWhitelist, (EntityUid)args.Args.Target))
{
_bloodstreamSystem.TryAddToChemicals(uid, ichorInjection);
}
// If the devoured thing meets the stomach whitelist criteria, add it to the stomach
if (args.Args.Target != null && _entityWhitelistSystem.IsWhitelistPass(component.StomachStorageWhitelist, (EntityUid)args.Args.Target))
{
ContainerSystem.Insert(args.Args.Target.Value, component.Stomach);
}
//TODO: Figure out a better way of removing structures via devour that still entails standing still and waiting for a DoAfter. Somehow.
//If it's not alive, it must be a structure.
// Delete if the thing isn't in the stomach storage whitelist (or the stomach whitelist is null/empty)
else if (args.Args.Target != null)
{
QueueDel(args.Args.Target.Value);
}
_audioSystem.PlayPvs(component.SoundDevour, uid);
}
private void OnGibContents(EntityUid uid, DevourerComponent component, ref BeingGibbedEvent args)
{
if (component.StomachStorageWhitelist == null)
return;
// For some reason we have two different systems that should handle gibbing,
// and for some another reason GibbingSystem, which should empty all containers, doesn't get involved in this process
ContainerSystem.EmptyContainer(component.Stomach);
}
}