diff --git a/Content.Server/Dragon/DragonComponent.cs b/Content.Server/Dragon/DragonComponent.cs index c8e7fffe7b..d8bcac9db5 100644 --- a/Content.Server/Dragon/DragonComponent.cs +++ b/Content.Server/Dragon/DragonComponent.cs @@ -5,6 +5,7 @@ using Content.Shared.Actions; using Content.Shared.Chemistry.Reagent; using Content.Shared.Sound; using Content.Shared.Storage; +using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -57,14 +58,23 @@ namespace Content.Server.Dragon public SoundSpecifier? SoundDeath = new SoundPathSpecifier("/Audio/Animals/space_dragon_roar.ogg"); [ViewVariables(VVAccess.ReadWrite), DataField("soundDevour")] - public SoundSpecifier? SoundDevour = new SoundPathSpecifier("/Audio/Effects/demon_consume.ogg"); + public SoundSpecifier? SoundDevour = new SoundPathSpecifier("/Audio/Effects/demon_consume.ogg") + { + Params = AudioParams.Default.WithVolume(-3f), + }; [ViewVariables(VVAccess.ReadWrite), DataField("soundStructureDevour")] - public SoundSpecifier? SoundStructureDevour = new SoundPathSpecifier("/Audio/Machines/airlock_creaking.ogg"); + public SoundSpecifier? SoundStructureDevour = new SoundPathSpecifier("/Audio/Machines/airlock_creaking.ogg") + { + Params = AudioParams.Default.WithVolume(-3f), + }; [ViewVariables(VVAccess.ReadWrite), DataField("soundRoar")] public SoundSpecifier? SoundRoar = - new SoundPathSpecifier("/Audio/Animals/space_dragon_roar.ogg"); + new SoundPathSpecifier("/Audio/Animals/space_dragon_roar.ogg") + { + Params = AudioParams.Default.WithVolume(-3f), + }; public CancellationTokenSource? CancelToken; diff --git a/Content.Server/Dragon/DragonSystem.cs b/Content.Server/Dragon/DragonSystem.cs index 22fac2f6e1..c92a9359d3 100644 --- a/Content.Server/Dragon/DragonSystem.cs +++ b/Content.Server/Dragon/DragonSystem.cs @@ -31,10 +31,11 @@ namespace Content.Server.Dragon base.Initialize(); SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnDragonDevourComplete); SubscribeLocalEvent(OnDevourAction); SubscribeLocalEvent(OnDragonSpawnAction); - SubscribeLocalEvent(OnDragonDevourComplete); + SubscribeLocalEvent(OnDragonStructureDevourComplete); SubscribeLocalEvent(OnDragonDevourCancelled); SubscribeLocalEvent(OnMobStateChanged); } @@ -46,7 +47,7 @@ namespace Content.Server.Dragon if (args.CurrentMobState.IsDead()) { if (component.SoundDeath != null) - SoundSystem.Play(component.SoundDeath.GetSound(), Filter.Pvs(uid, entityManager: EntityManager)); + SoundSystem.Play(component.SoundDeath.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, component.SoundDeath.Params); component.DragonStomach.EmptyContainer(); } @@ -58,13 +59,36 @@ namespace Content.Server.Dragon } private void OnDragonDevourComplete(EntityUid uid, DragonComponent component, DragonDevourComplete args) + { + var ichorInjection = new Solution(component.DevourChem, component.DevourHealRate); + + //Humanoid devours allow dragon to get eggs, corpses included + if (EntityManager.HasComponent(args.Target)) + { + // Add a spawn for a consumed humanoid + component.SpawnsLeft = Math.Min(component.SpawnsLeft + 1, component.MaxSpawns); + } + //Non-humanoid mobs can only heal dragon for half the normal amount, with no additional spawn tickets + else + { + ichorInjection.ScaleSolution(0.5f); + } + + _bloodstreamSystem.TryAddToChemicals(uid, ichorInjection); + component.DragonStomach.Insert(args.Target); + + if (component.SoundDevour != null) + SoundSystem.Play(component.SoundDevour.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, component.SoundDevour.Params); + } + + private void OnDragonStructureDevourComplete(EntityUid uid, DragonComponent component, DragonStructureDevourComplete args) { component.CancelToken = null; //TODO: Figure out a better way of removing structures via devour that still entails standing still and waiting for a DoAfter. Somehow. EntityManager.QueueDeleteEntity(args.Target); if (component.SoundDevour != null) - SoundSystem.Play(component.SoundDevour.GetSound(), Filter.Pvs(args.User, entityManager: EntityManager)); + SoundSystem.Play(component.SoundDevour.GetSound(), Filter.Pvs(args.User, entityManager: EntityManager), uid, component.SoundDevour.Params); } private void OnStartup(EntityUid uid, DragonComponent component, ComponentStartup args) @@ -82,7 +106,7 @@ namespace Content.Server.Dragon _actionsSystem.AddAction(uid, component.SpawnAction, null); if (component.SoundRoar != null) - SoundSystem.Play(component.SoundRoar.GetSound(), Filter.Pvs(uid, 4f, EntityManager)); + SoundSystem.Play(component.SoundRoar.GetSound(), Filter.Pvs(uid, 4f, EntityManager), uid, component.SoundRoar.Params); } /// @@ -94,38 +118,25 @@ namespace Content.Server.Dragon args.Handled = true; var target = args.Target; - var ichorInjection = new Solution(component.DevourChem, component.DevourHealRate); - - //Check if the target is valid. The effects should be possible to accomplish on either a wall or a body. - //Eating bodies is instant, the wall requires a doAfter. + // Structure and mob devours handled differently. if (EntityManager.TryGetComponent(target, out MobStateComponent? targetState)) { switch (targetState.CurrentState) { case SharedCriticalMobState: case SharedDeadMobState: - if (!EntityManager.HasComponent(dragonuid)) return; + component.CancelToken = new CancellationTokenSource(); - //Humanoid devours allow dragon to get eggs, corpses included - if (EntityManager.HasComponent(target)) + _doAfterSystem.DoAfter(new DoAfterEventArgs(dragonuid, component.DevourTime, component.CancelToken.Token, target) { - // Add a spawn for a consumed humanoid - component.SpawnsLeft = Math.Min(component.SpawnsLeft + 1, component.MaxSpawns); - } - //Non-humanoid mobs can only heal dragon for half the normal amount, with no additional spawn tickets - else - { - ichorInjection.ScaleSolution(0.5f); - } - - _bloodstreamSystem.TryAddToChemicals(dragonuid, ichorInjection); - component.DragonStomach.Insert(target); - - if (component.SoundDevour != null) - SoundSystem.Play(component.SoundDevour.GetSound(), Filter.Pvs(dragonuid, entityManager: EntityManager)); - - return; + UserFinishedEvent = new DragonStructureDevourComplete(dragonuid, target), + UserCancelledEvent = new DragonDevourCancelledEvent(), + BreakOnTargetMove = true, + BreakOnUserMove = true, + BreakOnStun = true, + }); + break; default: _popupSystem.PopupEntity(Loc.GetString("devour-action-popup-message-fail-target-alive"), dragonuid, Filter.Entities(dragonuid)); break; @@ -141,13 +152,13 @@ namespace Content.Server.Dragon _popupSystem.PopupEntity(Loc.GetString("devour-action-popup-message-structure"), dragonuid, Filter.Entities(dragonuid)); if (component.SoundStructureDevour != null) - SoundSystem.Play(component.SoundStructureDevour.GetSound(), Filter.Pvs(dragonuid, entityManager: EntityManager)); + SoundSystem.Play(component.SoundStructureDevour.GetSound(), Filter.Pvs(dragonuid, entityManager: EntityManager), dragonuid, component.SoundStructureDevour.Params); component.CancelToken = new CancellationTokenSource(); _doAfterSystem.DoAfter(new DoAfterEventArgs(dragonuid, component.DevourTime, component.CancelToken.Token, target) { - UserFinishedEvent = new DragonDevourComplete(dragonuid, target), + UserFinishedEvent = new DragonStructureDevourComplete(dragonuid, target), UserCancelledEvent = new DragonDevourCancelledEvent(), BreakOnTargetMove = true, BreakOnUserMove = true, @@ -177,6 +188,18 @@ namespace Content.Server.Dragon public EntityUid Target { get; } public DragonDevourComplete(EntityUid user, EntityUid target) + { + User = user; + Target = target; + } + } + + private sealed class DragonStructureDevourComplete : EntityEventArgs + { + public EntityUid User { get; } + public EntityUid Target { get; } + + public DragonStructureDevourComplete(EntityUid user, EntityUid target) { User = user; Target = target; diff --git a/Resources/Audio/Animals/space_dragon_roar.ogg b/Resources/Audio/Animals/space_dragon_roar.ogg index f7f4503b89..1f63d18e4b 100644 Binary files a/Resources/Audio/Animals/space_dragon_roar.ogg and b/Resources/Audio/Animals/space_dragon_roar.ogg differ