diff --git a/Content.Server/GameObjects/Components/Fluids/SpillableComponent.cs b/Content.Server/GameObjects/Components/Fluids/SpillableComponent.cs index 55e71cc63e..cf1306980f 100644 --- a/Content.Server/GameObjects/Components/Fluids/SpillableComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/SpillableComponent.cs @@ -3,13 +3,14 @@ using Content.Shared.GameObjects.Components.Chemistry; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Content.Shared.GameObjects.Verbs; using Content.Shared.Interfaces; +using Content.Shared.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; using Robust.Shared.Localization; namespace Content.Server.GameObjects.Components.Fluids { [RegisterComponent] - public class SpillableComponent : Component + public class SpillableComponent : Component, IDropped { public override string Name => "Spillable"; @@ -51,11 +52,17 @@ namespace Content.Server.GameObjects.Components.Fluids } // Need this as when we split the component's owner may be deleted - var entityLocation = component.Owner.Transform.Coordinates; - var solution = solutionComponent.Drain(solutionComponent.DrainAvailable); - solution.SpillAt(entityLocation, "PuddleSmear"); + solutionComponent.Drain(solutionComponent.DrainAvailable).SpillAt(component.Owner.Transform.Coordinates, "PuddleSmear"); } } } + + void IDropped.Dropped(DroppedEventArgs eventArgs) + { + if (!eventArgs.Intentional && Owner.TryGetComponent(out ISolutionInteractionsComponent solutionComponent)) + { + solutionComponent.Drain(solutionComponent.DrainAvailable).SpillAt(Owner.Transform.Coordinates, "PuddleSmear"); + } + } } } diff --git a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs index dbbfd9790a..0902075b57 100644 --- a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs @@ -252,18 +252,19 @@ namespace Content.Server.GameObjects.Components.GUI /// /// The itemcomponent of the item to be dropped /// Check if the item can be dropped + /// If the item was dropped intentionally /// True if IDropped.Dropped was called, otherwise false - private bool DroppedInteraction(ItemComponent item, bool doMobChecks) + private bool DroppedInteraction(ItemComponent item, bool doMobChecks, bool intentional) { var interactionSystem = _entitySystemManager.GetEntitySystem(); if (doMobChecks) { - if (!interactionSystem.TryDroppedInteraction(Owner, item.Owner)) + if (!interactionSystem.TryDroppedInteraction(Owner, item.Owner, intentional)) return false; } else { - interactionSystem.DroppedInteraction(Owner, item.Owner); + interactionSystem.DroppedInteraction(Owner, item.Owner, intentional); } return true; } @@ -284,7 +285,7 @@ namespace Content.Server.GameObjects.Components.GUI return false; } - public bool Drop(string slot, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true) + public bool Drop(string slot, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true) { var hand = GetHand(slot); if (!CanDrop(slot, doMobChecks) || hand?.Entity == null) @@ -302,7 +303,7 @@ namespace Content.Server.GameObjects.Components.GUI _entitySystemManager.GetEntitySystem().UnequippedHandInteraction(Owner, item.Owner, ToSharedHand(hand)); - if (doDropInteraction && !DroppedInteraction(item, false)) + if (doDropInteraction && !DroppedInteraction(item, false, intentional)) return false; item.RemovedFromSlot(); @@ -325,7 +326,7 @@ namespace Content.Server.GameObjects.Components.GUI } - public bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true) + public bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true) { if (slot == null) { @@ -363,7 +364,7 @@ namespace Content.Server.GameObjects.Components.GUI _entitySystemManager.GetEntitySystem().UnequippedHandInteraction(Owner, item.Owner, ToSharedHand(hand)); - if (doDropInteraction && !DroppedInteraction(item, doMobChecks)) + if (doDropInteraction && !DroppedInteraction(item, doMobChecks, intentional)) return false; item.RemovedFromSlot(); @@ -379,7 +380,7 @@ namespace Content.Server.GameObjects.Components.GUI return true; } - public bool Drop(IEntity entity, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true) + public bool Drop(IEntity entity, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true) { if (entity == null) { @@ -391,15 +392,15 @@ namespace Content.Server.GameObjects.Components.GUI throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity)); } - return Drop(slot, coords, doMobChecks, doDropInteraction); + return Drop(slot, coords, doMobChecks, doDropInteraction, intentional); } - public bool Drop(string slot, bool mobChecks = true, bool doDropInteraction = true) + public bool Drop(string slot, bool mobChecks = true, bool doDropInteraction = true, bool intentional = true) { - return Drop(slot, Owner.Transform.Coordinates, mobChecks, doDropInteraction); + return Drop(slot, Owner.Transform.Coordinates, mobChecks, doDropInteraction, intentional); } - public bool Drop(IEntity entity, bool mobChecks = true, bool doDropInteraction = true) + public bool Drop(IEntity entity, bool mobChecks = true, bool doDropInteraction = true, bool intentional = true) { if (entity == null) { @@ -411,10 +412,10 @@ namespace Content.Server.GameObjects.Components.GUI throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity)); } - return Drop(slot, Owner.Transform.Coordinates, mobChecks, doDropInteraction); + return Drop(slot, Owner.Transform.Coordinates, mobChecks, doDropInteraction, intentional); } - public bool Drop(IEntity entity, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true) + public bool Drop(IEntity entity, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true) { if (entity == null) { @@ -426,7 +427,7 @@ namespace Content.Server.GameObjects.Components.GUI throw new ArgumentException("Entity must be held in one of our hands.", nameof(entity)); } - return Drop(slot, targetContainer, doMobChecks, doDropInteraction); + return Drop(slot, targetContainer, doMobChecks, doDropInteraction, intentional); } /// diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index 90c3b2b852..b513339e49 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -716,11 +716,11 @@ namespace Content.Server.GameObjects.EntitySystems.Click /// Activates the Dropped behavior of an object /// Verifies that the user is capable of doing the drop interaction first /// - public bool TryDroppedInteraction(IEntity user, IEntity item) + public bool TryDroppedInteraction(IEntity user, IEntity item, bool intentional) { if (user == null || item == null || !ActionBlockerSystem.CanDrop(user)) return false; - DroppedInteraction(user, item); + DroppedInteraction(user, item, intentional); return true; } @@ -728,9 +728,9 @@ namespace Content.Server.GameObjects.EntitySystems.Click /// Calls Dropped on all components that implement the IDropped interface /// on an entity that has been dropped. /// - public void DroppedInteraction(IEntity user, IEntity item) + public void DroppedInteraction(IEntity user, IEntity item, bool intentional) { - var dropMsg = new DroppedMessage(user, item); + var dropMsg = new DroppedMessage(user, item, intentional); RaiseLocalEvent(dropMsg); if (dropMsg.Handled) { @@ -742,7 +742,7 @@ namespace Content.Server.GameObjects.EntitySystems.Click // Call Land on all components that implement the interface foreach (var comp in comps) { - comp.Dropped(new DroppedEventArgs(user)); + comp.Dropped(new DroppedEventArgs(user, intentional)); } } diff --git a/Content.Server/GameObjects/EntitySystems/StandingStateSystem.cs b/Content.Server/GameObjects/EntitySystems/StandingStateSystem.cs index bc89e19e76..87230a7ebe 100644 --- a/Content.Server/GameObjects/EntitySystems/StandingStateSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/StandingStateSystem.cs @@ -57,7 +57,7 @@ namespace Content.Server.GameObjects.EntitySystems foreach (var heldItem in hands.GetAllHeldItems()) { - hands.Drop(heldItem.Owner, doMobChecks); + hands.Drop(heldItem.Owner, doMobChecks, intentional:false); } } diff --git a/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs b/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs index 58173ca102..0fd2196616 100644 --- a/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs +++ b/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs @@ -110,7 +110,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True on success, false if something blocked the drop. - bool Drop(string slot, bool mobChecks = true, bool doDropInteraction = true); + bool Drop(string slot, bool mobChecks = true, bool doDropInteraction = true, bool intentional = true); /// /// Drops an item held by one of our hand slots to the same position as our owning entity. @@ -125,7 +125,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// /// Thrown if is not actually held in any hand. /// - bool Drop(IEntity entity, bool mobChecks = true, bool doDropInteraction = true); + bool Drop(IEntity entity, bool mobChecks = true, bool doDropInteraction = true, bool intentional = true); /// /// Drops the item in a slot. @@ -135,7 +135,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True if an item was dropped, false otherwise. - bool Drop(string slot, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true); + bool Drop(string slot, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true); /// /// Drop the specified entity in our hands to a certain position. @@ -158,7 +158,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// /// Thrown if is not actually held in any hand. /// - bool Drop(IEntity entity, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true); + bool Drop(IEntity entity, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true); /// /// Drop the item contained in a slot into another container. @@ -173,7 +173,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// but practical remove or insert returned false anyways. /// This is an edge-case that is currently unhandled. /// - bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true); + bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true); /// /// Drops an item in one of the hands into a container. @@ -194,7 +194,7 @@ namespace Content.Server.Interfaces.GameObjects.Components.Items /// /// Thrown if is not actually held in any hand. /// - bool Drop(IEntity entity, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true); + bool Drop(IEntity entity, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true, bool intentional = true); /// /// Checks whether the item in the specified hand can be dropped. diff --git a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IDropped.cs b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IDropped.cs index 041587b71f..29dbad1753 100644 --- a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IDropped.cs +++ b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IDropped.cs @@ -16,12 +16,15 @@ namespace Content.Shared.Interfaces.GameObjects.Components public class DroppedEventArgs : EventArgs { - public DroppedEventArgs(IEntity user) + public DroppedEventArgs(IEntity user, bool intentional) { User = user; + Intentional = intentional; } public IEntity User { get; } + + public bool Intentional { get; } } /// @@ -45,10 +48,16 @@ namespace Content.Shared.Interfaces.GameObjects.Components /// public IEntity Dropped { get; } - public DroppedMessage(IEntity user, IEntity dropped) + /// + /// If the item was dropped intentionally. + /// + public bool Intentional { get; } + + public DroppedMessage(IEntity user, IEntity dropped, bool intentional) { User = user; Dropped = dropped; + Intentional = intentional; } } }