diff --git a/Content.Server/Damage/Commands/GodModeCommand.cs b/Content.Server/Damage/Commands/GodModeCommand.cs index 84dbb22128..4445ea7390 100644 --- a/Content.Server/Damage/Commands/GodModeCommand.cs +++ b/Content.Server/Damage/Commands/GodModeCommand.cs @@ -1,4 +1,5 @@ using Content.Server.Administration; +using Content.Server.Damage.Systems; using Content.Shared.Administration; using Robust.Server.Player; using Robust.Shared.Console; diff --git a/Content.Server/Damage/Components/DamageOnLandComponent.cs b/Content.Server/Damage/Components/DamageOnLandComponent.cs index 5beb3331f4..5d9b1118c9 100644 --- a/Content.Server/Damage/Components/DamageOnLandComponent.cs +++ b/Content.Server/Damage/Components/DamageOnLandComponent.cs @@ -1,44 +1,28 @@ using Content.Shared.Damage; -using Content.Shared.Damage.Components; -using Content.Shared.Throwing; using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; -using Robust.Shared.Prototypes; -using Robust.Shared.IoC; using Robust.Shared.ViewVariables; namespace Content.Server.Damage.Components { [RegisterComponent] - public class DamageOnLandComponent : Component, ILand + public sealed class DamageOnLandComponent : Component { public override string Name => "DamageOnLand"; [DataField("amount")] [ViewVariables(VVAccess.ReadWrite)] - private int _amount = 1; + public int Amount = 1; [DataField("ignoreResistances")] [ViewVariables(VVAccess.ReadWrite)] - private bool _ignoreResistances; + public bool IgnoreResistances; // TODO PROTOTYPE Replace this datafield variable with prototype references, once they are supported. // Also remove Initialize override, if no longer needed. - [DataField("damageType")] - private readonly string _damageTypeID = "Blunt"; + [DataField("damageType")] public readonly string DamageTypeId = "Blunt"; + [ViewVariables(VVAccess.ReadWrite)] public DamageTypePrototype DamageType = default!; - protected override void Initialize() - { - base.Initialize(); - DamageType = IoCManager.Resolve().Index(_damageTypeID); - } - - void ILand.Land(LandEventArgs eventArgs) - { - if (!Owner.TryGetComponent(out IDamageableComponent? damageable)) - return; - damageable.TryChangeDamage(DamageType, _amount, _ignoreResistances); - } } } diff --git a/Content.Server/Damage/Components/DamageOtherOnHitComponent.cs b/Content.Server/Damage/Components/DamageOtherOnHitComponent.cs index ec04d76358..ed005d5ef4 100644 --- a/Content.Server/Damage/Components/DamageOtherOnHitComponent.cs +++ b/Content.Server/Damage/Components/DamageOtherOnHitComponent.cs @@ -1,3 +1,4 @@ +using Content.Server.Damage.Systems; using Content.Shared.Damage; using Robust.Shared.Analyzers; using Robust.Shared.GameObjects; diff --git a/Content.Server/Damage/DamageOnHighSpeedImpactSystem.cs b/Content.Server/Damage/Systems/DamageOnHighSpeedImpactSystem.cs similarity index 97% rename from Content.Server/Damage/DamageOnHighSpeedImpactSystem.cs rename to Content.Server/Damage/Systems/DamageOnHighSpeedImpactSystem.cs index 3d2dd3b301..752e227f45 100644 --- a/Content.Server/Damage/DamageOnHighSpeedImpactSystem.cs +++ b/Content.Server/Damage/Systems/DamageOnHighSpeedImpactSystem.cs @@ -11,7 +11,7 @@ using Robust.Shared.Player; using Robust.Shared.Random; using Robust.Shared.Timing; -namespace Content.Server.Damage +namespace Content.Server.Damage.Systems { [UsedImplicitly] internal sealed class DamageOnHighSpeedImpactSystem: EntitySystem diff --git a/Content.Server/Damage/Systems/DamageOnLandSystem.cs b/Content.Server/Damage/Systems/DamageOnLandSystem.cs new file mode 100644 index 0000000000..49e89a8fec --- /dev/null +++ b/Content.Server/Damage/Systems/DamageOnLandSystem.cs @@ -0,0 +1,35 @@ +using Content.Server.Damage.Components; +using Content.Shared.Damage; +using Content.Shared.Damage.Components; +using Content.Shared.Throwing; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Prototypes; + +namespace Content.Server.Damage.Systems +{ + public sealed class DamageOnLandSystem : EntitySystem + { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(HandleInit); + SubscribeLocalEvent(DamageOnLand); + } + + private void HandleInit(EntityUid uid, DamageOnLandComponent component, ComponentInit args) + { + component.DamageType = _protoManager.Index(component.DamageTypeId); + } + + private void DamageOnLand(EntityUid uid, DamageOnLandComponent component, LandEvent args) + { + if (!ComponentManager.TryGetComponent(uid, out var damageable)) + return; + + damageable.TryChangeDamage(component.DamageType, component.Amount, component.IgnoreResistances); + } + } +} diff --git a/Content.Server/Damage/DamageOtherOnHitSystem.cs b/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs similarity index 94% rename from Content.Server/Damage/DamageOtherOnHitSystem.cs rename to Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs index 27323162d9..419f0838da 100644 --- a/Content.Server/Damage/DamageOtherOnHitSystem.cs +++ b/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs @@ -3,7 +3,7 @@ using Content.Shared.Damage.Components; using Content.Shared.Throwing; using Robust.Shared.GameObjects; -namespace Content.Server.Damage +namespace Content.Server.Damage.Systems { public class DamageOtherOnHitSystem : EntitySystem { diff --git a/Content.Server/Damage/GodmodeSystem.cs b/Content.Server/Damage/Systems/GodmodeSystem.cs similarity index 99% rename from Content.Server/Damage/GodmodeSystem.cs rename to Content.Server/Damage/Systems/GodmodeSystem.cs index f80aaa28ce..8abf07a104 100644 --- a/Content.Server/Damage/GodmodeSystem.cs +++ b/Content.Server/Damage/Systems/GodmodeSystem.cs @@ -7,7 +7,7 @@ using Content.Shared.GameTicking; using JetBrains.Annotations; using Robust.Shared.GameObjects; -namespace Content.Server.Damage +namespace Content.Server.Damage.Systems { [UsedImplicitly] public class GodmodeSystem : EntitySystem diff --git a/Content.Server/Light/Components/LightBulbComponent.cs b/Content.Server/Light/Components/LightBulbComponent.cs index 342dc41303..740faca969 100644 --- a/Content.Server/Light/Components/LightBulbComponent.cs +++ b/Content.Server/Light/Components/LightBulbComponent.cs @@ -33,11 +33,8 @@ namespace Content.Server.Light.Components /// Component that represents a light bulb. Can be broken, or burned, which turns them mostly useless. /// [RegisterComponent] - public class LightBulbComponent : Component, ILand, IBreakAct + public class LightBulbComponent : Component, IBreakAct { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IRobustRandom _random = default!; - /// /// Invoked whenever the state of the light bulb changes. /// @@ -121,12 +118,6 @@ namespace Content.Server.Light.Components UpdateColor(); } - void ILand.Land(LandEventArgs eventArgs) - { - PlayBreakSound(); - State = LightBulbState.Broken; - } - public void OnBreak(BreakageEventArgs eventArgs) { State = LightBulbState.Broken; diff --git a/Content.Server/Light/EntitySystems/LightBulbSystem.cs b/Content.Server/Light/EntitySystems/LightBulbSystem.cs new file mode 100644 index 0000000000..79c5c1285c --- /dev/null +++ b/Content.Server/Light/EntitySystems/LightBulbSystem.cs @@ -0,0 +1,21 @@ +using Content.Server.Light.Components; +using Content.Shared.Throwing; +using Robust.Shared.GameObjects; + +namespace Content.Server.Light.EntitySystems +{ + public sealed class LightBulbSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(HandleLand); + } + + private void HandleLand(EntityUid uid, LightBulbComponent component, LandEvent args) + { + component.PlayBreakSound(); + component.State = LightBulbState.Broken; + } + } +} diff --git a/Content.Server/Nutrition/Components/DrinkComponent.cs b/Content.Server/Nutrition/Components/DrinkComponent.cs index b1c565e963..e87fca3009 100644 --- a/Content.Server/Nutrition/Components/DrinkComponent.cs +++ b/Content.Server/Nutrition/Components/DrinkComponent.cs @@ -12,15 +12,12 @@ using Content.Shared.Interaction.Helpers; using Content.Shared.Notification.Managers; using Content.Shared.Nutrition.Components; using Content.Shared.Sound; -using Content.Shared.Throwing; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Player; -using Robust.Shared.Random; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; @@ -28,10 +25,8 @@ using Robust.Shared.ViewVariables; namespace Content.Server.Nutrition.Components { [RegisterComponent] - public class DrinkComponent : Component, IUse, IAfterInteract, IExamine, ILand + public class DrinkComponent : Component, IUse, IAfterInteract, IExamine { - [Dependency] private readonly IRobustRandom _random = default!; - [DataField("solution")] public string SolutionName { get; set; } = DefaultSolutionName; public const string DefaultSolutionName = "drink"; @@ -81,10 +76,10 @@ namespace Content.Server.Nutrition.Components [DataField("openSounds")] private SoundSpecifier _openSounds = new SoundCollectionSpecifier("canOpenSounds"); - [DataField("pressurized")] - private bool _pressurized = default; - [DataField("burstSound")] - private SoundSpecifier _burstSound = new SoundPathSpecifier("/Audio/Effects/flash_bang.ogg"); + + [DataField("pressurized")] public bool Pressurized; + + [DataField("burstSound")] public SoundSpecifier BurstSound = new SoundPathSpecifier("/Audio/Effects/flash_bang.ogg"); private void OpenedChanged() { @@ -233,22 +228,5 @@ namespace Content.Server.Nutrition.Components return true; } - - void ILand.Land(LandEventArgs eventArgs) - { - if (_pressurized && - !Opened && - _random.Prob(0.25f) && - EntitySystem.Get().TryGetDrainableSolution(Owner.Uid, out var interactions)) - { - Opened = true; - - var solution = EntitySystem.Get() - .Drain(Owner.Uid, interactions, interactions.DrainAvailable); - solution.SpillAt(Owner, "PuddleSmear"); - - SoundSystem.Play(Filter.Pvs(Owner), _burstSound.GetSound(), Owner, AudioParams.Default.WithVolume(-4)); - } - } } } diff --git a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs index 3a0eaaf02d..2b5f7fb0d8 100644 --- a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs @@ -1,15 +1,21 @@ -using Content.Server.Nutrition.Components; +using Content.Server.Fluids.Components; +using Content.Server.Nutrition.Components; using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Throwing; using JetBrains.Annotations; +using Robust.Shared.Audio; using Robust.Shared.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Player; +using Robust.Shared.Random; namespace Content.Server.Nutrition.EntitySystems { [UsedImplicitly] public class DrinkSystem : EntitySystem { + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; public override void Initialize() @@ -18,6 +24,25 @@ namespace Content.Server.Nutrition.EntitySystems SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnDrinkInit); + SubscribeLocalEvent(HandleLand); + } + + private void HandleLand(EntityUid uid, DrinkComponent component, LandEvent args) + { + if (component.Pressurized && + !component.Opened && + _random.Prob(0.25f) && + _solutionContainerSystem.TryGetDrainableSolution(uid, out var interactions)) + { + component.Opened = true; + + var entity = EntityManager.GetEntity(uid); + + var solution = _solutionContainerSystem.Drain(uid, interactions, interactions.DrainAvailable); + solution.SpillAt(entity, "PuddleSmear"); + + SoundSystem.Play(Filter.Pvs(entity), component.BurstSound.GetSound(), entity, AudioParams.Default.WithVolume(-4)); + } } private void OnDrinkInit(EntityUid uid, DrinkComponent component, ComponentInit args) diff --git a/Content.Shared/Throwing/ILand.cs b/Content.Shared/Throwing/LandEvent.cs similarity index 56% rename from Content.Shared/Throwing/ILand.cs rename to Content.Shared/Throwing/LandEvent.cs index 449ec198bf..550f4d0f61 100644 --- a/Content.Shared/Throwing/ILand.cs +++ b/Content.Shared/Throwing/LandEvent.cs @@ -1,37 +1,14 @@ -using System; using JetBrains.Annotations; -using Robust.Shared.Analyzers; using Robust.Shared.GameObjects; using Robust.Shared.Map; namespace Content.Shared.Throwing { - /// - /// This interface gives components behavior when landing after being thrown. - /// - [RequiresExplicitImplementation] - public interface ILand - { - void Land(LandEventArgs eventArgs); - } - - public class LandEventArgs : EventArgs - { - public LandEventArgs(IEntity? user, EntityCoordinates landingLocation) - { - User = user; - LandingLocation = landingLocation; - } - - public IEntity? User { get; } - public EntityCoordinates LandingLocation { get; } - } - /// /// Raised when an entity that was thrown lands. /// [PublicAPI] - public class LandEvent : HandledEntityEventArgs + public sealed class LandEvent : EntityEventArgs { /// /// Entity that threw the item. diff --git a/Content.Shared/Throwing/ThrownItemSystem.cs b/Content.Shared/Throwing/ThrownItemSystem.cs index 6636a889f9..8a3d645ae0 100644 --- a/Content.Shared/Throwing/ThrownItemSystem.cs +++ b/Content.Shared/Throwing/ThrownItemSystem.cs @@ -124,25 +124,8 @@ namespace Content.Shared.Throwing var user = thrownItem.Thrower; var coordinates = landing.Transform.Coordinates; - // LandInteraction - // TODO: Refactor these to system messages var landMsg = new LandEvent(user, landing, coordinates); RaiseLocalEvent(landing.Uid, landMsg); - if (landMsg.Handled) - { - return; - } - - var comps = landing.GetAllComponents().ToArray(); - var landArgs = new LandEventArgs(user, coordinates); - - // Call Land on all components that implement the interface - foreach (var comp in comps) - { - if (landing.Deleted) break; - comp.Land(landArgs); - } - ComponentManager.RemoveComponent(landing.Uid, thrownItem); }