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(OnDoAfter); SubscribeLocalEvent(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); } }