From a4ced5f1fc97c7a9f3b1d98879a5bb741739a138 Mon Sep 17 00:00:00 2001 From: ike709 Date: Fri, 3 Jul 2020 16:26:13 -0500 Subject: [PATCH 01/18] Fixes being able to drink a closed drink (#1257) --- .../GameObjects/Components/Nutrition/DrinkComponent.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs index 79081b27db..712f01130b 100644 --- a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs @@ -128,6 +128,7 @@ namespace Content.Server.GameObjects.Components.Nutrition if (!_opened) { target.PopupMessage(target, Loc.GetString("Open it first!")); + return false; } if (_contents.CurrentVolume.Float() <= 0) From c1ba2f76c7ffd95a9e391b9bd67ef1a2f7ef7b31 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Fri, 3 Jul 2020 23:26:30 +0200 Subject: [PATCH 02/18] Fix crash when reentering a body (#1258) --- Content.Client/EntryPoint.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index 9e8172d4cf..28c04b08a2 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -125,7 +125,10 @@ namespace Content.Client /// public static void DetachPlayerFromEntity(EntityDetachedEventArgs eventArgs) { - eventArgs.OldEntity.RemoveComponent(); + if (!eventArgs.OldEntity.Deleted) + { + eventArgs.OldEntity.RemoveComponent(); + } } public override void PostInit() From 77368886e96334130ae3f0376038fb1de3e1bf7a Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Fri, 3 Jul 2020 23:26:49 +0200 Subject: [PATCH 03/18] Fix Urist McHands' constant aspirations to follow in Pablo Picasso's steps (#1259) --- Resources/Prototypes/Entities/Mobs/Player/human.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 8995218961..129866f5bd 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -2,7 +2,6 @@ save: false name: Urist McHands parent: BaseHumanMob_Content - abstract: true id: HumanMob_Content description: A miserable pile of secrets drawdepth: Mobs @@ -17,4 +16,4 @@ zoom: 0.5, 0.5 - type: CameraRecoil - type: Examiner - - type: HumanInventoryController \ No newline at end of file + - type: HumanInventoryController From 68a515ee0919f0a3bc2eeaf7a6c31ab27b231c60 Mon Sep 17 00:00:00 2001 From: Jackw2As Date: Fri, 3 Jul 2020 22:27:52 +0100 Subject: [PATCH 04/18] Adds Damage on tool interaction component (#1060) (#1102) Fixed issue with Welding Tool ignoring the tools list. --- .../Damage/DamageOnToolInteractComponent.cs | 67 +++++++++++++++++++ .../Storage/StorageTanks/fuel_tank.yml | 5 ++ 2 files changed, 72 insertions(+) create mode 100644 Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs diff --git a/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs b/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs new file mode 100644 index 0000000000..4f66b92807 --- /dev/null +++ b/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs @@ -0,0 +1,67 @@ +using Content.Server.GameObjects.Components.Interactable; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.Components.Interactable; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization; +using System.Collections.Generic; + +namespace Content.Server.GameObjects.Components.Damage +{ + [RegisterComponent] + class DamageOnToolInteractComponent : Component, IInteractUsing + { + public override string Name => "DamageOnToolInteract"; + + /* Set in YAML */ + protected int Damage; + private List _tools = new List(); + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref Damage, "damage", 0); + + serializer.DataField(ref _tools, "tools", new List()); + } + + public override void Initialize() + { + base.Initialize(); + Owner.EnsureComponent(); + } + + public bool InteractUsing(InteractUsingEventArgs eventArgs) + { + if (eventArgs.Using.TryGetComponent(out var tool)) + { + foreach (var toolQuality in _tools) + { + if (tool.HasQuality(ToolQuality.Welding) && toolQuality == ToolQuality.Welding) + { + if (eventArgs.Using.TryGetComponent(out WelderComponent welder)) + { + if (welder.WelderLit) return CallDamage(eventArgs, tool); + } + break; //If the tool quality is welding and its not lit or its not actually a welder that can be lit then its pointless to continue. + } + + if (tool.HasQuality(toolQuality)) return CallDamage(eventArgs, tool); + } + } + return false; + } + + protected bool CallDamage(InteractUsingEventArgs eventArgs, ToolComponent tool) + { + if (eventArgs.Target.TryGetComponent(out var damageable)) + { + if(tool.HasQuality(ToolQuality.Welding)) damageable.TakeDamage(Shared.GameObjects.DamageType.Heat, Damage, eventArgs.Using, eventArgs.User); + else + damageable.TakeDamage(Shared.GameObjects.DamageType.Brute, Damage, eventArgs.Using, eventArgs.User); + return true; + } + return false; + } + } +} diff --git a/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/fuel_tank.yml b/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/fuel_tank.yml index 0f032dcf45..55a315154b 100644 --- a/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/fuel_tank.yml +++ b/Resources/Prototypes/Entities/Buildings/Storage/StorageTanks/fuel_tank.yml @@ -18,3 +18,8 @@ reagents: - ReagentId: chem.WeldingFuel Quantity: 1500 + - type: DamageOnToolInteract + damage: 200 + tools: + - Welding + From 299b2bda6b6ab80a1c99523e7c65a58ab949dfd3 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Fri, 3 Jul 2020 23:28:17 +0200 Subject: [PATCH 05/18] Fix sandbox panel not reopening properly after being closed by clicking its X (#1260) --- Content.Client/Sandbox/SandboxManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Client/Sandbox/SandboxManager.cs b/Content.Client/Sandbox/SandboxManager.cs index 65559ba958..e20931fd58 100644 --- a/Content.Client/Sandbox/SandboxManager.cs +++ b/Content.Client/Sandbox/SandboxManager.cs @@ -36,7 +36,7 @@ namespace Content.Client.Sandbox private SandboxWindow _window; private EntitySpawnWindow _spawnWindow; private TileSpawnWindow _tilesSpawnWindow; - private bool _sandboxWindowToggled = false; + private bool _sandboxWindowToggled; public void Initialize() { @@ -114,6 +114,7 @@ namespace Content.Client.Sandbox { _window = null; _gameHud.SandboxButtonDown = false; + _sandboxWindowToggled = false; } private void OnRespawnButtonOnOnPressed(BaseButton.ButtonEventArgs args) From 73eb53da467138d27a464cc14bc3f61327bceb6c Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Fri, 3 Jul 2020 23:32:41 +0200 Subject: [PATCH 06/18] Fix a player's mob continuing to move after disconnecting (#1265) --- Content.Client/GameObjects/EntitySystems/MoverSystem.cs | 2 +- Content.Server/GameObjects/EntitySystems/MoverSystem.cs | 7 ++++++- Content.Server/GameTicking/GameTicker.cs | 2 ++ .../GameObjects/Components/Movement/IMoverComponent.cs | 2 +- .../GameObjects/EntitySystems/SharedMoverSystem.cs | 1 - 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Content.Client/GameObjects/EntitySystems/MoverSystem.cs b/Content.Client/GameObjects/EntitySystems/MoverSystem.cs index 0197ed1b97..37689e355c 100644 --- a/Content.Client/GameObjects/EntitySystems/MoverSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/MoverSystem.cs @@ -46,7 +46,7 @@ namespace Content.Client.GameObjects.EntitySystems protected override void SetController(PhysicsComponent physics) { - ((PhysicsComponent)physics).SetController(); + physics.SetController(); } } } diff --git a/Content.Server/GameObjects/EntitySystems/MoverSystem.cs b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs index e1cdd9348f..f33243f5be 100644 --- a/Content.Server/GameObjects/EntitySystems/MoverSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs @@ -79,7 +79,7 @@ namespace Content.Server.GameObjects.EntitySystems protected override void SetController(PhysicsComponent physics) { - ((PhysicsComponent) physics).SetController(); + physics.SetController(); } private static void PlayerAttached(PlayerAttachSystemMessage ev) @@ -96,6 +96,11 @@ namespace Content.Server.GameObjects.EntitySystems { ev.Entity.RemoveComponent(); } + + if (ev.Entity.TryGetComponent(out PhysicsComponent physics)) + { + (physics.Controller as MoverController)?.StopMoving(); + } } protected override void HandleFootsteps(IMoverComponent mover) diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index d5b4715572..4d89eb2351 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -22,6 +22,7 @@ using Content.Shared; using Content.Shared.Chat; using Content.Shared.GameObjects.Components.PDA; using Content.Shared.Jobs; +using Content.Shared.Physics; using Content.Shared.Preferences; using Prometheus; using Robust.Server.Interfaces; @@ -32,6 +33,7 @@ using Robust.Server.ServerStatus; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.Configuration; using Robust.Shared.Interfaces.GameObjects; diff --git a/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs b/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs index 3074a970fd..975a2c6477 100644 --- a/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs +++ b/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs @@ -45,7 +45,7 @@ namespace Content.Shared.GameObjects.Components.Movement /// /// Toggles one of the four cardinal directions. Each of the four directions are - /// composed into a single direction vector, . Enabling + /// composed into a single direction vector, . Enabling /// opposite directions will cancel each other out, resulting in no direction. /// /// Direction to toggle. diff --git a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs index 6df3b87d19..931648c5f1 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs @@ -54,7 +54,6 @@ namespace Content.Shared.GameObjects.EntitySystems base.Shutdown(); } - protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent? collider = null) { From acec6405202cdfdcec3087036902c01c3baf54ec Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 4 Jul 2020 00:50:31 +0200 Subject: [PATCH 07/18] Update submodule --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 2d7192d79d..af4c920606 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 2d7192d79dfc3e74607a66cb1d5bb155ac955ec3 +Subproject commit af4c920606932d0083ef794cdacd1cacb1e3a817 From 7e4b506aaf568e5b16590d3263c6ab6a4868a997 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 5 Jul 2020 20:17:17 +1000 Subject: [PATCH 08/18] Fix AI not using items in hand (#1273) I love 1 character commits Co-authored-by: Metal Gear Sloth --- Content.Server/AI/Operators/Inventory/UseItemInHandsOperator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/AI/Operators/Inventory/UseItemInHandsOperator.cs b/Content.Server/AI/Operators/Inventory/UseItemInHandsOperator.cs index 3e4ed39de8..3c678641ce 100644 --- a/Content.Server/AI/Operators/Inventory/UseItemInHandsOperator.cs +++ b/Content.Server/AI/Operators/Inventory/UseItemInHandsOperator.cs @@ -30,7 +30,7 @@ namespace Content.Server.AI.Operators.Inventory return Outcome.Failed; } - if (_target.TryGetComponent(out ItemComponent itemComponent)) + if (!_target.TryGetComponent(out ItemComponent itemComponent)) { return Outcome.Failed; } From 3bab2fd80329136f5e591b7d207f0bd5387973c2 Mon Sep 17 00:00:00 2001 From: ike709 Date: Mon, 6 Jul 2020 08:45:58 -0500 Subject: [PATCH 09/18] Focus OOC hotkey (#1272) --- Content.Client/Input/ContentContexts.cs | 1 + Content.Client/State/GameScreen.cs | 14 ++++++++++++++ Content.Client/UserInterface/TutorialWindow.cs | 4 +++- Content.Shared/Input/ContentKeyFunctions.cs | 1 + Resources/keybinds.yml | 3 +++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index f9636dc01f..5e54b537dc 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -13,6 +13,7 @@ namespace Content.Client.Input { var common = contexts.GetContext("common"); common.AddFunction(ContentKeyFunctions.FocusChat); + common.AddFunction(ContentKeyFunctions.FocusOOC); common.AddFunction(ContentKeyFunctions.ExamineEntity); common.AddFunction(ContentKeyFunctions.OpenTutorial); common.AddFunction(ContentKeyFunctions.TakeScreenshot); diff --git a/Content.Client/State/GameScreen.cs b/Content.Client/State/GameScreen.cs index 3deb982aae..5d5ff40f04 100644 --- a/Content.Client/State/GameScreen.cs +++ b/Content.Client/State/GameScreen.cs @@ -41,6 +41,9 @@ namespace Content.Client.State _inputManager.SetInputCommand(ContentKeyFunctions.FocusChat, InputCmdHandler.FromDelegate(s => FocusChat(_gameChat))); + + _inputManager.SetInputCommand(ContentKeyFunctions.FocusOOC, + InputCmdHandler.FromDelegate(s => FocusOOC(_gameChat))); } public override void Shutdown() @@ -61,5 +64,16 @@ namespace Content.Client.State chat.Input.IgnoreNext = true; chat.Input.GrabKeyboardFocus(); } + internal static void FocusOOC(ChatBox chat) + { + if (chat == null || chat.UserInterfaceManager.KeyboardFocused != null) + { + return; + } + + chat.Input.IgnoreNext = true; + chat.Input.GrabKeyboardFocus(); + chat.Input.InsertAtCursor("["); + } } } diff --git a/Content.Client/UserInterface/TutorialWindow.cs b/Content.Client/UserInterface/TutorialWindow.cs index af54907d57..ce9362a62c 100644 --- a/Content.Client/UserInterface/TutorialWindow.cs +++ b/Content.Client/UserInterface/TutorialWindow.cs @@ -75,6 +75,7 @@ Open inventory: [color=#a4885c]{7}[/color] Open character window: [color=#a4885c]{8}[/color] Open crafting window: [color=#a4885c]{9}[/color] Focus chat: [color=#a4885c]{10}[/color] +Focus OOC: [color=#a4885c]{26}[/color] Use hand/object in hand: [color=#a4885c]{22}[/color] Do wide attack: [color=#a4885c]{23}[/color] Use targeted entity: [color=#a4885c]{11}[/color] @@ -110,7 +111,8 @@ Toggle sandbox window: [color=#a4885c]{21}[/color]", Key(Use), Key(WideAttack), Key(SmartEquipBackpack), - Key(SmartEquipBelt))); + Key(SmartEquipBelt), + Key(FocusOOC))); //Gameplay VBox.AddChild(new Label { FontOverride = headerFont, Text = "\nGameplay" }); diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs index d44cb1d64d..bdbc7cee49 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -11,6 +11,7 @@ namespace Content.Shared.Input public static readonly BoundKeyFunction Drop = "Drop"; public static readonly BoundKeyFunction ExamineEntity = "ExamineEntity"; public static readonly BoundKeyFunction FocusChat = "FocusChatWindow"; + public static readonly BoundKeyFunction FocusOOC = "FocusOOCWindow"; public static readonly BoundKeyFunction OpenCharacterMenu = "OpenCharacterMenu"; public static readonly BoundKeyFunction OpenContextMenu = "OpenContextMenu"; public static readonly BoundKeyFunction OpenCraftingMenu = "OpenCraftingMenu"; diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index 29388101ed..5c2a9da3c3 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -43,6 +43,9 @@ binds: - function: FocusChatWindow type: State key: T +- function: FocusOOCWindow + type: State + key: LBracket - function: EditorLinePlace type: State key: MouseLeft From 137511d8b972d25c16ac4d4f220fd4470fda632a Mon Sep 17 00:00:00 2001 From: py01 <60152240+collinlunn@users.noreply.github.com> Date: Mon, 6 Jul 2020 07:48:18 -0600 Subject: [PATCH 10/18] NodeGroup remake deferment (#1268) * Remove Unnecessary AnchorUpdate() call * NodeGroupManager * NodeGroupManager issues NodeGroup remake attempts * Code cleanup * NodeGroupManager only stores dirty groups, handles them on next frame * Removes unused NodeGroupManager dependency * Prevents OnRemoveNode from iterating over every connector after the first time * Revert "Prevents OnRemoveNode from iterating over every connector after the first time" This reverts commit c72af4b18d55192af789514f74bef893cf076fbc. * Dependancy warning fix Co-authored-by: py01 --- .../NodeContainer/NodeGroups/INodeGroup.cs | 10 +++-- .../NodeGroups/INodeGroupManager.cs | 37 +++++++++++++++++++ .../Components/NodeContainer/Nodes/Node.cs | 1 - .../EntitySystems/NodeGroupSystem.cs | 19 ++++++++++ Content.Server/ServerContentIoC.cs | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs create mode 100644 Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs index 00a1d32561..ef3dc7aaf1 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroup.cs @@ -1,4 +1,5 @@ using Content.Server.GameObjects.Components.NodeContainer.Nodes; +using Robust.Shared.IoC; using Robust.Shared.ViewVariables; using System.Collections.Generic; @@ -10,7 +11,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups /// public interface INodeGroup { - public IReadOnlyList Nodes { get; } + IReadOnlyList Nodes { get; } void AddNode(Node node); @@ -25,6 +26,8 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups void BeforeRemakeSpread(); void AfterRemakeSpread(); + + void RemakeGroup(); } [NodeGroup(NodeGroupID.Default)] @@ -49,7 +52,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups { _nodes.Remove(node); OnRemoveNode(node); - RemakeGroup(); + IoCManager.Resolve().AddDirtyNodeGroup(this); } public void CombineGroup(INodeGroup newGroup) @@ -73,7 +76,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups /// Causes all s to remake their groups. Called when a is removed /// and may have split a group in two, so multiple new groups may need to be formed. /// - private void RemakeGroup() + public void RemakeGroup() { BeforeRemake(); foreach (var node in Nodes) @@ -116,6 +119,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups public void AfterCombine() { } public void BeforeRemakeSpread() { } public void AfterRemakeSpread() { } + public void RemakeGroup() { } } } } diff --git a/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs new file mode 100644 index 0000000000..762752fb78 --- /dev/null +++ b/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/INodeGroupManager.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups +{ + /// + /// Maintains a set of s that need to be remade with . + /// Defers remaking to reduce recalculations when a group is altered multiple times in a frame. + /// + public interface INodeGroupManager + { + /// + /// Queue up an to be remade. + /// + void AddDirtyNodeGroup(INodeGroup nodeGroup); + + void Update(float frameTime); + } + + public class NodeGroupManager : INodeGroupManager + { + private readonly HashSet _dirtyNodeGroups = new HashSet(); + + public void AddDirtyNodeGroup(INodeGroup nodeGroup) + { + _dirtyNodeGroups.Add(nodeGroup); + } + + public void Update(float frameTime) + { + foreach (var group in _dirtyNodeGroups) + { + group.RemakeGroup(); + } + _dirtyNodeGroups.Clear(); + } + } +} diff --git a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs index 82b1b25950..b0e6cefc40 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs @@ -72,7 +72,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes _deleting = true; if (Owner.TryGetComponent(out var physics)) { - AnchorUpdate(); physics.AnchoredChanged -= AnchorUpdate; } NodeGroup.RemoveNode(this); diff --git a/Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs b/Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs new file mode 100644 index 0000000000..c1c719ad22 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/NodeGroupSystem.cs @@ -0,0 +1,19 @@ +using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.IoC; + +namespace Content.Server.GameObjects.EntitySystems +{ + public class NodeGroupSystem : EntitySystem + { +#pragma warning disable 649 + [Dependency] private readonly INodeGroupManager _groupManager; +#pragma warning restore 649 + + public override void Update(float frameTime) + { + base.Update(frameTime); + _groupManager.Update(frameTime); + } + } +} diff --git a/Content.Server/ServerContentIoC.cs b/Content.Server/ServerContentIoC.cs index 4e58f6379e..5af7382d2c 100644 --- a/Content.Server/ServerContentIoC.cs +++ b/Content.Server/ServerContentIoC.cs @@ -34,6 +34,7 @@ namespace Content.Server IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); } From 90982d8943f0cf6f0ae41b7b9d15c1178184d66f Mon Sep 17 00:00:00 2001 From: Jackson Lewis Date: Mon, 6 Jul 2020 13:00:07 -0700 Subject: [PATCH 11/18] Fix airlock collisions (#1030) Co-authored-by: Pieter-Jan Briers --- .../GameObjects/Components/Doors/ServerDoorComponent.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index 0c424fe17d..29076c4501 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -154,7 +154,7 @@ namespace Content.Server.GameObjects Timer.Spawn(OpenTimeOne, async () => { - collidableComponent.CanCollide = false; + collidableComponent.Hard = false; await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token); @@ -192,14 +192,14 @@ namespace Content.Server.GameObjects public bool Close() { - if (collidableComponent.IsColliding(Vector2.Zero)) + if (collidableComponent.IsColliding(Vector2.Zero, false)) { // Do nothing, somebody's in the door. return false; } State = DoorState.Closing; - collidableComponent.CanCollide = true; + collidableComponent.Hard = true; OpenTimeCounter = 0; SetAppearance(DoorVisualState.Closing); From cee8aaa84c82b5a504c554d53a2b1ec37ec535e4 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 6 Jul 2020 22:53:42 +0200 Subject: [PATCH 12/18] Fix cases of net messages not being registered before being sent. --- Content.Client/ClientPreferencesManager.cs | 1 + Content.Server/EntryPoint.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Client/ClientPreferencesManager.cs b/Content.Client/ClientPreferencesManager.cs index c7abc9b5f9..298ba8e80d 100644 --- a/Content.Client/ClientPreferencesManager.cs +++ b/Content.Client/ClientPreferencesManager.cs @@ -26,6 +26,7 @@ namespace Content.Client { _netManager.RegisterNetMessage(nameof(MsgPreferencesAndSettings), HandlePreferencesAndSettings); + _netManager.RegisterNetMessage(nameof(MsgUpdateCharacter)); } public void SelectCharacter(ICharacterProfile profile) diff --git a/Content.Server/EntryPoint.cs b/Content.Server/EntryPoint.cs index c16c0fb636..b7220dc612 100644 --- a/Content.Server/EntryPoint.cs +++ b/Content.Server/EntryPoint.cs @@ -61,6 +61,7 @@ namespace Content.Server IoCManager.Resolve().StartInit(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); + IoCManager.Resolve().Initialize(); } public override void PostInit() @@ -69,7 +70,6 @@ namespace Content.Server IoCManager.Resolve().FinishInit(); _gameTicker.Initialize(); - IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); From c019d428a750dbacbbdd37c630a814479f4e9247 Mon Sep 17 00:00:00 2001 From: ike709 Date: Mon, 6 Jul 2020 16:24:29 -0500 Subject: [PATCH 13/18] Antag preferences and antag prototype (#1264) Co-authored-by: Pieter-Jan Briers --- .../UserInterface/HumanoidProfileEditor.cs | 97 ++++++++- .../20200706172726_Antags.Designer.cs | 185 ++++++++++++++++++ .../Postgres/20200706172726_Antags.cs | 43 ++++ ...stgresPreferencesDbContextModelSnapshot.cs | 31 +++ .../Sqlite/20200706172741_Antags.Designer.cs | 178 +++++++++++++++++ .../Sqlite/20200706172741_Antags.cs | 42 ++++ ...SqlitePreferencesDbContextModelSnapshot.cs | 30 +++ Content.Server.Database/Model.cs | 14 ++ Content.Server.Database/PrefsDb.cs | 5 +- Content.Server/GameTicking/GamePreset.cs | 2 + .../GamePresets/PresetSuspicion.cs | 55 +++++- .../GameTicking/GameRules/RuleSuspicion.cs | 4 +- Content.Server/GameTicking/GameTicker.cs | 22 ++- Content.Server/Mobs/Role.cs | 2 +- Content.Server/Mobs/Roles/Job.cs | 2 +- .../Mobs/Roles/SuspicionInnocentRole.cs | 16 +- .../Mobs/Roles/SuspicionTraitorRole.cs | 18 +- Content.Server/PDA/PDAUplinkManager.cs | 2 +- .../Preferences/PreferencesDatabase.cs | 8 +- .../Preferences/HumanoidCharacterProfile.cs | 64 ++++-- Content.Shared/Roles/AntagPrototype.cs | 48 +++++ .../{Jobs => Roles}/JobPrototype.cs | 0 .../{Jobs => Roles}/StartingGearPrototype.cs | 0 .../Preferences/PreferencesDatabaseTests.cs | 3 +- .../Antags/Suspicion/SuspicionInnocent.yml | 6 + .../Antags/Suspicion/SuspicionTraitor.yml | 6 + .../Jobs/Cargo/CargoTechnician.yml | 0 .../{ => Roles}/Jobs/Civilian/Assistant.yml | 0 .../{ => Roles}/Jobs/Civilian/Bartender.yml | 0 .../{ => Roles}/Jobs/Civilian/Chef.yml | 0 .../{ => Roles}/Jobs/Civilian/Clown.yml | 0 .../{ => Roles}/Jobs/Civilian/Janitor.yml | 0 .../{ => Roles}/Jobs/Command/captain.yml | 0 .../Jobs/Command/head_of_personnel.yml | 0 .../Jobs/Engineering/chief_engineer.yml | 0 .../Jobs/Engineering/station_engineer.yml | 0 .../Jobs/Medical/chief_medical_officer.yml | 0 .../Jobs/Medical/medical_doctor.yml | 0 .../Jobs/Science/research_director.yml | 0 .../{ => Roles}/Jobs/Science/scientist.yml | 0 .../Jobs/Security/head_of_security.yml | 0 .../Jobs/Security/security_officer.yml | 0 42 files changed, 833 insertions(+), 50 deletions(-) create mode 100644 Content.Server.Database/Migrations/Postgres/20200706172726_Antags.Designer.cs create mode 100644 Content.Server.Database/Migrations/Postgres/20200706172726_Antags.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.Designer.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.cs create mode 100644 Content.Shared/Roles/AntagPrototype.cs rename Content.Shared/{Jobs => Roles}/JobPrototype.cs (100%) rename Content.Shared/{Jobs => Roles}/StartingGearPrototype.cs (100%) create mode 100644 Resources/Prototypes/Roles/Antags/Suspicion/SuspicionInnocent.yml create mode 100644 Resources/Prototypes/Roles/Antags/Suspicion/SuspicionTraitor.yml rename Resources/Prototypes/{ => Roles}/Jobs/Cargo/CargoTechnician.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Civilian/Assistant.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Civilian/Bartender.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Civilian/Chef.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Civilian/Clown.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Civilian/Janitor.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Command/captain.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Command/head_of_personnel.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Engineering/chief_engineer.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Engineering/station_engineer.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Medical/chief_medical_officer.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Medical/medical_doctor.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Science/research_director.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Science/scientist.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Security/head_of_security.yml (100%) rename Resources/Prototypes/{ => Roles}/Jobs/Security/security_officer.yml (100%) diff --git a/Content.Client/UserInterface/HumanoidProfileEditor.cs b/Content.Client/UserInterface/HumanoidProfileEditor.cs index 83e0492885..7a6f5f33d4 100644 --- a/Content.Client/UserInterface/HumanoidProfileEditor.cs +++ b/Content.Client/UserInterface/HumanoidProfileEditor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Content.Client.GameObjects.Components; @@ -6,6 +6,7 @@ using Content.Client.Interfaces; using Content.Client.Utility; using Content.Shared; using Content.Shared.Jobs; +using Content.Shared.Antags; using Content.Shared.Preferences; using Robust.Client.Graphics.Drawing; using Robust.Client.UserInterface; @@ -42,6 +43,7 @@ namespace Content.Client.UserInterface private readonly FacialHairStylePicker _facialHairPicker; private readonly List _jobPriorities; private readonly OptionButton _preferenceUnavailableButton; + private readonly List _antagPreferences; private bool _isDirty; public int CharacterSlot; @@ -320,6 +322,52 @@ namespace Content.Client.UserInterface #endregion + #region Antags + + { + var antagList = new VBoxContainer(); + + var antagVBox = new VBoxContainer + { + Children = + { + new ScrollContainer + { + SizeFlagsVertical = SizeFlags.FillExpand, + Children = + { + antagList + } + } + } + }; + + tabContainer.AddChild(antagVBox); + + tabContainer.SetTabTitle(2, Loc.GetString("Antags")); + + _antagPreferences = new List(); + + foreach (var antag in prototypeManager.EnumeratePrototypes().OrderBy(a => a.Name)) + { + if(!antag.SetPreference) + { + continue; + } + var selector = new AntagPreferenceSelector(antag); + antagList.AddChild(selector); + _antagPreferences.Add(selector); + + selector.PreferenceChanged += preference => + { + Profile = Profile.WithAntagPreference(antag.ID, preference); + IsDirty = true; + }; + } + } + + #endregion + var rightColumn = new VBoxContainer(); middleContainer.AddChild(rightColumn); @@ -466,6 +514,7 @@ namespace Content.Client.UserInterface UpdateHairPickers(); UpdateSaveButton(); UpdateJobPriorities(); + UpdateAntagPreferences(); _preferenceUnavailableButton.SelectId((int) Profile.PreferenceUnavailable); } @@ -533,5 +582,51 @@ namespace Content.Client.UserInterface }); } } + + private void UpdateAntagPreferences() + { + foreach (var preferenceSelector in _antagPreferences) + { + var antagId = preferenceSelector.Antag.ID; + + var preference = Profile.AntagPreferences.Contains(antagId); + + preferenceSelector.Preference = preference; + } + } + + private class AntagPreferenceSelector : Control + { + public AntagPrototype Antag { get; } + private readonly CheckBox _checkBox; + + public bool Preference + { + get => _checkBox.Pressed; + set => _checkBox.Pressed = value; + } + + public event Action PreferenceChanged; + + public AntagPreferenceSelector(AntagPrototype antag) + { + Antag = antag; + + _checkBox = new CheckBox {Text = $"{antag.Name}"}; + _checkBox.OnToggled += OnCheckBoxToggled; + + AddChild(new HBoxContainer + { + Children = + { + _checkBox + } + }); + } + private void OnCheckBoxToggled(BaseButton.ButtonToggledEventArgs args) + { + PreferenceChanged?.Invoke(Preference); + } + } } } diff --git a/Content.Server.Database/Migrations/Postgres/20200706172726_Antags.Designer.cs b/Content.Server.Database/Migrations/Postgres/20200706172726_Antags.Designer.cs new file mode 100644 index 0000000000..266aa377e5 --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20200706172726_Antags.Designer.cs @@ -0,0 +1,185 @@ +// +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + [DbContext(typeof(PostgresPreferencesDbContext))] + [Migration("20200706172726_Antags")] + partial class Antags + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("AntagId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("text"); + + b.Property("HumanoidProfileId") + .HasColumnType("integer"); + + b.HasKey("AntagId"); + + b.HasIndex("HumanoidProfileId", "AntagName") + .IsUnique(); + + b.ToTable("Antag"); + }); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.Property("HumanoidProfileId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Age") + .HasColumnType("integer"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("text"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreferenceUnavailable") + .HasColumnType("integer"); + + b.Property("PrefsId") + .HasColumnType("integer"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("text"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("Slot") + .HasColumnType("integer"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("HumanoidProfileId"); + + b.HasIndex("PrefsId"); + + b.HasIndex("Slot", "PrefsId") + .IsUnique(); + + b.ToTable("HumanoidProfile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("JobId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("ProfileHumanoidProfileId") + .HasColumnType("integer"); + + b.HasKey("JobId"); + + b.HasIndex("ProfileHumanoidProfileId"); + + b.ToTable("Job"); + }); + + modelBuilder.Entity("Content.Server.Database.Prefs", b => + { + b.Property("PrefsId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("SelectedCharacterSlot") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("PrefsId"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Preferences"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Antags") + .HasForeignKey("HumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.HasOne("Content.Server.Database.Prefs", "Prefs") + .WithMany("HumanoidProfiles") + .HasForeignKey("PrefsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileHumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/20200706172726_Antags.cs b/Content.Server.Database/Migrations/Postgres/20200706172726_Antags.cs new file mode 100644 index 0000000000..23d595a79b --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20200706172726_Antags.cs @@ -0,0 +1,43 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + public partial class Antags : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Antag", + columns: table => new + { + AntagId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + HumanoidProfileId = table.Column(nullable: false), + AntagName = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Antag", x => x.AntagId); + table.ForeignKey( + name: "FK_Antag_HumanoidProfile_HumanoidProfileId", + column: x => x.HumanoidProfileId, + principalTable: "HumanoidProfile", + principalColumn: "HumanoidProfileId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Antag_HumanoidProfileId_AntagName", + table: "Antag", + columns: new[] { "HumanoidProfileId", "AntagName" }, + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Antag"); + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs index bfd4851099..0343886635 100644 --- a/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs @@ -18,6 +18,28 @@ namespace Content.Server.Database.Migrations.Postgres .HasAnnotation("ProductVersion", "3.1.4") .HasAnnotation("Relational:MaxIdentifierLength", 63); + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("AntagId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("text"); + + b.Property("HumanoidProfileId") + .HasColumnType("integer"); + + b.HasKey("AntagId"); + + b.HasIndex("HumanoidProfileId", "AntagName") + .IsUnique(); + + b.ToTable("Antag"); + }); + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => { b.Property("HumanoidProfileId") @@ -129,6 +151,15 @@ namespace Content.Server.Database.Migrations.Postgres b.ToTable("Preferences"); }); + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Antags") + .HasForeignKey("HumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => { b.HasOne("Content.Server.Database.Prefs", "Prefs") diff --git a/Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.Designer.cs new file mode 100644 index 0000000000..00fe13a785 --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.Designer.cs @@ -0,0 +1,178 @@ +// +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Content.Server.Database.Migrations.Sqlite +{ + [DbContext(typeof(SqlitePreferencesDbContext))] + [Migration("20200706172741_Antags")] + partial class Antags + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.4"); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("AntagId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("HumanoidProfileId") + .HasColumnType("INTEGER"); + + b.HasKey("AntagId"); + + b.HasIndex("HumanoidProfileId", "AntagName") + .IsUnique(); + + b.ToTable("Antag"); + }); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.Property("HumanoidProfileId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Age") + .HasColumnType("INTEGER"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PreferenceUnavailable") + .HasColumnType("INTEGER"); + + b.Property("PrefsId") + .HasColumnType("INTEGER"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Slot") + .HasColumnType("INTEGER"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("HumanoidProfileId"); + + b.HasIndex("PrefsId"); + + b.HasIndex("Slot", "PrefsId") + .IsUnique(); + + b.ToTable("HumanoidProfile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("JobId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Priority") + .HasColumnType("INTEGER"); + + b.Property("ProfileHumanoidProfileId") + .HasColumnType("INTEGER"); + + b.HasKey("JobId"); + + b.HasIndex("ProfileHumanoidProfileId"); + + b.ToTable("Job"); + }); + + modelBuilder.Entity("Content.Server.Database.Prefs", b => + { + b.Property("PrefsId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SelectedCharacterSlot") + .HasColumnType("INTEGER"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("PrefsId"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Preferences"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Antags") + .HasForeignKey("HumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.HasOne("Content.Server.Database.Prefs", "Prefs") + .WithMany("HumanoidProfiles") + .HasForeignKey("PrefsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileHumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.cs b/Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.cs new file mode 100644 index 0000000000..f2c1185b00 --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20200706172741_Antags.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Content.Server.Database.Migrations.Sqlite +{ + public partial class Antags : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Antag", + columns: table => new + { + AntagId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + HumanoidProfileId = table.Column(nullable: false), + AntagName = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Antag", x => x.AntagId); + table.ForeignKey( + name: "FK_Antag_HumanoidProfile_HumanoidProfileId", + column: x => x.HumanoidProfileId, + principalTable: "HumanoidProfile", + principalColumn: "HumanoidProfileId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Antag_HumanoidProfileId_AntagName", + table: "Antag", + columns: new[] { "HumanoidProfileId", "AntagName" }, + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Antag"); + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs index bf6e21f02a..60b7c39f14 100644 --- a/Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs @@ -15,6 +15,27 @@ namespace Content.Server.Database.Migrations modelBuilder .HasAnnotation("ProductVersion", "3.1.4"); + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("AntagId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("HumanoidProfileId") + .HasColumnType("INTEGER"); + + b.HasKey("AntagId"); + + b.HasIndex("HumanoidProfileId", "AntagName") + .IsUnique(); + + b.ToTable("Antag"); + }); + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => { b.Property("HumanoidProfileId") @@ -123,6 +144,15 @@ namespace Content.Server.Database.Migrations b.ToTable("Preferences"); }); + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Antags") + .HasForeignKey("HumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => { b.HasOne("Content.Server.Database.Prefs", "Prefs") diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index e3c62ffd13..a28d1dcb8f 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -64,6 +64,10 @@ namespace Content.Server.Database modelBuilder.Entity() .HasIndex(p => new {p.Slot, p.PrefsId}) .IsUnique(); + + modelBuilder.Entity() + .HasIndex(p => new {p.HumanoidProfileId , p.AntagName}) + .IsUnique(); } } @@ -90,6 +94,7 @@ namespace Content.Server.Database public string EyeColor { get; set; } = null!; public string SkinColor { get; set; } = null!; public List Jobs { get; } = new List(); + public List Antags { get; } = new List(); public DbPreferenceUnavailableMode PreferenceUnavailable { get; set; } public int PrefsId { get; set; } @@ -114,6 +119,15 @@ namespace Content.Server.Database High = 3 } + public class Antag + { + public int AntagId { get; set; } + public HumanoidProfile Profile { get; set; } = null!; + public int HumanoidProfileId { get; set; } + + public string AntagName { get; set; } = null!; + } + public enum DbPreferenceUnavailableMode { // These enum values HAVE to match the ones in PreferenceUnavailableMode in Shared. diff --git a/Content.Server.Database/PrefsDb.cs b/Content.Server.Database/PrefsDb.cs index a1c3de32cd..73e98b0216 100644 --- a/Content.Server.Database/PrefsDb.cs +++ b/Content.Server.Database/PrefsDb.cs @@ -26,8 +26,8 @@ namespace Content.Server.Database { return await _prefsCtx .Preferences - .Include(p => p.HumanoidProfiles) - .ThenInclude(h => h.Jobs) + .Include(p => p.HumanoidProfiles).ThenInclude(h => h.Jobs) + .Include(p => p.HumanoidProfiles).ThenInclude(h => h.Antags) .SingleOrDefaultAsync(p => p.Username == username); } @@ -72,6 +72,7 @@ namespace Content.Server.Database { return await _prefsCtx.HumanoidProfile .Include(p => p.Jobs) + .Include(a => a.Antags) .Join(_prefsCtx.Preferences, profile => new {profile.Slot, profile.PrefsId}, prefs => new {Slot = prefs.SelectedCharacterSlot, prefs.PrefsId}, diff --git a/Content.Server/GameTicking/GamePreset.cs b/Content.Server/GameTicking/GamePreset.cs index 5b4fdadf2d..0f9642184a 100644 --- a/Content.Server/GameTicking/GamePreset.cs +++ b/Content.Server/GameTicking/GamePreset.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Robust.Server.Interfaces.Player; +using Content.Shared.Preferences; namespace Content.Server.GameTicking { @@ -11,5 +12,6 @@ namespace Content.Server.GameTicking public abstract bool Start(IReadOnlyList readyPlayers, bool force = false); public virtual string ModeTitle => "Sandbox"; public virtual string Description => "Secret!"; + public Dictionary readyProfiles; } } diff --git a/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs b/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs index b59e7d7ae5..17def7d31a 100644 --- a/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs +++ b/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs @@ -1,17 +1,23 @@ -using System; -using System.Collections.Generic; -using Content.Server.GameTicking.GameRules; +using Content.Server.GameTicking.GameRules; +using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; using Content.Server.Interfaces.GameTicking; using Content.Server.Mobs.Roles; using Content.Server.Players; -using Content.Server.Sandbox; -using NFluidsynth; +using Content.Shared.Antags; using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.Random; using Robust.Shared.IoC; +using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Logger = Robust.Shared.Log.Logger; +using System; +using System.Collections.Generic; +using System.Linq; +using Robust.Shared.Log; +using System.Threading.Tasks; +using Content.Shared.Preferences; + + namespace Content.Server.GameTicking.GamePresets { @@ -21,11 +27,14 @@ namespace Content.Server.GameTicking.GamePresets [Dependency] private readonly IChatManager _chatManager; [Dependency] private readonly IGameTicker _gameTicker; [Dependency] private readonly IRobustRandom _random; + [Dependency] private IPrototypeManager _prototypeManager; #pragma warning restore 649 public int MinPlayers { get; set; } = 5; public int MinTraitors { get; set; } = 2; public int PlayersPerTraitor { get; set; } = 5; + private static string TraitorID = "SuspicionTraitor"; + private static string InnocentID = "SuspicionInnocent"; public override bool Start(IReadOnlyList readyPlayers, bool force = false) { @@ -36,20 +45,48 @@ namespace Content.Server.GameTicking.GamePresets } var list = new List(readyPlayers); + var prefList = new List(); + + foreach (var player in list) + { + if (!readyProfiles.ContainsKey(player.Name)) + { + continue; + } + var profile = readyProfiles[player.Name]; + if (profile.AntagPreferences.Contains(_prototypeManager.Index(TraitorID).Name)) + { + prefList.Add(player); + } + } + var numTraitors = Math.Clamp(readyPlayers.Count % PlayersPerTraitor, MinTraitors, readyPlayers.Count); for (var i = 0; i < numTraitors; i++) { - var traitor = _random.PickAndTake(list); + IPlayerSession traitor; + if(prefList.Count() == 0) + { + traitor = _random.PickAndTake(list); + Logger.InfoS("preset", "Insufficient preferred traitors, picking at random."); + } + else + { + traitor = _random.PickAndTake(prefList); + list.Remove(traitor); + Logger.InfoS("preset", "Selected a preferred traitor."); + } var mind = traitor.Data.ContentData().Mind; - mind.AddRole(new SuspicionTraitorRole(mind)); + var antagPrototype = _prototypeManager.Index(TraitorID); + mind.AddRole(new SuspicionTraitorRole(mind, antagPrototype)); } foreach (var player in list) { var mind = player.Data.ContentData().Mind; - mind.AddRole(new SuspicionInnocentRole(mind)); + var antagPrototype = _prototypeManager.Index(InnocentID); + mind.AddRole(new SuspicionInnocentRole(mind, antagPrototype)); } _gameTicker.AddGameRule(); diff --git a/Content.Server/GameTicking/GameRules/RuleSuspicion.cs b/Content.Server/GameTicking/GameRules/RuleSuspicion.cs index 91b16f3aaf..50f236072d 100644 --- a/Content.Server/GameTicking/GameRules/RuleSuspicion.cs +++ b/Content.Server/GameTicking/GameRules/RuleSuspicion.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading; using Content.Server.GameObjects; using Content.Server.GameObjects.Components.Mobs; @@ -38,8 +39,6 @@ namespace Content.Server.GameTicking.GameRules public override void Added() { - _chatManager.DispatchServerAnnouncement("There are traitors on the station! Find them, and kill them!"); - _entityManager.EventBus.SubscribeEvent(EventSource.Local, this, _onMobDamageStateChanged); Timer.SpawnRepeating(DeadCheckDelay, _checkWinConditions, _checkTimerCancel.Token); @@ -86,7 +85,6 @@ namespace Content.Server.GameTicking.GameRules { continue; } - if (playerSession.ContentData().Mind.HasRole()) traitorsAlive++; else diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 4d89eb2351..759914db40 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -267,12 +267,12 @@ namespace Content.Server.GameTicking } // Time to start the preset. - var preset = MakeGamePreset(); + var preset = MakeGamePreset(profiles); if (!preset.Start(assignedJobs.Keys.ToList(), force)) { SetStartPreset(_configurationManager.GetCVar("game.fallbackpreset")); - var newPreset = MakeGamePreset(); + var newPreset = MakeGamePreset(profiles); _chatManager.DispatchServerAnnouncement( $"Failed to start {preset.ModeTitle} mode! Defaulting to {newPreset.ModeTitle}..."); if (!newPreset.Start(readyPlayers, force)) @@ -306,7 +306,7 @@ namespace Content.Server.GameTicking //Tell every client the round has ended. var roundEndMessage = _netManager.CreateNetMessage(); - roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle; + roundEndMessage.GamemodeTitle = MakeGamePreset(null).ModeTitle; //Get the timespan of the round. roundEndMessage.RoundDuration = IoCManager.Resolve().RealTime.Subtract(_roundStartTimeSpan); @@ -318,13 +318,13 @@ namespace Content.Server.GameTicking var mind = ply.ContentData().Mind; if (mind != null) { - var antag = mind.AllRoles.Any(role => role.Antag); + var antag = mind.AllRoles.Any(role => role.Antagonist); var playerEndRoundInfo = new RoundEndPlayerInfo() { PlayerOOCName = ply.Name, PlayerICName = mind.CurrentEntity.Name, Role = antag - ? mind.AllRoles.First(role => role.Antag).Name + ? mind.AllRoles.First(role => role.Antagonist).Name : mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unknown"), Antag = antag }; @@ -805,7 +805,7 @@ namespace Content.Server.GameTicking var mindComponent = mob.GetComponent(); if (mindComponent.HasMind) //Redundancy checks. { - if (mindComponent.Mind.AllRoles.Any(role => role.Antag)) //Give antags a new uplinkaccount. + if (mindComponent.Mind.AllRoles.Any(role => role.Antagonist)) //Give antags a new uplinkaccount. { var uplinkAccount = new UplinkAccount(mob.Uid, @@ -883,8 +883,8 @@ namespace Content.Server.GameTicking private string GetInfoText() { - var gmTitle = MakeGamePreset().ModeTitle; - var desc = MakeGamePreset().Description; + var gmTitle = MakeGamePreset(null).ModeTitle; + var desc = MakeGamePreset(null).Description; return _localization.GetString(@"Hi and welcome to [color=white]Space Station 14![/color] The current game mode is: [color=white]{0}[/color]. @@ -898,9 +898,11 @@ The current game mode is: [color=white]{0}[/color]. _netManager.ServerSendToMany(infoMsg, _playersInLobby.Keys.Select(p => p.ConnectedClient).ToList()); } - private GamePreset MakeGamePreset() + private GamePreset MakeGamePreset(Dictionary readyProfiles) { - return _dynamicTypeFactory.CreateInstance(_presetType ?? typeof(PresetSandbox)); + var preset = _dynamicTypeFactory.CreateInstance(_presetType ?? typeof(PresetSandbox)); + preset.readyProfiles = readyProfiles; + return preset; } #pragma warning disable 649 diff --git a/Content.Server/Mobs/Role.cs b/Content.Server/Mobs/Role.cs index f78b579f11..d1980956a5 100644 --- a/Content.Server/Mobs/Role.cs +++ b/Content.Server/Mobs/Role.cs @@ -26,7 +26,7 @@ namespace Content.Server.Mobs /// /// Whether this role should be considered antagonistic or not. /// - public abstract bool Antag { get; } + public abstract bool Antagonist { get; } protected Role(Mind mind) { diff --git a/Content.Server/Mobs/Roles/Job.cs b/Content.Server/Mobs/Roles/Job.cs index 680a91ff20..33db5a65dc 100644 --- a/Content.Server/Mobs/Roles/Job.cs +++ b/Content.Server/Mobs/Roles/Job.cs @@ -11,7 +11,7 @@ namespace Content.Server.Mobs.Roles public JobPrototype Prototype { get; } public override string Name { get; } - public override bool Antag => false; + public override bool Antagonist => false; public string StartingGear => Prototype.StartingGear; diff --git a/Content.Server/Mobs/Roles/SuspicionInnocentRole.cs b/Content.Server/Mobs/Roles/SuspicionInnocentRole.cs index 177a8d3bbd..4c2f16f6a9 100644 --- a/Content.Server/Mobs/Roles/SuspicionInnocentRole.cs +++ b/Content.Server/Mobs/Roles/SuspicionInnocentRole.cs @@ -2,24 +2,32 @@ using Content.Server.GameObjects; using Content.Server.Interfaces.Chat; using Robust.Shared.IoC; using Robust.Shared.Utility; +using Content.Shared.Antags; namespace Content.Server.Mobs.Roles { public class SuspicionInnocentRole : Role { - public SuspicionInnocentRole(Mind mind) : base(mind) + public AntagPrototype Prototype { get; } + + public SuspicionInnocentRole(Mind mind, AntagPrototype antagPrototype) : base(mind) { + Prototype = antagPrototype; + Name = antagPrototype.Name; + Antagonist = antagPrototype.Antagonist; } - public override string Name => "Innocent"; - public override bool Antag => false; + public override string Name { get; } + public string Objective => Prototype.Objective; + public override bool Antagonist { get; } public override void Greet() { base.Greet(); var chat = IoCManager.Resolve(); - chat.DispatchServerMessage(Mind.Session, "You're an innocent!"); + chat.DispatchServerMessage(Mind.Session, $"You're a {Name}!"); + chat.DispatchServerMessage(Mind.Session, $"Objective: {Objective}"); } } } diff --git a/Content.Server/Mobs/Roles/SuspicionTraitorRole.cs b/Content.Server/Mobs/Roles/SuspicionTraitorRole.cs index 65c1e10306..5d19854454 100644 --- a/Content.Server/Mobs/Roles/SuspicionTraitorRole.cs +++ b/Content.Server/Mobs/Roles/SuspicionTraitorRole.cs @@ -1,25 +1,33 @@ -using Content.Server.GameObjects; +using Content.Server.GameObjects; using Content.Server.Interfaces.Chat; using Robust.Shared.IoC; using Robust.Shared.Utility; +using Content.Shared.Antags; namespace Content.Server.Mobs.Roles { public sealed class SuspicionTraitorRole : Role { - public SuspicionTraitorRole(Mind mind) : base(mind) + public AntagPrototype Prototype { get; } + + public SuspicionTraitorRole(Mind mind, AntagPrototype antagPrototype) : base(mind) { + Prototype = antagPrototype; + Name = antagPrototype.Name; + Antagonist = antagPrototype.Antagonist; } - public override string Name => "Traitor"; - public override bool Antag => true; + public override string Name { get; } + public string Objective => Prototype.Objective; + public override bool Antagonist { get; } public override void Greet() { base.Greet(); var chat = IoCManager.Resolve(); - chat.DispatchServerMessage(Mind.Session, "You're a traitor!"); + chat.DispatchServerMessage(Mind.Session, $"You're a {Name}!"); + chat.DispatchServerMessage(Mind.Session, $"Objective: {Objective}"); } } } diff --git a/Content.Server/PDA/PDAUplinkManager.cs b/Content.Server/PDA/PDAUplinkManager.cs index 7e199ce153..56b673df12 100644 --- a/Content.Server/PDA/PDAUplinkManager.cs +++ b/Content.Server/PDA/PDAUplinkManager.cs @@ -56,7 +56,7 @@ namespace Content.Server.PDA var entity = _entityManager.GetEntity(acc.AccountHolder); if (entity.TryGetComponent(out MindComponent mindComponent)) { - if (mindComponent.Mind.AllRoles.Any(role => !role.Antag)) + if (mindComponent.Mind.AllRoles.Any(role => !role.Antagonist)) { return false; } diff --git a/Content.Server/Preferences/PreferencesDatabase.cs b/Content.Server/Preferences/PreferencesDatabase.cs index b29ff4a255..6c6c4719d0 100644 --- a/Content.Server/Preferences/PreferencesDatabase.cs +++ b/Content.Server/Preferences/PreferencesDatabase.cs @@ -107,6 +107,10 @@ namespace Content.Server.Preferences .Where(j => j.Value != JobPriority.Never) .Select(j => new Job {JobName = j.Key, Priority = (DbJobPriority) j.Value}) ); + entity.Antags.AddRange( + humanoid.AntagPreferences + .Select(a => new Antag {AntagName = a}) + ); await _prefsDb.SaveCharacterSlotAsync(username, entity); } finally @@ -140,6 +144,7 @@ namespace Content.Server.Preferences private static HumanoidCharacterProfile ConvertProfiles(HumanoidProfile profile) { var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority); + var antags = profile.Antags.Select(a => a.AntagName); return new HumanoidCharacterProfile( profile.CharacterName, profile.Age, @@ -154,7 +159,8 @@ namespace Content.Server.Preferences Color.FromHex(profile.SkinColor) ), jobs, - (PreferenceUnavailableMode) profile.PreferenceUnavailable + (PreferenceUnavailableMode) profile.PreferenceUnavailable, + antags.ToList() ); } } diff --git a/Content.Shared/Preferences/HumanoidCharacterProfile.cs b/Content.Shared/Preferences/HumanoidCharacterProfile.cs index 5b061d5a3f..db068e358d 100644 --- a/Content.Shared/Preferences/HumanoidCharacterProfile.cs +++ b/Content.Shared/Preferences/HumanoidCharacterProfile.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using Content.Shared.Antags; +using Robust.Shared.IoC; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Preferences @@ -9,6 +12,7 @@ namespace Content.Shared.Preferences public class HumanoidCharacterProfile : ICharacterProfile { private readonly Dictionary _jobPriorities; + private readonly List _antagPreferences; public static int MinimumAge = 18; public static int MaximumAge = 90; @@ -18,7 +22,8 @@ namespace Content.Shared.Preferences Sex sex, HumanoidCharacterAppearance appearance, Dictionary jobPriorities, - PreferenceUnavailableMode preferenceUnavailable) + PreferenceUnavailableMode preferenceUnavailable, + List antagPreferences) { Name = name; Age = age; @@ -26,6 +31,7 @@ namespace Content.Shared.Preferences Appearance = appearance; _jobPriorities = jobPriorities; PreferenceUnavailable = preferenceUnavailable; + _antagPreferences = antagPreferences; } public HumanoidCharacterProfile( @@ -34,9 +40,10 @@ namespace Content.Shared.Preferences Sex sex, HumanoidCharacterAppearance appearance, IReadOnlyDictionary jobPriorities, - PreferenceUnavailableMode preferenceUnavailable) + PreferenceUnavailableMode preferenceUnavailable, + IReadOnlyList antagPreferences) : this(name, age, sex, appearance, new Dictionary(jobPriorities), - preferenceUnavailable) + preferenceUnavailable, new List(antagPreferences)) { } @@ -46,7 +53,7 @@ namespace Content.Shared.Preferences new Dictionary { {SharedGameTicker.OverflowJob, JobPriority.High} - }, PreferenceUnavailableMode.StayInLobby); + }, PreferenceUnavailableMode.StayInLobby, new List()); } public string Name { get; } @@ -55,26 +62,27 @@ namespace Content.Shared.Preferences public ICharacterAppearance CharacterAppearance => Appearance; public HumanoidCharacterAppearance Appearance { get; } public IReadOnlyDictionary JobPriorities => _jobPriorities; + public IReadOnlyList AntagPreferences => _antagPreferences; public PreferenceUnavailableMode PreferenceUnavailable { get; } public HumanoidCharacterProfile WithName(string name) { - return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable); + return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); } public HumanoidCharacterProfile WithAge(int age) { - return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities, PreferenceUnavailable); + return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); } public HumanoidCharacterProfile WithSex(Sex sex) { - return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable); + return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); } public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance) { - return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable); + return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); } public HumanoidCharacterProfile WithJobPriorities(IReadOnlyDictionary jobPriorities) @@ -85,7 +93,8 @@ namespace Content.Shared.Preferences Sex, Appearance, new Dictionary(jobPriorities), - PreferenceUnavailable); + PreferenceUnavailable, + _antagPreferences); } public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority) @@ -100,12 +109,44 @@ namespace Content.Shared.Preferences dictionary[jobId] = priority; } - return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable); + return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable, _antagPreferences); } public HumanoidCharacterProfile WithPreferenceUnavailable(PreferenceUnavailableMode mode) { - return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, mode); + return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, mode, _antagPreferences); + } + + public HumanoidCharacterProfile WithAntagPreferences(IReadOnlyList antagPreferences) + { + return new HumanoidCharacterProfile( + Name, + Age, + Sex, + Appearance, + _jobPriorities, + PreferenceUnavailable, + new List(antagPreferences)); + } + + public HumanoidCharacterProfile WithAntagPreference(string antagId, bool pref) + { + var list = new List(_antagPreferences); + if(pref) + { + if(!list.Contains(antagId)) + { + list.Add(antagId); + } + } + else + { + if(list.Contains(antagId)) + { + list.Remove(antagId); + } + } + return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, list); } public string Summary => @@ -119,6 +160,7 @@ namespace Content.Shared.Preferences if (Sex != other.Sex) return false; if (PreferenceUnavailable != other.PreferenceUnavailable) return false; if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false; + if (!_antagPreferences.SequenceEqual(other._antagPreferences)) return false; return Appearance.MemberwiseEquals(other.Appearance); } } diff --git a/Content.Shared/Roles/AntagPrototype.cs b/Content.Shared/Roles/AntagPrototype.cs new file mode 100644 index 0000000000..a253d13a1a --- /dev/null +++ b/Content.Shared/Roles/AntagPrototype.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Robust.Shared.Localization; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; +using YamlDotNet.RepresentationModel; + +namespace Content.Shared.Antags +{ + /// + /// Describes information for a single antag. + /// + [Prototype("antag")] + public class AntagPrototype : IPrototype, IIndexedPrototype + { + public string ID { get; private set; } + + /// + /// The name of this antag as displayed to players. + /// + public string Name { get; private set; } + + /// + /// The antag's objective, displayed at round-start to the player. + /// + public string Objective { get; private set; } + + /// + /// Whether or not the antag role is one of the bad guys. + /// + public bool Antagonist { get; private set; } + + /// + /// Whether or not the player can set the antag role in antag preferences. + /// + public bool SetPreference { get; private set; } + + public void LoadFrom(YamlMappingNode mapping) + { + ID = mapping.GetNode("id").AsString(); + Name = Loc.GetString(mapping.GetNode("name").ToString()); + Objective = mapping.GetNode("objective").ToString(); + Antagonist = mapping.GetNode("antagonist").AsBool(); + SetPreference = mapping.GetNode("setPreference").AsBool(); + } + } +} diff --git a/Content.Shared/Jobs/JobPrototype.cs b/Content.Shared/Roles/JobPrototype.cs similarity index 100% rename from Content.Shared/Jobs/JobPrototype.cs rename to Content.Shared/Roles/JobPrototype.cs diff --git a/Content.Shared/Jobs/StartingGearPrototype.cs b/Content.Shared/Roles/StartingGearPrototype.cs similarity index 100% rename from Content.Shared/Jobs/StartingGearPrototype.cs rename to Content.Shared/Roles/StartingGearPrototype.cs diff --git a/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs b/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs index b0a087a5db..1aa4353c10 100644 --- a/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs +++ b/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs @@ -35,7 +35,8 @@ namespace Content.Tests.Server.Preferences { {SharedGameTicker.OverflowJob, JobPriority.High} }, - PreferenceUnavailableMode.StayInLobby + PreferenceUnavailableMode.StayInLobby, + new List{} ); } diff --git a/Resources/Prototypes/Roles/Antags/Suspicion/SuspicionInnocent.yml b/Resources/Prototypes/Roles/Antags/Suspicion/SuspicionInnocent.yml new file mode 100644 index 0000000000..92c73b550f --- /dev/null +++ b/Resources/Prototypes/Roles/Antags/Suspicion/SuspicionInnocent.yml @@ -0,0 +1,6 @@ +- type: antag + id: SuspicionInnocent + name: "innocent" + antagonist: false + setPreference: false + objective: "Discover and eliminate all traitors." diff --git a/Resources/Prototypes/Roles/Antags/Suspicion/SuspicionTraitor.yml b/Resources/Prototypes/Roles/Antags/Suspicion/SuspicionTraitor.yml new file mode 100644 index 0000000000..1d2168232c --- /dev/null +++ b/Resources/Prototypes/Roles/Antags/Suspicion/SuspicionTraitor.yml @@ -0,0 +1,6 @@ +- type: antag + id: SuspicionTraitor + name: "traitor" + antagonist: true + setPreference: true + objective: "Kill the innocents." diff --git a/Resources/Prototypes/Jobs/Cargo/CargoTechnician.yml b/Resources/Prototypes/Roles/Jobs/Cargo/CargoTechnician.yml similarity index 100% rename from Resources/Prototypes/Jobs/Cargo/CargoTechnician.yml rename to Resources/Prototypes/Roles/Jobs/Cargo/CargoTechnician.yml diff --git a/Resources/Prototypes/Jobs/Civilian/Assistant.yml b/Resources/Prototypes/Roles/Jobs/Civilian/Assistant.yml similarity index 100% rename from Resources/Prototypes/Jobs/Civilian/Assistant.yml rename to Resources/Prototypes/Roles/Jobs/Civilian/Assistant.yml diff --git a/Resources/Prototypes/Jobs/Civilian/Bartender.yml b/Resources/Prototypes/Roles/Jobs/Civilian/Bartender.yml similarity index 100% rename from Resources/Prototypes/Jobs/Civilian/Bartender.yml rename to Resources/Prototypes/Roles/Jobs/Civilian/Bartender.yml diff --git a/Resources/Prototypes/Jobs/Civilian/Chef.yml b/Resources/Prototypes/Roles/Jobs/Civilian/Chef.yml similarity index 100% rename from Resources/Prototypes/Jobs/Civilian/Chef.yml rename to Resources/Prototypes/Roles/Jobs/Civilian/Chef.yml diff --git a/Resources/Prototypes/Jobs/Civilian/Clown.yml b/Resources/Prototypes/Roles/Jobs/Civilian/Clown.yml similarity index 100% rename from Resources/Prototypes/Jobs/Civilian/Clown.yml rename to Resources/Prototypes/Roles/Jobs/Civilian/Clown.yml diff --git a/Resources/Prototypes/Jobs/Civilian/Janitor.yml b/Resources/Prototypes/Roles/Jobs/Civilian/Janitor.yml similarity index 100% rename from Resources/Prototypes/Jobs/Civilian/Janitor.yml rename to Resources/Prototypes/Roles/Jobs/Civilian/Janitor.yml diff --git a/Resources/Prototypes/Jobs/Command/captain.yml b/Resources/Prototypes/Roles/Jobs/Command/captain.yml similarity index 100% rename from Resources/Prototypes/Jobs/Command/captain.yml rename to Resources/Prototypes/Roles/Jobs/Command/captain.yml diff --git a/Resources/Prototypes/Jobs/Command/head_of_personnel.yml b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml similarity index 100% rename from Resources/Prototypes/Jobs/Command/head_of_personnel.yml rename to Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml diff --git a/Resources/Prototypes/Jobs/Engineering/chief_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml similarity index 100% rename from Resources/Prototypes/Jobs/Engineering/chief_engineer.yml rename to Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml diff --git a/Resources/Prototypes/Jobs/Engineering/station_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml similarity index 100% rename from Resources/Prototypes/Jobs/Engineering/station_engineer.yml rename to Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml diff --git a/Resources/Prototypes/Jobs/Medical/chief_medical_officer.yml b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml similarity index 100% rename from Resources/Prototypes/Jobs/Medical/chief_medical_officer.yml rename to Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml diff --git a/Resources/Prototypes/Jobs/Medical/medical_doctor.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml similarity index 100% rename from Resources/Prototypes/Jobs/Medical/medical_doctor.yml rename to Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml diff --git a/Resources/Prototypes/Jobs/Science/research_director.yml b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml similarity index 100% rename from Resources/Prototypes/Jobs/Science/research_director.yml rename to Resources/Prototypes/Roles/Jobs/Science/research_director.yml diff --git a/Resources/Prototypes/Jobs/Science/scientist.yml b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml similarity index 100% rename from Resources/Prototypes/Jobs/Science/scientist.yml rename to Resources/Prototypes/Roles/Jobs/Science/scientist.yml diff --git a/Resources/Prototypes/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml similarity index 100% rename from Resources/Prototypes/Jobs/Security/head_of_security.yml rename to Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml diff --git a/Resources/Prototypes/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml similarity index 100% rename from Resources/Prototypes/Jobs/Security/security_officer.yml rename to Resources/Prototypes/Roles/Jobs/Security/security_officer.yml From b35333d3669a2add989e0801cf48ffdc75a441fe Mon Sep 17 00:00:00 2001 From: chairbender Date: Mon, 6 Jul 2020 14:27:03 -0700 Subject: [PATCH 14/18] Click Drag Functionality + Refactor Interaction Interfaces (#1125) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com> Co-authored-by: ComicIronic Co-authored-by: Pieter-Jan Briers --- Content.Client/EscapeMenuOwner.cs | 1 + .../Components/Items/ItemComponent.cs | 4 +- .../Components/PlaceableSurfaceComponent.cs | 11 + .../Storage/ClientStorageComponent.cs | 15 +- .../EntitySystems/DragDropSystem.cs | 397 ++++++++++ Content.Client/IgnoredComponents.cs | 1 - .../Interaction/IClientDraggable.cs | 59 ++ Content.Client/Sandbox/SandboxManager.cs | 1 + Content.Client/ScreenshotHook.cs | 1 + Content.Client/State/GameScreen.cs | 6 + Content.Client/State/GameScreenBase.cs | 24 +- Content.Client/State/LobbyState.cs | 1 + Content.Client/UserInterface/GameHud.cs | 1 + .../Combat/Melee/SwingMeleeWeaponOperator.cs | 5 +- .../Combat/Melee/UnarmedCombatOperator.cs | 7 +- .../Inventory/CloseStorageOperator.cs | 12 +- .../Inventory/InteractWithEntityOperator.cs | 2 +- .../Inventory/OpenStorageOperator.cs | 16 +- .../Inventory/PickupEntityOperator.cs | 2 +- .../ActionBlocker/CanMoveCon.cs | 2 + Content.Server/Chat/ChatManager.cs | 2 +- Content.Server/Explosions/ExplosionHelper.cs | 2 +- .../Access/IdCardConsoleComponent.cs | 1 + .../Components/AnchorableComponent.cs | 4 +- .../Components/Cargo/CargoConsoleComponent.cs | 1 + .../Components/Chemistry/InjectorComponent.cs | 2 +- .../Components/Chemistry/PourableComponent.cs | 2 +- .../Chemistry/ReagentDispenserComponent.cs | 2 +- .../Components/Chemistry/SolutionComponent.cs | 3 +- .../TransformableContainerComponent.cs | 2 +- .../Command/CommunicationsConsoleComponent.cs | 2 +- .../Construction/ConstructionComponent.cs | 9 +- .../Components/Damage/BreakableComponent.cs | 2 +- .../Damage/DamageOnToolInteractComponent.cs | 3 +- .../Damage/DestructibleComponent.cs | 2 +- .../Components/Doors/AirlockComponent.cs | 2 +- .../Components/Doors/ServerDoorComponent.cs | 2 + .../Explosion/ExplosiveComponent.cs | 2 +- .../Explosion/FlashExplosiveComponent.cs | 3 +- .../Components/Fluids/BucketComponent.cs | 2 +- .../Components/Fluids/MopComponent.cs | 2 +- .../Components/GUI/InventoryComponent.cs | 3 +- .../Components/GUI/ServerHandsComponent.cs | 2 + .../Gravity/GravityGeneratorComponent.cs | 2 +- .../Components/Healing/HealingComponent.cs | 2 +- .../Instruments/InstrumentComponent.cs | 2 +- .../Interactable/HandheldLightComponent.cs | 3 + .../Interactable/MultitoolComponent.cs | 2 +- .../Interactable/TilePryingComponent.cs | 3 +- .../Components/Interactable/ToolComponent.cs | 5 + .../Interactable/WelderComponent.cs | 3 +- .../Items/Clothing/ClothingComponent.cs | 2 +- .../Components/Items/DiceComponent.cs | 5 +- .../Items/FloorTileItemComponent.cs | 2 +- .../Items/Storage/EntityStorageComponent.cs | 2 +- .../Components/Items/Storage/ItemComponent.cs | 8 +- .../Storage/SecureEntityStorageComponent.cs | 2 +- .../Items/Storage/ServerStorageComponent.cs | 28 +- .../Components/Items/ToysComponent.cs | 1 + .../Components/Kitchen/MicrowaveComponent.cs | 2 +- .../Components/MagicMirrorComponent.cs | 2 +- .../Components/Markers/WarpPointComponent.cs | 3 +- .../Medical/MedicalScannerComponent.cs | 2 +- .../Metabolism/BloodstreamComponent.cs | 2 +- .../Mining/AsteroidRockComponent.cs | 2 +- .../Components/Mobs/BuckleComponent.cs | 1 + .../Components/Mobs/DamageStates.cs | 2 +- .../Components/Mobs/MindComponent.cs | 3 +- .../Components/Mobs/SpeciesComponent.cs | 2 +- .../Components/Mobs/StunnableComponent.cs | 3 + .../Movement/ServerTeleporterComponent.cs | 2 +- .../Components/Nutrition/DrinkComponent.cs | 3 +- .../Components/Nutrition/FoodComponent.cs | 2 + .../Nutrition/FoodContainerComponent.cs | 2 +- .../Components/Observer/GhostComponent.cs | 2 +- .../Components/PDA/PDAComponent.cs | 2 +- .../Components/Paper/PaperComponent.cs | 3 +- .../Components/PlaceableSurfaceComponent.cs | 7 +- .../Components/PottedPlantHideComponent.cs | 2 +- .../Power/ApcNetComponents/ApcComponent.cs | 1 + .../PowerReceiverUsers/BaseCharger.cs | 3 +- .../PowerReceiverUsers/LightBulbComponent.cs | 2 +- .../PowerCellChargerComponent.cs | 1 + .../PoweredLightComponent.cs | 1 + .../WeaponCapacitorChargerComponent.cs | 1 + .../SolarControlConsoleComponent.cs | 4 +- .../PowerNetComponents/SolarPanelComponent.cs | 1 + .../Components/Power/WireComponent.cs | 1 + .../Components/Power/WirePlacerComponent.cs | 2 +- .../Projectiles/ThrownItemComponent.cs | 5 +- .../Components/Research/LatheComponent.cs | 2 +- .../Research/ResearchClientComponent.cs | 2 +- .../Research/ResearchConsoleComponent.cs | 2 +- .../Research/ResearchPointSourceComponent.cs | 2 +- .../Research/ResearchServerComponent.cs | 2 +- .../Sound/EmitSoundOnThrowComponent.cs | 1 + .../Sound/EmitSoundOnUseComponent.cs | 2 +- .../Components/Stack/StackComponent.cs | 3 +- .../Components/Strap/StrapComponent.cs | 1 + .../OnUseTimerTriggerComponent.cs | 2 +- .../Components/Utensil/UtensilComponent.cs | 1 + .../VendingMachineComponent.cs | 3 + .../Weapon/Melee/MeleeWeaponComponent.cs | 2 +- .../Weapon/Melee/StunbatonComponent.cs | 3 +- .../Ranged/Ammunition/AmmoBoxComponent.cs | 1 + .../Ammunition/RangedMagazineComponent.cs | 9 +- .../Ranged/Ammunition/SpeedLoaderComponent.cs | 17 +- .../Barrels/BoltActionBarrelComponent.cs | 1 + .../Ranged/Barrels/PumpBarrelComponent.cs | 1 + .../Ranged/Barrels/RevolverBarrelComponent.cs | 1 + .../Barrels/ServerBatteryBarrelComponent.cs | 19 +- .../Barrels/ServerMagazineBarrelComponent.cs | 1 + .../Barrels/ServerRangedBarrelComponent.cs | 1 + .../Ranged/ServerRangedWeaponComponent.cs | 1 + .../GameObjects/Components/WiresComponent.cs | 3 +- .../GameObjects/EntitySystems/ActSystem.cs | 2 +- .../EntitySystems/BaseChargerSystem.cs | 2 +- .../EntitySystems/BloodstreamSystem.cs | 2 +- .../EntitySystems/ChemistrySystem.cs | 2 +- .../EntitySystems/Click/ExamineSystem.cs | 4 +- .../EntitySystems/Click/InteractionSystem.cs | 738 +----------------- .../EntitySystems/CombatModeSystem.cs | 2 +- .../EntitySystems/ConstructionSystem.cs | 9 +- .../GameObjects/EntitySystems/DoorSystem.cs | 5 +- .../EntitySystems/GravitySystem.cs | 2 +- .../EntitySystems/HandHeldLightSystem.cs | 2 +- .../GameObjects/EntitySystems/HandsSystem.cs | 4 +- .../GameObjects/EntitySystems/HungerSystem.cs | 2 +- .../EntitySystems/InstrumentSystem.cs | 2 +- .../GameObjects/EntitySystems/LatheSystem.cs | 2 +- .../EntitySystems/MedicalScannerSystem.cs | 2 +- .../EntitySystems/MeleeWeaponSystem.cs | 2 +- .../EntitySystems/MicrowaveSystem.cs | 2 +- .../GameObjects/EntitySystems/MoverSystem.cs | 3 +- .../GameObjects/EntitySystems/PortalSystem.cs | 2 +- .../EntitySystems/PowerApcSystem.cs | 2 +- .../EntitySystems/PowerSmesSystem.cs | 2 +- .../EntitySystems/PowerSolarSystem.cs | 2 +- .../EntitySystems/ProjectileSystem.cs | 2 +- .../GameObjects/EntitySystems/PuddleSystem.cs | 2 +- .../EntitySystems/ResearchSystem.cs | 2 +- .../EntitySystems/RoundEndSystem.cs | 2 +- .../EntitySystems/StomachSystem.cs | 2 +- .../EntitySystems/StorageSystem.cs | 4 +- .../GameObjects/EntitySystems/StunSystem.cs | 2 +- .../EntitySystems/TemperatureSystem.cs | 5 +- .../GameObjects/EntitySystems/ThirstSystem.cs | 2 +- .../EntitySystems/TriggerSystem.cs | 4 +- .../GameObjects/EntitySystems/VerbSystem.cs | 2 +- .../GameObjects/EntitySystems/WelderSystem.cs | 2 +- .../EntitySystems/WireHackingSystem.cs | 2 +- Content.Server/GameTicking/GameTicker.cs | 1 + .../Health/BodySystem/BodyManagerComponent.cs | 2 +- .../BodyPart/DroppedBodyPartComponent.cs | 3 +- .../BodyScanner/BodyScannerComponent.cs | 2 +- .../Mechanism/DroppedMechanismComponent.cs | 5 +- .../Surgery/Surgeon/SurgeryToolComponent.cs | 5 +- .../Components/Interaction/IActivate.cs | 53 ++ .../Components/Interaction/IAfterInteract.cs | 68 ++ .../Components/Interaction/IAttack.cs | 26 + .../Components/Interaction/IDragDrop.cs | 40 + .../Components/Interaction/IDragDropOn.cs | 24 + .../Components/Interaction/IDropped.cs | 53 ++ .../Components/Interaction/IEquipped.cs | 62 ++ .../Components/Interaction/IHandDeselected.cs | 53 ++ .../Components/Interaction/IHandSelected.cs | 53 ++ .../Components/Interaction/IInteractHand.cs | 54 ++ .../Components/Interaction/IInteractUsing.cs | 68 ++ .../Components/Interaction/ILand.cs | 62 ++ .../Components/Interaction/IRangedInteract.cs | 69 ++ .../Interaction/ITargetedInteractEventArgs.cs | 17 + .../Components/Interaction/IThrown.cs | 53 ++ .../Components/Interaction/IUnequipped.cs | 64 ++ .../Components/Interaction/IUse.cs | 52 ++ Content.Server/Mobs/Mind.cs | 2 +- Content.Server/Mobs/Role.cs | 2 +- Content.Server/Observer/Ghost.cs | 2 +- Content.Server/Utility/InteractionChecks.cs | 47 +- .../SharedPlaceableSurfaceComponent.cs | 9 + .../EntitySystemMessages/DragDropMessage.cs | 25 + .../EntitySystems/ExamineSystemShared.cs | 3 +- .../EntitySystems/SharedInteractionSystem.cs | 18 +- .../Entities/Markers/drag_shadow.yml | 7 + RobustToolbox | 2 +- 184 files changed, 1792 insertions(+), 895 deletions(-) create mode 100644 Content.Client/GameObjects/Components/PlaceableSurfaceComponent.cs create mode 100644 Content.Client/GameObjects/EntitySystems/DragDropSystem.cs create mode 100644 Content.Client/Interfaces/GameObjects/Components/Interaction/IClientDraggable.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IActivate.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IAfterInteract.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IAttack.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDrop.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDropOn.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IDropped.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IEquipped.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IHandDeselected.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IHandSelected.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractHand.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractUsing.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/ILand.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IRangedInteract.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/ITargetedInteractEventArgs.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IThrown.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IUnequipped.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Interaction/IUse.cs create mode 100644 Content.Shared/GameObjects/Components/SharedPlaceableSurfaceComponent.cs create mode 100644 Content.Shared/GameObjects/EntitySystemMessages/DragDropMessage.cs create mode 100644 Resources/Prototypes/Entities/Markers/drag_shadow.yml diff --git a/Content.Client/EscapeMenuOwner.cs b/Content.Client/EscapeMenuOwner.cs index 5cbd33c1d8..93acf5b298 100644 --- a/Content.Client/EscapeMenuOwner.cs +++ b/Content.Client/EscapeMenuOwner.cs @@ -6,6 +6,7 @@ using Robust.Client.Interfaces.Placement; using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.Interfaces.State; using Robust.Shared.Input; +using Robust.Shared.Input.Binding; using Robust.Shared.Interfaces.Configuration; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; diff --git a/Content.Client/GameObjects/Components/Items/ItemComponent.cs b/Content.Client/GameObjects/Components/Items/ItemComponent.cs index 4c6a1d0402..b3efb0fa16 100644 --- a/Content.Client/GameObjects/Components/Items/ItemComponent.cs +++ b/Content.Client/GameObjects/Components/Items/ItemComponent.cs @@ -1,4 +1,6 @@ -using Content.Shared.GameObjects; +using Content.Client.GameObjects.Components.Storage; +using Content.Client.Interfaces.GameObjects.Components.Interaction; +using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Items; using Robust.Client.Graphics; using Robust.Client.Interfaces.ResourceManagement; diff --git a/Content.Client/GameObjects/Components/PlaceableSurfaceComponent.cs b/Content.Client/GameObjects/Components/PlaceableSurfaceComponent.cs new file mode 100644 index 0000000000..88c12cad83 --- /dev/null +++ b/Content.Client/GameObjects/Components/PlaceableSurfaceComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.GameObjects.Components; +using Robust.Shared.GameObjects; + +namespace Content.Client.GameObjects.Components +{ + [RegisterComponent] + public class PlaceableSurfaceComponent : SharedPlaceableSurfaceComponent + { + + } +} diff --git a/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs b/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs index 0a0b948237..4fc955ede6 100644 --- a/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs +++ b/Content.Client/GameObjects/Components/Storage/ClientStorageComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Content.Shared.GameObjects.Components.Storage; using Content.Client.Interfaces.GameObjects; +using Content.Client.Interfaces.GameObjects.Components.Interaction; using Robust.Client.Graphics.Drawing; using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.UserInterface; @@ -21,7 +22,7 @@ namespace Content.Client.GameObjects.Components.Storage /// Client version of item storage containers, contains a UI which displays stored entities and their size /// [RegisterComponent] - public class ClientStorageComponent : SharedStorageComponent + public class ClientStorageComponent : SharedStorageComponent, IClientDraggable { private Dictionary StoredEntities { get; set; } = new Dictionary(); private int StorageSizeUsed; @@ -316,5 +317,17 @@ namespace Content.Client.GameObjects.Components.Storage AddChild(hBoxContainer); } } + + public bool ClientCanDropOn(CanDropEventArgs eventArgs) + { + //can only drop on placeable surfaces to empty out contents + return eventArgs.Target.HasComponent(); + } + + public bool ClientCanDrag(CanDragEventArgs eventArgs) + { + //always draggable, at least for now + return true; + } } } diff --git a/Content.Client/GameObjects/EntitySystems/DragDropSystem.cs b/Content.Client/GameObjects/EntitySystems/DragDropSystem.cs new file mode 100644 index 0000000000..feb97342a2 --- /dev/null +++ b/Content.Client/GameObjects/EntitySystems/DragDropSystem.cs @@ -0,0 +1,397 @@ +using System.Collections.Generic; +using Content.Client.Interfaces.GameObjects.Components.Interaction; +using Content.Client.State; +using Content.Shared.GameObjects; +using Content.Shared.GameObjects.EntitySystemMessages; +using Content.Shared.GameObjects.EntitySystems; +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.GameObjects.EntitySystems; +using Robust.Client.Graphics.Shaders; +using Robust.Client.Interfaces.Graphics.ClientEye; +using Robust.Client.Interfaces.Input; +using Robust.Client.Interfaces.State; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Input; +using Robust.Shared.Input.Binding; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Log; +using Robust.Shared.Maths; +using Robust.Shared.Prototypes; + +namespace Content.Client.GameObjects.EntitySystems +{ + /// + /// Handles clientside drag and drop logic + /// + [UsedImplicitly] + public class DragDropSystem : EntitySystem + { + // drag will be triggered when mouse leaves this deadzone around the click position. + private const float DragDeadzone = 2f; + // how often to recheck possible targets (prevents calling expensive + // check logic each update) + private const float TargetRecheckInterval = 0.25f; + + // if a drag ends up being cancelled and it has been under this + // amount of time since the mousedown, we will "replay" the original + // mousedown event so it can be treated like a regular click + private const float MaxMouseDownTimeForReplayingClick = 0.85f; + + private const string ShaderDropTargetInRange = "SelectionOutlineInrange"; + private const string ShaderDropTargetOutOfRange = "SelectionOutline"; + +#pragma warning disable 649 + [Dependency] private readonly IStateManager _stateManager; + [Dependency] private readonly IEntityManager _entityManager; + [Dependency] private readonly IInputManager _inputManager; + [Dependency] private readonly IEyeManager _eyeManager; + [Dependency] private readonly IPrototypeManager _prototypeManager; + [Dependency] private readonly IMapManager _mapManager; +#pragma warning restore 649 + + // entity performing the drag action + private IEntity _dragger; + private IEntity _draggedEntity; + private IClientDraggable _draggable; + private IEntity _dragShadow; + private DragState _state; + // time since mouse down over the dragged entity + private float _mouseDownTime; + // screen pos where the mouse down began + private Vector2 _mouseDownScreenPos; + // how much time since last recheck of all possible targets + private float _targetRecheckTime; + // reserved initial mousedown event so we can replay it if no drag ends up being performed + private PointerInputCmdHandler.PointerInputCmdArgs? _savedMouseDown; + // whether we are currently replaying the original mouse down, so we + // can ignore any events sent to this system + private bool _isReplaying; + + private ShaderInstance _dropTargetInRangeShader; + private ShaderInstance _dropTargetOutOfRangeShader; + private SharedInteractionSystem _interactionSystem; + private InputSystem _inputSystem; + + private List highlightedSprites = new List(); + + private enum DragState + { + NotDragging, + // not dragging yet, waiting to see + // if they hold for long enough + MouseDown, + // currently dragging something + Dragging, + } + + + public override void Initialize() + { + _state = DragState.NotDragging; + + _dropTargetInRangeShader = _prototypeManager.Index(ShaderDropTargetInRange).Instance(); + _dropTargetOutOfRangeShader = _prototypeManager.Index(ShaderDropTargetOutOfRange).Instance(); + _interactionSystem = EntitySystem.Get(); + _inputSystem = EntitySystem.Get(); + // needs to fire on mouseup and mousedown so we can detect a drag / drop + CommandBinds.Builder + .Bind(EngineKeyFunctions.Use, new PointerInputCmdHandler(OnUse, false)) + .Register(); + + } + + public override void Shutdown() + { + CancelDrag(false, null); + CommandBinds.Unregister(); + base.Shutdown(); + } + + private bool OnUse(in PointerInputCmdHandler.PointerInputCmdArgs args) + { + // not currently predicted + if (_inputSystem.Predicted) return false; + + // currently replaying a saved click, don't handle this because + // we already decided this click doesn't represent an actual drag attempt + if (_isReplaying) return false; + + if (args.State == BoundKeyState.Down) + { + return OnUseMouseDown(args); + } + else if (args.State == BoundKeyState.Up) + { + return OnUseMouseUp(args); + } + + return false; + } + + private bool OnUseMouseDown(in PointerInputCmdHandler.PointerInputCmdArgs args) + { + var dragger = args.Session.AttachedEntity; + // cancel any current dragging if there is one (shouldn't be because they would've had to have lifted + // the mouse, canceling the drag, but just being cautious) + CancelDrag(false, null); + + // possibly initiating a drag + // check if the clicked entity is draggable + if (_entityManager.TryGetEntity(args.EntityUid, out var entity)) + { + // check if the entity is reachable + if (_interactionSystem.InRangeUnobstructed(dragger.Transform.MapPosition, + entity.Transform.MapPosition, ignoredEnt: dragger) == false) + { + { + return false; + } + } + foreach (var draggable in entity.GetAllComponents()) + { + var dragEventArgs = new CanDragEventArgs(args.Session.AttachedEntity, entity); + if (draggable.ClientCanDrag(dragEventArgs)) + { + // wait to initiate a drag + _dragger = dragger; + _draggedEntity = entity; + _draggable = draggable; + _mouseDownTime = 0; + _state = DragState.MouseDown; + _mouseDownScreenPos = _inputManager.MouseScreenPosition; + // don't want anything else to process the click, + // but we will save the event so we can "re-play" it if this drag does + // not turn into an actual drag so the click can be handled normally + _savedMouseDown = args; + return true; + } + } + } + + return false; + } + + private bool OnUseMouseUp(in PointerInputCmdHandler.PointerInputCmdArgs args) + { + if (_state == DragState.MouseDown) + { + // quick mouseup, definitely treat it as a normal click by + // replaying the original + CancelDrag(true, args.OriginalMessage); + return false; + } + if (_state != DragState.Dragging) return false; + + // remaining CancelDrag calls will not replay the click because + // by this time we've determined the input was actually a drag attempt + + + // tell the server we are dropping if we are over a valid drop target in range. + // We don't use args.EntityUid here because drag interactions generally should + // work even if there's something "on top" of the drop target + if (_interactionSystem.InRangeUnobstructed(_dragger.Transform.MapPosition, + args.Coordinates.ToMap(_mapManager), ignoredEnt: _dragger) == false) + { + { + CancelDrag(false, null); + return false; + } + } + + var entities = GameScreenBase.GetEntitiesUnderPosition(_stateManager, args.Coordinates); + foreach (var entity in entities) + { + // check if it's able to be dropped on by current dragged entity + if (_draggable.ClientCanDropOn(new CanDropEventArgs(_dragger, _draggedEntity, entity))) + { + // tell the server about the drop attempt + RaiseNetworkEvent(new DragDropMessage(args.Coordinates, _draggedEntity.Uid, + entity.Uid)); + + CancelDrag(false, null); + return true; + } + } + CancelDrag(false, null); + return false; + } + + private void StartDragging() + { + // this is checked elsewhere but adding this as a failsafe + if (_draggedEntity == null || _draggedEntity.Deleted) + { + Logger.Error("Programming error. Cannot initiate drag, no dragged entity or entity" + + " was deleted."); + return; + } + + if (_draggedEntity.TryGetComponent(out var draggedSprite)) + { + _state = DragState.Dragging; + // pop up drag shadow under mouse + var mousePos = _eyeManager.ScreenToMap(_inputManager.MouseScreenPosition); + _dragShadow = _entityManager.SpawnEntity("dragshadow", mousePos); + var dragSprite = _dragShadow.GetComponent(); + dragSprite.CopyFrom(draggedSprite); + dragSprite.RenderOrder = EntityManager.CurrentTick.Value; + dragSprite.Color = dragSprite.Color.WithAlpha(0.7f); + // keep it on top of everything + dragSprite.DrawDepth = (int) DrawDepth.Overlays; + + HighlightTargets(); + } + else + { + Logger.Warning("Unable to display drag shadow for {0} because it" + + " has no sprite component.", _draggedEntity.Name); + } + } + + private void HighlightTargets() + { + if (_state != DragState.Dragging || _draggedEntity == null || + _draggedEntity.Deleted || _dragShadow == null || _dragShadow.Deleted) + { + Logger.Warning("Programming error. Can't highlight drag and drop targets, not currently " + + "dragging anything or dragged entity / shadow was deleted."); + return; + } + + // highlights the possible targets which are visible + // and able to be dropped on by the current dragged entity + + // remove current highlights + RemoveHighlights(); + + // find possible targets on screen even if not reachable + // TODO: Duplicated in SpriteSystem + var pvsBounds = _eyeManager.GetWorldViewport().Enlarged(5); + var pvsEntities = EntityManager.GetEntitiesIntersecting(_eyeManager.CurrentMap, pvsBounds, true); + foreach (var pvsEntity in pvsEntities) + { + if (pvsEntity.TryGetComponent(out var inRangeSprite)) + { + // can't highlight if there's no sprite or it's not visible + if (inRangeSprite.Visible == false) continue; + + // check if it's able to be dropped on by current dragged entity + if (_draggable.ClientCanDropOn(new CanDropEventArgs(_dragger, _draggedEntity, pvsEntity))) + { + // highlight depending on whether its in or out of range + var inRange = _interactionSystem.InRangeUnobstructed(_dragger.Transform.MapPosition, + pvsEntity.Transform.MapPosition, ignoredEnt: _dragger); + inRangeSprite.PostShader = inRange ? _dropTargetInRangeShader : _dropTargetOutOfRangeShader; + inRangeSprite.RenderOrder = EntityManager.CurrentTick.Value; + highlightedSprites.Add(inRangeSprite); + } + } + } + } + + private void RemoveHighlights() + { + foreach (var highlightedSprite in highlightedSprites) + { + highlightedSprite.PostShader = null; + highlightedSprite.RenderOrder = 0; + } + highlightedSprites.Clear(); + } + + /// + /// Cancels the drag, firing our saved drag event if instructed to do so and + /// we are within the threshold for replaying the click + /// (essentially reverting the drag attempt and allowing the original click + /// to proceed as if no drag was performed) + /// + /// if fireSavedCmd is true, this should be passed with the value of + /// the pointer cmd that caused the drag to be cancelled + private void CancelDrag(bool fireSavedCmd, FullInputCmdMessage cause) + { + RemoveHighlights(); + if (_dragShadow != null) + { + _entityManager.DeleteEntity(_dragShadow); + } + + _dragShadow = null; + _draggedEntity = null; + _draggable = null; + _dragger = null; + _state = DragState.NotDragging; + + _mouseDownTime = 0; + + if (fireSavedCmd && _savedMouseDown.HasValue && _mouseDownTime < MaxMouseDownTimeForReplayingClick) + { + var savedValue = _savedMouseDown.Value; + _isReplaying = true; + // adjust the timing info based on the current tick so it appears as if it happened now + var replayMsg = savedValue.OriginalMessage; + var adjustedInputMsg = new FullInputCmdMessage(cause.Tick, cause.SubTick, replayMsg.InputFunctionId, replayMsg.State, replayMsg.Coordinates, replayMsg.ScreenCoordinates, replayMsg.Uid); + + _inputSystem.HandleInputCommand(savedValue.Session, EngineKeyFunctions.Use, + adjustedInputMsg, true); + _isReplaying = false; + } + + _savedMouseDown = null; + + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + if (_state == DragState.MouseDown) + { + var screenPos = _inputManager.MouseScreenPosition; + if (_draggedEntity == null || _draggedEntity.Deleted) + { + // something happened to the clicked entity or we moved the mouse off the target so + // we shouldn't replay the original click + CancelDrag(false, null); + return; + } + else if ((_mouseDownScreenPos - screenPos).Length > DragDeadzone) + { + // initiate actual drag + StartDragging(); + _mouseDownTime = 0; + } + } + else if (_state == DragState.Dragging) + { + if (_draggedEntity == null || _draggedEntity.Deleted) + { + CancelDrag(false, null); + return; + } + // still in range of the thing we are dragging? + if (_interactionSystem.InRangeUnobstructed(_dragger.Transform.MapPosition, + _draggedEntity.Transform.MapPosition, ignoredEnt: _dragger) == false) + { + CancelDrag(false, null); + return; + } + + // keep dragged entity under mouse + var mousePos = _eyeManager.ScreenToMap(_inputManager.MouseScreenPosition); + // TODO: would use MapPosition instead if it had a setter, but it has no setter. + // is that intentional, or should we add a setter for Transform.MapPosition? + _dragShadow.Transform.WorldPosition = mousePos.Position; + + _targetRecheckTime += frameTime; + if (_targetRecheckTime > TargetRecheckInterval) + { + HighlightTargets(); + _targetRecheckTime = 0; + } + + } + } + } +} diff --git a/Content.Client/IgnoredComponents.cs b/Content.Client/IgnoredComponents.cs index 838d82a380..961e34eae8 100644 --- a/Content.Client/IgnoredComponents.cs +++ b/Content.Client/IgnoredComponents.cs @@ -25,7 +25,6 @@ "ItemTeleporter", "Portal", "EntityStorage", - "PlaceableSurface", "Wirecutter", "Screwdriver", "Multitool", diff --git a/Content.Client/Interfaces/GameObjects/Components/Interaction/IClientDraggable.cs b/Content.Client/Interfaces/GameObjects/Components/Interaction/IClientDraggable.cs new file mode 100644 index 0000000000..26c36d878c --- /dev/null +++ b/Content.Client/Interfaces/GameObjects/Components/Interaction/IClientDraggable.cs @@ -0,0 +1,59 @@ +using System; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Client.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface allows a local client to initiate dragging of the component's entity by mouse, for drag and + /// drop interactions. The actual logic of what happens on drop + /// is handled by IDragDrop + /// + public interface IClientDraggable + { + + /// + /// Invoked on entities visible to the user to check if this component's entity + /// can be dropped on the indicated target entity. No need to check range / reachability in here. + /// + /// true iff target is a valid target to be dropped on by this + /// component's entity. Returning true will cause the target entity to be highlighted as a potential + /// target and allow dropping when in range. + bool ClientCanDropOn(CanDropEventArgs eventArgs); + + /// + /// Invoked clientside when user is attempting to initiate a drag with this component's entity + /// in range. Return true if the drag should be initiated. It's fine to + /// return true even if there wouldn't be any valid targets - just return true + /// if this entity is in a "draggable" state. + /// + /// + /// true iff drag should be initiated + bool ClientCanDrag(CanDragEventArgs eventArgs); + } + + public class CanDropEventArgs : EventArgs + { + public CanDropEventArgs(IEntity user, IEntity dragged, IEntity target) + { + User = user; + Dragged = dragged; + Target = target; + } + + public IEntity User { get; } + public IEntity Dragged { get; } + public IEntity Target { get; } + } + + public class CanDragEventArgs : EventArgs + { + public CanDragEventArgs(IEntity user, IEntity dragged) + { + User = user; + Dragged = dragged; + } + + public IEntity User { get; } + public IEntity Dragged { get; } + } +} diff --git a/Content.Client/Sandbox/SandboxManager.cs b/Content.Client/Sandbox/SandboxManager.cs index e20931fd58..9a83f2b29e 100644 --- a/Content.Client/Sandbox/SandboxManager.cs +++ b/Content.Client/Sandbox/SandboxManager.cs @@ -8,6 +8,7 @@ using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Input; +using Robust.Shared.Input.Binding; using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; diff --git a/Content.Client/ScreenshotHook.cs b/Content.Client/ScreenshotHook.cs index 529a469b72..f3a7565bed 100644 --- a/Content.Client/ScreenshotHook.cs +++ b/Content.Client/ScreenshotHook.cs @@ -5,6 +5,7 @@ using Content.Shared.Input; using Robust.Client.Interfaces.Graphics; using Robust.Client.Interfaces.Input; using Robust.Shared.Input; +using Robust.Shared.Input.Binding; using Robust.Shared.Interfaces.Resources; using Robust.Shared.IoC; using Robust.Shared.Log; diff --git a/Content.Client/State/GameScreen.cs b/Content.Client/State/GameScreen.cs index 5d5ff40f04..a0d947c4e8 100644 --- a/Content.Client/State/GameScreen.cs +++ b/Content.Client/State/GameScreen.cs @@ -1,13 +1,19 @@ +using System.Collections.Generic; +using System.Collections.Immutable; using Content.Client.Chat; using Content.Client.Interfaces.Chat; using Content.Client.UserInterface; using Content.Shared.Input; using Robust.Client.Interfaces.Input; +using Robust.Client.Interfaces.State; using Robust.Client.Interfaces.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Input; +using Robust.Shared.Input.Binding; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Map; using Robust.Shared.ViewVariables; namespace Content.Client.State diff --git a/Content.Client/State/GameScreenBase.cs b/Content.Client/State/GameScreenBase.cs index b11201eca3..f7d7742540 100644 --- a/Content.Client/State/GameScreenBase.cs +++ b/Content.Client/State/GameScreenBase.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using Content.Client.GameObjects.Components; -using Content.Shared.GameObjects; using Content.Shared.GameObjects.EntitySystems; using Robust.Client.GameObjects.EntitySystems; using Robust.Client.Interfaces.GameObjects; @@ -9,6 +9,7 @@ using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.Interfaces.Graphics.ClientEye; using Robust.Client.Interfaces.Input; using Robust.Client.Interfaces.UserInterface; +using Robust.Client.Interfaces.State; using Robust.Client.Player; using Robust.Shared.GameObjects; using Robust.Shared.Input; @@ -71,7 +72,7 @@ namespace Content.Client.State .InRangeUnobstructed(playerPos, entityPos, predicate: entity => entity == _playerManager.LocalPlayer.ControlledEntity || entity == entityToClick, - insideBlockerValid: true); + ignoreInsideBlocker: true); } InteractionOutlineComponent outline; @@ -146,6 +147,25 @@ namespace Content.Client.State return foundEntities.Select(a => a.clicked).ToList(); } + /// + /// Gets all entities intersecting the given position. + /// + /// Static alternative to GetEntitiesUnderPosition to cut out + /// some of the boilerplate needed to get state manager and check the current state. + /// + /// state manager to use to get the current game screen + /// coordinates to check + /// the entities under the position, empty list if none found + public static IList GetEntitiesUnderPosition(IStateManager stateManager, GridCoordinates coordinates) + { + if (stateManager.CurrentState is GameScreenBase gameScreenBase) + { + return gameScreenBase.GetEntitiesUnderPosition(coordinates); + } + + return ImmutableList.Empty; + } + internal class ClickableEntityComparer : IComparer<(IEntity clicked, int depth, uint renderOrder)> { public int Compare((IEntity clicked, int depth, uint renderOrder) x, diff --git a/Content.Client/State/LobbyState.cs b/Content.Client/State/LobbyState.cs index 3209e1d01b..440509796c 100644 --- a/Content.Client/State/LobbyState.cs +++ b/Content.Client/State/LobbyState.cs @@ -12,6 +12,7 @@ using Robust.Client.Interfaces.UserInterface; using Robust.Client.Player; using Robust.Client.UserInterface.Controls; using Robust.Shared.Input; +using Robust.Shared.Input.Binding; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; diff --git a/Content.Client/UserInterface/GameHud.cs b/Content.Client/UserInterface/GameHud.cs index fdfd3e624c..587dbe4304 100644 --- a/Content.Client/UserInterface/GameHud.cs +++ b/Content.Client/UserInterface/GameHud.cs @@ -9,6 +9,7 @@ using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Input; +using Robust.Shared.Input.Binding; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; diff --git a/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs b/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs index 38065d5973..207710d94b 100644 --- a/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs +++ b/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs @@ -2,6 +2,7 @@ using Content.Server.GameObjects; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Weapon.Melee; using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; @@ -28,7 +29,7 @@ namespace Content.Server.AI.Operators.Combat.Melee { return true; } - + if (!_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) { return false; @@ -41,7 +42,7 @@ namespace Content.Server.AI.Operators.Combat.Melee return true; } - + public override void Shutdown(Outcome outcome) { base.Shutdown(outcome); diff --git a/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs b/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs index 5fc0332351..a0bade8ae3 100644 --- a/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs +++ b/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs @@ -2,6 +2,7 @@ using Content.Server.GameObjects; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Weapon.Melee; using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; @@ -29,7 +30,7 @@ namespace Content.Server.AI.Operators.Combat.Melee { return true; } - + if (!_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) { return false; @@ -39,7 +40,7 @@ namespace Content.Server.AI.Operators.Combat.Melee { combatModeComponent.IsInCombatMode = true; } - + if (_owner.TryGetComponent(out UnarmedCombatComponent unarmedCombatComponent)) { _unarmedCombat = unarmedCombatComponent; @@ -85,4 +86,4 @@ namespace Content.Server.AI.Operators.Combat.Melee return Outcome.Continuing; } } -} \ No newline at end of file +} diff --git a/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs b/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs index 193b45077e..d70300e4a4 100644 --- a/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs +++ b/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs @@ -1,7 +1,7 @@ using Content.Server.AI.Utility; using Content.Server.AI.WorldState.States.Inventory; using Content.Server.GameObjects.Components; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Robust.Shared.Interfaces.GameObjects; @@ -27,7 +27,7 @@ namespace Content.Server.AI.Operators.Inventory { return true; } - + var blackboard = UtilityAiHelpers.GetBlackboard(_owner); if (blackboard == null) @@ -36,7 +36,7 @@ namespace Content.Server.AI.Operators.Inventory } _target = blackboard.GetState().GetValue(); - + return _target != null; } @@ -55,12 +55,12 @@ namespace Content.Server.AI.Operators.Inventory return Outcome.Failed; } - if (!_target.TryGetComponent(out EntityStorageComponent storageComponent) || + if (!_target.TryGetComponent(out EntityStorageComponent storageComponent) || storageComponent.IsWeldedShut) { return Outcome.Failed; } - + if (storageComponent.Open) { var activateArgs = new ActivateEventArgs {User = _owner, Target = _target}; @@ -70,4 +70,4 @@ namespace Content.Server.AI.Operators.Inventory return Outcome.Success; } } -} \ No newline at end of file +} diff --git a/Content.Server/AI/Operators/Inventory/InteractWithEntityOperator.cs b/Content.Server/AI/Operators/Inventory/InteractWithEntityOperator.cs index dc2412a335..8e49c9587c 100644 --- a/Content.Server/AI/Operators/Inventory/InteractWithEntityOperator.cs +++ b/Content.Server/AI/Operators/Inventory/InteractWithEntityOperator.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; using Content.Server.Utility; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; diff --git a/Content.Server/AI/Operators/Inventory/OpenStorageOperator.cs b/Content.Server/AI/Operators/Inventory/OpenStorageOperator.cs index c7c21ae3f2..54190e6e0b 100644 --- a/Content.Server/AI/Operators/Inventory/OpenStorageOperator.cs +++ b/Content.Server/AI/Operators/Inventory/OpenStorageOperator.cs @@ -1,7 +1,7 @@ using Content.Server.AI.Utility; using Content.Server.AI.WorldState.States.Inventory; using Content.Server.GameObjects.Components; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.EntitySystems; using Robust.Shared.Containers; @@ -16,13 +16,13 @@ namespace Content.Server.AI.Operators.Inventory { private readonly IEntity _owner; private readonly IEntity _target; - + public OpenStorageOperator(IEntity owner, IEntity target) { _owner = owner; _target = target; } - + public override Outcome Execute(float frameTime) { if (!ContainerHelpers.TryGetContainer(_target, out var container)) @@ -35,22 +35,22 @@ namespace Content.Server.AI.Operators.Inventory return Outcome.Failed; } - if (!container.Owner.TryGetComponent(out EntityStorageComponent storageComponent) || + if (!container.Owner.TryGetComponent(out EntityStorageComponent storageComponent) || storageComponent.IsWeldedShut) { return Outcome.Failed; } - + if (!storageComponent.Open) { var activateArgs = new ActivateEventArgs {User = _owner, Target = _target}; storageComponent.Activate(activateArgs); } - + var blackboard = UtilityAiHelpers.GetBlackboard(_owner); blackboard?.GetState().SetValue(container.Owner); - + return Outcome.Success; } } -} \ No newline at end of file +} diff --git a/Content.Server/AI/Operators/Inventory/PickupEntityOperator.cs b/Content.Server/AI/Operators/Inventory/PickupEntityOperator.cs index ba0f40f78f..01255d9470 100644 --- a/Content.Server/AI/Operators/Inventory/PickupEntityOperator.cs +++ b/Content.Server/AI/Operators/Inventory/PickupEntityOperator.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; using Content.Server.Utility; using Robust.Shared.Containers; using Robust.Shared.Interfaces.GameObjects; diff --git a/Content.Server/AI/Utility/Considerations/ActionBlocker/CanMoveCon.cs b/Content.Server/AI/Utility/Considerations/ActionBlocker/CanMoveCon.cs index 5d9949508e..0a1828d495 100644 --- a/Content.Server/AI/Utility/Considerations/ActionBlocker/CanMoveCon.cs +++ b/Content.Server/AI/Utility/Considerations/ActionBlocker/CanMoveCon.cs @@ -1,6 +1,8 @@ using Content.Server.AI.Utility.Curves; using Content.Server.AI.WorldState; using Content.Server.AI.WorldState.States; +using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.EntitySystems; namespace Content.Server.AI.Utility.Considerations.ActionBlocker diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index f36474ba1e..60c6eb4a64 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -1,6 +1,6 @@ using System.Linq; using Content.Server.GameObjects.Components.Observer; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; using Content.Server.Observer; diff --git a/Content.Server/Explosions/ExplosionHelper.cs b/Content.Server/Explosions/ExplosionHelper.cs index a7a61a6396..44b8926b71 100644 --- a/Content.Server/Explosions/ExplosionHelper.cs +++ b/Content.Server/Explosions/ExplosionHelper.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Maps; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs b/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs index cad078d673..98ca521b45 100644 --- a/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs +++ b/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects; using Content.Server.Utility; diff --git a/Content.Server/GameObjects/Components/AnchorableComponent.cs b/Content.Server/GameObjects/Components/AnchorableComponent.cs index ef98de532a..ef8e0b4a27 100644 --- a/Content.Server/GameObjects/Components/AnchorableComponent.cs +++ b/Content.Server/GameObjects/Components/AnchorableComponent.cs @@ -1,5 +1,5 @@ -using Content.Server.GameObjects.Components.Interactable; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.Components.Interactable; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Interactable; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; diff --git a/Content.Server/GameObjects/Components/Cargo/CargoConsoleComponent.cs b/Content.Server/GameObjects/Components/Cargo/CargoConsoleComponent.cs index b8be1cda01..cd5effccc2 100644 --- a/Content.Server/GameObjects/Components/Cargo/CargoConsoleComponent.cs +++ b/Content.Server/GameObjects/Components/Cargo/CargoConsoleComponent.cs @@ -1,6 +1,7 @@ using Content.Server.Cargo; using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Cargo; using Content.Shared.Prototypes.Cargo; using JetBrains.Annotations; diff --git a/Content.Server/GameObjects/Components/Chemistry/InjectorComponent.cs b/Content.Server/GameObjects/Components/Chemistry/InjectorComponent.cs index aa3fa3ea7b..189a7c3808 100644 --- a/Content.Server/GameObjects/Components/Chemistry/InjectorComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/InjectorComponent.cs @@ -1,6 +1,6 @@ using System; using Content.Server.GameObjects.Components.Metabolism; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Utility; using Content.Shared.Chemistry; diff --git a/Content.Server/GameObjects/Components/Chemistry/PourableComponent.cs b/Content.Server/GameObjects/Components/Chemistry/PourableComponent.cs index 3d14e1c481..c23f727381 100644 --- a/Content.Server/GameObjects/Components/Chemistry/PourableComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/PourableComponent.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; using Content.Server.GameObjects.Components.Nutrition; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Utility; using Content.Shared.Chemistry; diff --git a/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs b/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs index 099d8b20eb..6a7a855713 100644 --- a/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using Content.Server.GameObjects.Components.Sound; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.GameObjects.Components.Power; using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects; diff --git a/Content.Server/GameObjects/Components/Chemistry/SolutionComponent.cs b/Content.Server/GameObjects/Components/Chemistry/SolutionComponent.cs index 96b2dec4d7..c72c05f10c 100644 --- a/Content.Server/GameObjects/Components/Chemistry/SolutionComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/SolutionComponent.cs @@ -1,5 +1,5 @@ using Content.Server.Chemistry; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Chemistry; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Chemistry; @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.Linq; using Content.Shared.GameObjects.EntitySystems; using Robust.Shared.GameObjects.Systems; +using Content.Server.GameObjects.EntitySystems.Click; namespace Content.Server.GameObjects.Components.Chemistry { diff --git a/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs b/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs index 94d18c734e..048eb685a1 100644 --- a/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/TransformableContainerComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Chemistry; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Command/CommunicationsConsoleComponent.cs b/Content.Server/GameObjects/Components/Command/CommunicationsConsoleComponent.cs index 50db5f1ba3..38e54736b5 100644 --- a/Content.Server/GameObjects/Components/Command/CommunicationsConsoleComponent.cs +++ b/Content.Server/GameObjects/Components/Command/CommunicationsConsoleComponent.cs @@ -1,6 +1,6 @@ using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Power; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameTicking; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Command; diff --git a/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs b/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs index 1eb9cad50e..5005046472 100644 --- a/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs +++ b/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs @@ -1,4 +1,11 @@ -using Content.Shared.Construction; +using System; +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Interactable; +using Content.Server.GameObjects.Components.Stack; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Content.Server.Interfaces; +using Content.Server.Utility; +using Content.Shared.Construction; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; diff --git a/Content.Server/GameObjects/Components/Damage/BreakableComponent.cs b/Content.Server/GameObjects/Components/Damage/BreakableComponent.cs index de784838c5..226abbc3ab 100644 --- a/Content.Server/GameObjects/Components/Damage/BreakableComponent.cs +++ b/Content.Server/GameObjects/Components/Damage/BreakableComponent.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Shared.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs b/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs index 4f66b92807..8a50cd06c5 100644 --- a/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs +++ b/Content.Server/GameObjects/Components/Damage/DamageOnToolInteractComponent.cs @@ -4,6 +4,7 @@ using Content.Shared.GameObjects.Components.Interactable; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using System.Collections.Generic; +using Content.Server.Interfaces.GameObjects.Components.Interaction; namespace Content.Server.GameObjects.Components.Damage { @@ -43,7 +44,7 @@ namespace Content.Server.GameObjects.Components.Damage { if (welder.WelderLit) return CallDamage(eventArgs, tool); } - break; //If the tool quality is welding and its not lit or its not actually a welder that can be lit then its pointless to continue. + break; //If the tool quality is welding and its not lit or its not actually a welder that can be lit then its pointless to continue. } if (tool.HasQuality(toolQuality)) return CallDamage(eventArgs, tool); diff --git a/Content.Server/GameObjects/Components/Damage/DestructibleComponent.cs b/Content.Server/GameObjects/Components/Damage/DestructibleComponent.cs index ed72c17540..ae3fc6dcb2 100644 --- a/Content.Server/GameObjects/Components/Damage/DestructibleComponent.cs +++ b/Content.Server/GameObjects/Components/Damage/DestructibleComponent.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Shared.GameObjects; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs b/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs index e5755e3c5b..339e235790 100644 --- a/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs @@ -3,7 +3,7 @@ using System.Threading; using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.VendingMachines; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Shared.GameObjects.Components.Doors; using Content.Shared.GameObjects.Components.Interactable; diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index 29076c4501..50ea455972 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -1,6 +1,8 @@ using System; using Content.Server.GameObjects.Components.Access; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Content.Server.Utility; using Content.Shared.GameObjects.Components.Doors; using Content.Shared.GameObjects.Components.Movement; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Explosion/ExplosiveComponent.cs b/Content.Server/GameObjects/Components/Explosion/ExplosiveComponent.cs index f23c611e24..96b7f19202 100644 --- a/Content.Server/GameObjects/Components/Explosion/ExplosiveComponent.cs +++ b/Content.Server/GameObjects/Components/Explosion/ExplosiveComponent.cs @@ -1,5 +1,5 @@ using Content.Server.Explosions; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; diff --git a/Content.Server/GameObjects/Components/Explosion/FlashExplosiveComponent.cs b/Content.Server/GameObjects/Components/Explosion/FlashExplosiveComponent.cs index 02789749bf..024ea93f4c 100644 --- a/Content.Server/GameObjects/Components/Explosion/FlashExplosiveComponent.cs +++ b/Content.Server/GameObjects/Components/Explosion/FlashExplosiveComponent.cs @@ -1,5 +1,6 @@ using Content.Server.GameObjects.Components.Weapon; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Server.GameObjects.EntitySystems; using Robust.Shared.Containers; using Robust.Shared.GameObjects; @@ -51,7 +52,7 @@ namespace Content.Server.GameObjects.Components.Explosion { Owner.Delete(); } - + return true; } diff --git a/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs b/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs index 9eb7c71ad0..b35dd8d7b7 100644 --- a/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/BucketComponent.cs @@ -1,7 +1,7 @@ using System; using Content.Server.GameObjects.Components.Chemistry; using Content.Server.GameObjects.Components.Sound; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.Chemistry; using Content.Shared.Interfaces; diff --git a/Content.Server/GameObjects/Components/Fluids/MopComponent.cs b/Content.Server/GameObjects/Components/Fluids/MopComponent.cs index 3cab561acb..22fc46878a 100644 --- a/Content.Server/GameObjects/Components/Fluids/MopComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/MopComponent.cs @@ -1,7 +1,7 @@ using System; using Content.Server.GameObjects.Components.Chemistry; using Content.Server.GameObjects.Components.Sound; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.Chemistry; using Content.Shared.Interfaces; diff --git a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs index fb9227697a..6091c504dc 100644 --- a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs @@ -2,7 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks.Dataflow; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Shared.GameObjects; using Content.Shared.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs b/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs index 0b8a492592..df383f54fd 100644 --- a/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects; using Content.Shared.GameObjects; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Gravity/GravityGeneratorComponent.cs b/Content.Server/GameObjects/Components/Gravity/GravityGeneratorComponent.cs index a553c3e4bf..52f8a99fd5 100644 --- a/Content.Server/GameObjects/Components/Gravity/GravityGeneratorComponent.cs +++ b/Content.Server/GameObjects/Components/Gravity/GravityGeneratorComponent.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Power; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Gravity; diff --git a/Content.Server/GameObjects/Components/Healing/HealingComponent.cs b/Content.Server/GameObjects/Components/Healing/HealingComponent.cs index bfebc2d3ab..b0d0b9e2c0 100644 --- a/Content.Server/GameObjects/Components/Healing/HealingComponent.cs +++ b/Content.Server/GameObjects/Components/Healing/HealingComponent.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects.Components.Stack; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Instruments/InstrumentComponent.cs b/Content.Server/GameObjects/Components/Instruments/InstrumentComponent.cs index 868a74465e..d0017971e5 100644 --- a/Content.Server/GameObjects/Components/Instruments/InstrumentComponent.cs +++ b/Content.Server/GameObjects/Components/Instruments/InstrumentComponent.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Mobs; using Content.Shared.GameObjects.Components.Instruments; diff --git a/Content.Server/GameObjects/Components/Interactable/HandheldLightComponent.cs b/Content.Server/GameObjects/Components/Interactable/HandheldLightComponent.cs index 3348ab0593..42086c3cb0 100644 --- a/Content.Server/GameObjects/Components/Interactable/HandheldLightComponent.cs +++ b/Content.Server/GameObjects/Components/Interactable/HandheldLightComponent.cs @@ -1,4 +1,7 @@ using Content.Server.GameObjects.Components.Power; +using Content.Server.GameObjects.Components.Sound; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces.GameObjects; using Content.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Interactable/MultitoolComponent.cs b/Content.Server/GameObjects/Components/Interactable/MultitoolComponent.cs index e548f6e957..95973aa1d4 100644 --- a/Content.Server/GameObjects/Components/Interactable/MultitoolComponent.cs +++ b/Content.Server/GameObjects/Components/Interactable/MultitoolComponent.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Interactable; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Interactable/TilePryingComponent.cs b/Content.Server/GameObjects/Components/Interactable/TilePryingComponent.cs index be625da60f..12f95f4371 100644 --- a/Content.Server/GameObjects/Components/Interactable/TilePryingComponent.cs +++ b/Content.Server/GameObjects/Components/Interactable/TilePryingComponent.cs @@ -1,4 +1,5 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Interactable; using Content.Shared.Maps; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Interactable/ToolComponent.cs b/Content.Server/GameObjects/Components/Interactable/ToolComponent.cs index bfa1ac94ee..495fc008b5 100644 --- a/Content.Server/GameObjects/Components/Interactable/ToolComponent.cs +++ b/Content.Server/GameObjects/Components/Interactable/ToolComponent.cs @@ -3,6 +3,11 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using Content.Server.GameObjects.Components.Chemistry; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Interactable; using Content.Shared.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Interactable/WelderComponent.cs b/Content.Server/GameObjects/Components/Interactable/WelderComponent.cs index 03d2b85479..bf55f988fa 100644 --- a/Content.Server/GameObjects/Components/Interactable/WelderComponent.cs +++ b/Content.Server/GameObjects/Components/Interactable/WelderComponent.cs @@ -1,7 +1,8 @@ using System; using System.Runtime.Remoting; using Content.Server.GameObjects.Components.Chemistry; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; using Content.Server.Interfaces.GameObjects; diff --git a/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs b/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs index 1d5c187da4..6bf0ae5822 100644 --- a/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs @@ -3,7 +3,7 @@ using Robust.Shared.Utility; using System; using System.Collections.Generic; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Items; diff --git a/Content.Server/GameObjects/Components/Items/DiceComponent.cs b/Content.Server/GameObjects/Components/Items/DiceComponent.cs index 9620c8bbd5..90f5ab03ce 100644 --- a/Content.Server/GameObjects/Components/Items/DiceComponent.cs +++ b/Content.Server/GameObjects/Components/Items/DiceComponent.cs @@ -1,5 +1,6 @@ -using Content.Server.GameObjects.Components.Sound; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.Components.Sound; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.Audio; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Items/FloorTileItemComponent.cs b/Content.Server/GameObjects/Components/Items/FloorTileItemComponent.cs index cc1ce34725..3ebd014501 100644 --- a/Content.Server/GameObjects/Components/Items/FloorTileItemComponent.cs +++ b/Content.Server/GameObjects/Components/Items/FloorTileItemComponent.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects.Components.Stack; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.Maps; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs index 6eae6bf66f..2792be485a 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs @@ -3,7 +3,7 @@ using System.Linq; using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Sound; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Interactable; using Content.Shared.GameObjects.Components.Storage; diff --git a/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs index 054a557938..d999794391 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs @@ -1,4 +1,8 @@ -using Content.Server.GameObjects.EntitySystems; +using System; +using Content.Server.GameObjects.Components; +using Content.Server.GameObjects.Components.Destructible; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces.GameObjects; using Content.Server.Throw; using Content.Server.Utility; @@ -89,7 +93,7 @@ namespace Content.Server.GameObjects var userPos = user.Transform.MapPosition; var itemPos = Owner.Transform.MapPosition; - return InteractionChecks.InRangeUnobstructed(user, itemPos, ignoredEnt: Owner, insideBlockerValid:true); + return InteractionChecks.InRangeUnobstructed(user, itemPos, ignoredEnt: Owner, ignoreInsideBlocker:true); } public bool InteractHand(InteractHandEventArgs eventArgs) diff --git a/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs index 9f583e5a09..dbdb37c09e 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects.Components.Access; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Storage; diff --git a/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs index 6878efd0b0..5ab57cdc29 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/ServerStorageComponent.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components; using Content.Server.GameObjects.Components.Items.Storage; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Storage; @@ -21,6 +22,7 @@ using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; using Robust.Shared.Log; +using Robust.Shared.Maths; using Robust.Shared.Players; using Robust.Shared.Serialization; @@ -32,7 +34,8 @@ namespace Content.Server.GameObjects [RegisterComponent] [ComponentReference(typeof(IActivate))] [ComponentReference(typeof(IStorageComponent))] - public class ServerStorageComponent : SharedStorageComponent, IInteractUsing, IUse, IActivate, IStorageComponent, IDestroyAct, IExAct + public class ServerStorageComponent : SharedStorageComponent, IInteractUsing, IUse, IActivate, IStorageComponent, IDestroyAct, IExAct, + IDragDrop { #pragma warning disable 649 [Dependency] private readonly IMapManager _mapManager; @@ -409,5 +412,26 @@ namespace Content.Server.GameObjects Owner.PopupMessage(player, "Can't insert."); return false; } + + public bool DragDrop(DragDropEventArgs eventArgs) + { + if (eventArgs.Target.TryGetComponent(out var placeableSurface)) + { + if (!placeableSurface.IsPlaceable) return false; + + // empty everything out + foreach (var storedEntity in StoredEntities.ToList()) + { + if (Remove(storedEntity)) + { + storedEntity.Transform.WorldPosition = eventArgs.DropLocation.Position; + } + } + + return true; + } + + return false; + } } } diff --git a/Content.Server/GameObjects/Components/Items/ToysComponent.cs b/Content.Server/GameObjects/Components/Items/ToysComponent.cs index fdbf4d3347..d6ad2a8ae8 100644 --- a/Content.Server/GameObjects/Components/Items/ToysComponent.cs +++ b/Content.Server/GameObjects/Components/Items/ToysComponent.cs @@ -1,5 +1,6 @@ using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.Audio; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Kitchen/MicrowaveComponent.cs b/Content.Server/GameObjects/Components/Kitchen/MicrowaveComponent.cs index 8b83174754..e7af82550d 100644 --- a/Content.Server/GameObjects/Components/Kitchen/MicrowaveComponent.cs +++ b/Content.Server/GameObjects/Components/Kitchen/MicrowaveComponent.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Linq; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.ViewVariables; diff --git a/Content.Server/GameObjects/Components/MagicMirrorComponent.cs b/Content.Server/GameObjects/Components/MagicMirrorComponent.cs index 76017269c8..eec3bea3d3 100644 --- a/Content.Server/GameObjects/Components/MagicMirrorComponent.cs +++ b/Content.Server/GameObjects/Components/MagicMirrorComponent.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components; using Content.Shared.Interfaces; diff --git a/Content.Server/GameObjects/Components/Markers/WarpPointComponent.cs b/Content.Server/GameObjects/Components/Markers/WarpPointComponent.cs index 05ed281f67..232ba77ccf 100644 --- a/Content.Server/GameObjects/Components/Markers/WarpPointComponent.cs +++ b/Content.Server/GameObjects/Components/Markers/WarpPointComponent.cs @@ -1,4 +1,5 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.GameObjects; using Robust.Shared.Localization; using Robust.Shared.Serialization; diff --git a/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs b/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs index f8bbdaa168..84bd1b53ba 100644 --- a/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs +++ b/Content.Server/GameObjects/Components/Medical/MedicalScannerComponent.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Medical; using Content.Server.GameObjects.Components.Power; diff --git a/Content.Server/GameObjects/Components/Metabolism/BloodstreamComponent.cs b/Content.Server/GameObjects/Components/Metabolism/BloodstreamComponent.cs index e428c72f17..f1f9656f4f 100644 --- a/Content.Server/GameObjects/Components/Metabolism/BloodstreamComponent.cs +++ b/Content.Server/GameObjects/Components/Metabolism/BloodstreamComponent.cs @@ -1,6 +1,6 @@ using System.Linq; using Content.Server.GameObjects.Components.Chemistry; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Chemistry; using Robust.Shared.GameObjects; using Robust.Shared.IoC; diff --git a/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs b/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs index ef85c5eb4b..d6df7cca1d 100644 --- a/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs +++ b/Content.Server/GameObjects/Components/Mining/AsteroidRockComponent.cs @@ -1,6 +1,6 @@ using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.Components.Weapon.Melee; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs b/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs index 493a21e320..747737cea4 100644 --- a/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs @@ -1,6 +1,7 @@ using Content.Server.GameObjects.Components.Strap; using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Mobs; using Content.Server.Utility; using Content.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Mobs/DamageStates.cs b/Content.Server/GameObjects/Components/Mobs/DamageStates.cs index abfdcb52f0..ad79a7a106 100644 --- a/Content.Server/GameObjects/Components/Mobs/DamageStates.cs +++ b/Content.Server/GameObjects/Components/Mobs/DamageStates.cs @@ -1,5 +1,5 @@ using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Mobs; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Mobs; diff --git a/Content.Server/GameObjects/Components/Mobs/MindComponent.cs b/Content.Server/GameObjects/Components/Mobs/MindComponent.cs index 6272bc8464..3e15cdceaf 100644 --- a/Content.Server/GameObjects/Components/Mobs/MindComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/MindComponent.cs @@ -1,5 +1,6 @@ using Content.Server.GameObjects.Components.Observer; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameTicking; using Content.Server.Mobs; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs index 380f93d667..23342f3a15 100644 --- a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Observer; using Content.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Mobs/StunnableComponent.cs b/Content.Server/GameObjects/Components/Mobs/StunnableComponent.cs index 3098310a57..0b72696503 100644 --- a/Content.Server/GameObjects/Components/Mobs/StunnableComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/StunnableComponent.cs @@ -1,5 +1,8 @@ using System; using System.Threading; +using Content.Server.GameObjects.Components.Movement; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Content.Server.Interfaces.GameObjects; using Content.Server.GameObjects.EntitySystems; using Content.Server.Mobs; using Content.Shared.Audio; diff --git a/Content.Server/GameObjects/Components/Movement/ServerTeleporterComponent.cs b/Content.Server/GameObjects/Components/Movement/ServerTeleporterComponent.cs index f6aaaf46da..12e55c9576 100644 --- a/Content.Server/GameObjects/Components/Movement/ServerTeleporterComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/ServerTeleporterComponent.cs @@ -1,6 +1,6 @@ using System; using System.Linq; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Movement; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs index 712f01130b..38d6e1fffe 100644 --- a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs @@ -1,6 +1,7 @@ using System; using Content.Server.GameObjects.Components.Chemistry; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Content.Shared.Chemistry; using Content.Shared.GameObjects.Components.Nutrition; diff --git a/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs b/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs index ef13d79fb9..e38af09497 100644 --- a/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs @@ -4,6 +4,8 @@ using Content.Server.GameObjects.Components.Chemistry; using Content.Server.GameObjects.Components.Utensil; using Content.Server.GameObjects.EntitySystems; using Content.Server.Utility; +using Content.Server.GameObjects.Components.Sound; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Chemistry; using Content.Shared.GameObjects.Components.Utensil; using Content.Shared.Interfaces; diff --git a/Content.Server/GameObjects/Components/Nutrition/FoodContainerComponent.cs b/Content.Server/GameObjects/Components/Nutrition/FoodContainerComponent.cs index efddfcc04b..572f1963c5 100644 --- a/Content.Server/GameObjects/Components/Nutrition/FoodContainerComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/FoodContainerComponent.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Nutrition; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs index 9caca4a53c..ba906a1b78 100644 --- a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs +++ b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Players; using Content.Shared.GameObjects.Components.Observer; using Content.Shared.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/PDA/PDAComponent.cs b/Content.Server/GameObjects/Components/PDA/PDAComponent.cs index 78328c9c94..eb7f1d1b68 100644 --- a/Content.Server/GameObjects/Components/PDA/PDAComponent.cs +++ b/Content.Server/GameObjects/Components/PDA/PDAComponent.cs @@ -3,7 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components.Access; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Interfaces.PDA; using Content.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Paper/PaperComponent.cs b/Content.Server/GameObjects/Components/Paper/PaperComponent.cs index 1cb46cece3..d8d391b483 100644 --- a/Content.Server/GameObjects/Components/Paper/PaperComponent.cs +++ b/Content.Server/GameObjects/Components/Paper/PaperComponent.cs @@ -1,4 +1,5 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/PlaceableSurfaceComponent.cs b/Content.Server/GameObjects/Components/PlaceableSurfaceComponent.cs index 1f8789d579..1f193bf5bd 100644 --- a/Content.Server/GameObjects/Components/PlaceableSurfaceComponent.cs +++ b/Content.Server/GameObjects/Components/PlaceableSurfaceComponent.cs @@ -1,15 +1,14 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; +using Content.Shared.GameObjects.Components; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; namespace Content.Server.GameObjects.Components { [RegisterComponent] - public class PlaceableSurfaceComponent : Component, IInteractUsing + public class PlaceableSurfaceComponent : SharedPlaceableSurfaceComponent, IInteractUsing { - public override string Name => "PlaceableSurface"; - private bool _isPlaceable; public bool IsPlaceable { get => _isPlaceable; set => _isPlaceable = value; } diff --git a/Content.Server/GameObjects/Components/PottedPlantHideComponent.cs b/Content.Server/GameObjects/Components/PottedPlantHideComponent.cs index 5093ac5b01..5de2091e62 100644 --- a/Content.Server/GameObjects/Components/PottedPlantHideComponent.cs +++ b/Content.Server/GameObjects/Components/PottedPlantHideComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects; using Content.Shared.Audio; using Content.Shared.Interfaces; diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/ApcComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/ApcComponent.cs index 9d7cebc0fb..5b5c62b12a 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/ApcComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/ApcComponent.cs @@ -11,6 +11,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.ViewVariables; using System; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.IoC; using Robust.Shared.Interfaces.Timing; diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/BaseCharger.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/BaseCharger.cs index 7645f43d8d..543c14b698 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/BaseCharger.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/BaseCharger.cs @@ -2,6 +2,7 @@ using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Power; using Content.Shared.GameObjects.EntitySystems; @@ -104,7 +105,7 @@ namespace Content.Server.GameObjects.Components.Power.Chargers { batteryBarrelComponent.UpdateAppearance(); } - + UpdateStatus(); } diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/LightBulbComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/LightBulbComponent.cs index 62742bb113..07aafe6459 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/LightBulbComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/LightBulbComponent.cs @@ -1,5 +1,5 @@ using System; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PowerCellChargerComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PowerCellChargerComponent.cs index ba066745d3..8e4adfced8 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PowerCellChargerComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PowerCellChargerComponent.cs @@ -1,4 +1,5 @@ using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PoweredLightComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PoweredLightComponent.cs index 4cc6ecebd9..a391b27a6f 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PoweredLightComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/PoweredLightComponent.cs @@ -1,6 +1,7 @@ using System; using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Sound; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; using Content.Server.Utility; diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/WeaponCapacitorChargerComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/WeaponCapacitorChargerComponent.cs index 4257742afa..bbbb29375a 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/WeaponCapacitorChargerComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverUsers/WeaponCapacitorChargerComponent.cs @@ -1,5 +1,6 @@ using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; diff --git a/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarControlConsoleComponent.cs b/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarControlConsoleComponent.cs index 954dc1bcec..24270c597e 100644 --- a/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarControlConsoleComponent.cs +++ b/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarControlConsoleComponent.cs @@ -1,11 +1,11 @@ -using Content.Server.GameObjects.Components.Power.ApcNetComponents; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Power; using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces.GameTicking; using Content.Shared.GameObjects.Components.Power; using Robust.Server.GameObjects.Components.UserInterface; using Robust.Server.Interfaces.GameObjects; -using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; diff --git a/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs b/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs index 7884358cfe..4cb7cde036 100644 --- a/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs +++ b/Content.Server/GameObjects/Components/Power/PowerNetComponents/SolarPanelComponent.cs @@ -1,5 +1,6 @@ using System; using Content.Server.GameObjects.Components.Damage; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.GameObjects.Components.Power.PowerNetComponents; using Content.Server.GameObjects.EntitySystems; using Content.Shared.Audio; diff --git a/Content.Server/GameObjects/Components/Power/WireComponent.cs b/Content.Server/GameObjects/Components/Power/WireComponent.cs index dce421d617..70b7d81193 100644 --- a/Content.Server/GameObjects/Components/Power/WireComponent.cs +++ b/Content.Server/GameObjects/Components/Power/WireComponent.cs @@ -1,6 +1,7 @@ using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Stack; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Interactable; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; diff --git a/Content.Server/GameObjects/Components/Power/WirePlacerComponent.cs b/Content.Server/GameObjects/Components/Power/WirePlacerComponent.cs index 323abcf8c5..b23a3cbf90 100644 --- a/Content.Server/GameObjects/Components/Power/WirePlacerComponent.cs +++ b/Content.Server/GameObjects/Components/Power/WirePlacerComponent.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; using Content.Server.GameObjects.Components.NodeContainer.Nodes; using Content.Server.GameObjects.Components.Stack; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs index 1f5600b186..357724ba53 100644 --- a/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs @@ -1,5 +1,6 @@ -using Content.Server.GameObjects.Components.Projectiles; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.Components.Projectiles; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.Physics; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Research/LatheComponent.cs b/Content.Server/GameObjects/Components/Research/LatheComponent.cs index bc6f16ac72..639664bdfa 100644 --- a/Content.Server/GameObjects/Components/Research/LatheComponent.cs +++ b/Content.Server/GameObjects/Components/Research/LatheComponent.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components.Power; using Content.Server.GameObjects.Components.Stack; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Materials; using Content.Shared.GameObjects.Components.Power; diff --git a/Content.Server/GameObjects/Components/Research/ResearchClientComponent.cs b/Content.Server/GameObjects/Components/Research/ResearchClientComponent.cs index ad63bb4bb7..3f14fe00da 100644 --- a/Content.Server/GameObjects/Components/Research/ResearchClientComponent.cs +++ b/Content.Server/GameObjects/Components/Research/ResearchClientComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Research; using Robust.Server.GameObjects.Components.UserInterface; diff --git a/Content.Server/GameObjects/Components/Research/ResearchConsoleComponent.cs b/Content.Server/GameObjects/Components/Research/ResearchConsoleComponent.cs index 6bef26d671..2a2c8ce62c 100644 --- a/Content.Server/GameObjects/Components/Research/ResearchConsoleComponent.cs +++ b/Content.Server/GameObjects/Components/Research/ResearchConsoleComponent.cs @@ -1,6 +1,6 @@ using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Power; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Research; diff --git a/Content.Server/GameObjects/Components/Research/ResearchPointSourceComponent.cs b/Content.Server/GameObjects/Components/Research/ResearchPointSourceComponent.cs index b273e41c26..c6d60cbd8a 100644 --- a/Content.Server/GameObjects/Components/Research/ResearchPointSourceComponent.cs +++ b/Content.Server/GameObjects/Components/Research/ResearchPointSourceComponent.cs @@ -1,6 +1,6 @@ using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.Components.Power; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; diff --git a/Content.Server/GameObjects/Components/Research/ResearchServerComponent.cs b/Content.Server/GameObjects/Components/Research/ResearchServerComponent.cs index 148663a380..4060b01368 100644 --- a/Content.Server/GameObjects/Components/Research/ResearchServerComponent.cs +++ b/Content.Server/GameObjects/Components/Research/ResearchServerComponent.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Power; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Research; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; diff --git a/Content.Server/GameObjects/Components/Sound/EmitSoundOnThrowComponent.cs b/Content.Server/GameObjects/Components/Sound/EmitSoundOnThrowComponent.cs index 19d6f81922..25b0f149f5 100644 --- a/Content.Server/GameObjects/Components/Sound/EmitSoundOnThrowComponent.cs +++ b/Content.Server/GameObjects/Components/Sound/EmitSoundOnThrowComponent.cs @@ -1,4 +1,5 @@ using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Robust.Server.GameObjects.EntitySystems; using Robust.Shared.Audio; diff --git a/Content.Server/GameObjects/Components/Sound/EmitSoundOnUseComponent.cs b/Content.Server/GameObjects/Components/Sound/EmitSoundOnUseComponent.cs index e81c57a7df..ef6f330ffc 100644 --- a/Content.Server/GameObjects/Components/Sound/EmitSoundOnUseComponent.cs +++ b/Content.Server/GameObjects/Components/Sound/EmitSoundOnUseComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Robust.Server.GameObjects.EntitySystems; using Robust.Shared.Audio; diff --git a/Content.Server/GameObjects/Components/Stack/StackComponent.cs b/Content.Server/GameObjects/Components/Stack/StackComponent.cs index 3db7729d5c..3d6d18d46d 100644 --- a/Content.Server/GameObjects/Components/Stack/StackComponent.cs +++ b/Content.Server/GameObjects/Components/Stack/StackComponent.cs @@ -1,5 +1,6 @@ using System; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components; using Content.Shared.Interfaces; diff --git a/Content.Server/GameObjects/Components/Strap/StrapComponent.cs b/Content.Server/GameObjects/Components/Strap/StrapComponent.cs index 9060193c1f..97da26fce6 100644 --- a/Content.Server/GameObjects/Components/Strap/StrapComponent.cs +++ b/Content.Server/GameObjects/Components/Strap/StrapComponent.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Strap; using Content.Shared.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Trigger/TimerTrigger/OnUseTimerTriggerComponent.cs b/Content.Server/GameObjects/Components/Trigger/TimerTrigger/OnUseTimerTriggerComponent.cs index 19d77f4ad7..81657b1063 100644 --- a/Content.Server/GameObjects/Components/Trigger/TimerTrigger/OnUseTimerTriggerComponent.cs +++ b/Content.Server/GameObjects/Components/Trigger/TimerTrigger/OnUseTimerTriggerComponent.cs @@ -1,5 +1,5 @@ using System; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Triggers; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Utensil/UtensilComponent.cs b/Content.Server/GameObjects/Components/Utensil/UtensilComponent.cs index 3069bd72c3..797a2160d9 100644 --- a/Content.Server/GameObjects/Components/Utensil/UtensilComponent.cs +++ b/Content.Server/GameObjects/Components/Utensil/UtensilComponent.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Nutrition; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Utensil; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/VendingMachines/VendingMachineComponent.cs b/Content.Server/GameObjects/Components/VendingMachines/VendingMachineComponent.cs index 4f730b77dd..6473490d56 100644 --- a/Content.Server/GameObjects/Components/VendingMachines/VendingMachineComponent.cs +++ b/Content.Server/GameObjects/Components/VendingMachines/VendingMachineComponent.cs @@ -3,6 +3,9 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.Components.Power; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components.VendingMachines; using Content.Shared.VendingMachines; diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index 78fae35837..29dbe2f98c 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Items; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs index 15310511b9..029610ba15 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Power; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects; using Content.Shared.Audio; using Content.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/AmmoBoxComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/AmmoBoxComponent.cs index 9d7d6a869d..2c733d186f 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/AmmoBoxComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/AmmoBoxComponent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/RangedMagazineComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/RangedMagazineComponent.cs index 92393e4d31..1f24d682fa 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/RangedMagazineComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/RangedMagazineComponent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.Interfaces; @@ -32,7 +33,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition public int ShotsLeft => _spawnedAmmo.Count + _unspawnedCount; public int Capacity => _capacity; private int _capacity; - + public MagazineType MagazineType => _magazineType; private MagazineType _magazineType; public BallisticCaliber Caliber => _caliber; @@ -87,7 +88,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition { _appearanceComponent = appearanceComponent; } - + _appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, true); } @@ -96,7 +97,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition _appearanceComponent?.SetData(AmmoVisuals.AmmoCount, ShotsLeft); _appearanceComponent?.SetData(AmmoVisuals.AmmoMax, Capacity); } - + public bool TryInsertAmmo(IEntity user, IEntity ammo) { if (!ammo.TryGetComponent(out AmmoComponent ammoComponent)) @@ -136,7 +137,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition _unspawnedCount--; ammo = Owner.EntityManager.SpawnEntity(_fillPrototype, Owner.Transform.GridPosition); } - + UpdateAppearance(); return ammo; } diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/SpeedLoaderComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/SpeedLoaderComponent.cs index 89cceb6828..e44f6a560c 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/SpeedLoaderComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Ammunition/SpeedLoaderComponent.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.Interfaces; using Robust.Server.GameObjects; @@ -38,7 +39,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition serializer.DataField(ref _caliber, "caliber", BallisticCaliber.Unspecified); serializer.DataField(ref _capacity, "capacity", 6); serializer.DataField(ref _fillPrototype, "fillPrototype", null); - + _spawnedAmmo = new Stack(_capacity); } @@ -56,7 +57,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition } } } - + void IMapInit.MapInit() { _unspawnedCount += _capacity; @@ -91,7 +92,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition Owner.PopupMessage(user, Loc.GetString("No room")); return false; } - + _spawnedAmmo.Push(entity); _ammoContainer.Insert(entity); UpdateAppearance(); @@ -149,10 +150,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition { return; } - + // This area is dirty but not sure of an easier way to do it besides add an interface or somethin bool changed = false; - + if (eventArgs.Target.TryGetComponent(out RevolverBarrelComponent revolverBarrel)) { for (var i = 0; i < Capacity; i++) @@ -193,9 +194,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition TryInsertAmmo(eventArgs.User, ammo); break; } - + } - + if (changed) { UpdateAppearance(); @@ -212,4 +213,4 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition return UseEntity(eventArgs.User); } } -} \ No newline at end of file +} diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/BoltActionBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/BoltActionBarrelComponent.cs index bdee4823b6..6ee38d4337 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/BoltActionBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/BoltActionBarrelComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/PumpBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/PumpBarrelComponent.cs index 405214490c..5116f2db5f 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/PumpBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/PumpBarrelComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.Interfaces; using Robust.Server.GameObjects; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/RevolverBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/RevolverBarrelComponent.cs index 1bbd687df2..3d07ecfe18 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/RevolverBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/RevolverBarrelComponent.cs @@ -2,6 +2,7 @@ using System; using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs index 60a2135eba..9c0f1597dc 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs @@ -4,6 +4,7 @@ using Content.Server.GameObjects.Components.Power; using Content.Server.GameObjects.Components.Projectiles; using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Robust.Server.GameObjects; @@ -68,9 +69,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels return (int) Math.Ceiling((float) (powerCell.GetComponent().MaxCharge / _baseFireCost)); } } - + private AppearanceComponent _appearanceComponent; - + // Sounds private string _soundPowerCellInsert; private string _soundPowerCellEject; @@ -110,10 +111,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels { _appearanceComponent = appearanceComponent; } - + UpdateAppearance(); } - + public void UpdateAppearance() { _appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, _powerCellContainer.ContainedEntity != null); @@ -223,14 +224,14 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels { return null; } - + var entity = _powerCellContainer.ContainedEntity; _powerCellContainer.Remove(entity); if (_soundPowerCellEject != null) { EntitySystem.Get().PlayAtCoords(_soundPowerCellEject, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); } - + UpdateAppearance(); //Dirty(); return entity; @@ -242,8 +243,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels { return false; } - - if (!eventArgs.User.TryGetComponent(out HandsComponent handsComponent) || + + if (!eventArgs.User.TryGetComponent(out HandsComponent handsComponent) || PowerCellEntity == null) { return false; @@ -254,7 +255,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels { return false; } - + var powerCell = RemovePowerCell(); handsComponent.PutInHand(itemComponent); powerCell.Transform.GridPosition = eventArgs.User.Transform.GridPosition; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerMagazineBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerMagazineBarrelComponent.cs index f10aab172d..21731fdfb9 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerMagazineBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerMagazineBarrelComponent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Weapons.Ranged; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs index d074bb2ee9..dcf5af0083 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs @@ -5,6 +5,7 @@ using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Projectiles; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Weapons.Ranged; using Robust.Server.GameObjects.EntitySystems; diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs index c6cb930c1a..6ac04ed143 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs @@ -2,6 +2,7 @@ using System; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Weapons.Ranged; using Content.Shared.GameObjects.EntitySystems; using Robust.Shared.GameObjects; diff --git a/Content.Server/GameObjects/Components/WiresComponent.cs b/Content.Server/GameObjects/Components/WiresComponent.cs index 60d0dd0dc0..c1d91359a5 100644 --- a/Content.Server/GameObjects/Components/WiresComponent.cs +++ b/Content.Server/GameObjects/Components/WiresComponent.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.VendingMachines; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects; using Content.Shared.GameObjects.Components; diff --git a/Content.Server/GameObjects/EntitySystems/ActSystem.cs b/Content.Server/GameObjects/EntitySystems/ActSystem.cs index 56be8389ea..4fd95bb847 100644 --- a/Content.Server/GameObjects/EntitySystems/ActSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ActSystem.cs @@ -5,7 +5,7 @@ using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Map; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// This interface gives components behavior on getting destoyed. diff --git a/Content.Server/GameObjects/EntitySystems/BaseChargerSystem.cs b/Content.Server/GameObjects/EntitySystems/BaseChargerSystem.cs index 6e0415b6a9..7e59153404 100644 --- a/Content.Server/GameObjects/EntitySystems/BaseChargerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/BaseChargerSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] internal class BaseChargerSystem : EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/BloodstreamSystem.cs b/Content.Server/GameObjects/EntitySystems/BloodstreamSystem.cs index 7806e09b25..69b432084b 100644 --- a/Content.Server/GameObjects/EntitySystems/BloodstreamSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/BloodstreamSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// Triggers metabolism updates for diff --git a/Content.Server/GameObjects/EntitySystems/ChemistrySystem.cs b/Content.Server/GameObjects/EntitySystems/ChemistrySystem.cs index 69bd555460..39cca2be0e 100644 --- a/Content.Server/GameObjects/EntitySystems/ChemistrySystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ChemistrySystem.cs @@ -4,7 +4,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// This interface gives components behavior on whether entities solution (implying SolutionComponent is in place) is changed diff --git a/Content.Server/GameObjects/EntitySystems/Click/ExamineSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/ExamineSystem.cs index fa7fdbaf4b..1babbc6ee6 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/ExamineSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/ExamineSystem.cs @@ -9,7 +9,7 @@ using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Utility; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.GameObjects.EntitySystems.Click { public interface IExamine { @@ -62,7 +62,7 @@ namespace Content.Server.GameObjects.EntitySystems var inDetailsRange = Get() .InRangeUnobstructed(examiner.Transform.MapPosition, entity.Transform.MapPosition, - ExamineDetailsRange, predicate: entity0 => entity0 == examiner || entity0 == entity, insideBlockerValid: true); + ExamineDetailsRange, predicate: entity0 => entity0 == examiner || entity0 == entity, ignoreInsideBlocker: true); //Add component statuses from components that report one foreach (var examineComponent in entity.GetAllComponents()) diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index c92df5fcc5..15ec860880 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -3,8 +3,10 @@ using System.Linq; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Timing; using Content.Server.Interfaces.GameObjects; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Utility; using Content.Shared.GameObjects.Components.Inventory; +using Content.Shared.GameObjects.EntitySystemMessages; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Input; using JetBrains.Annotations; @@ -18,294 +20,14 @@ using Robust.Shared.Input.Binding; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects.Components; using Robust.Shared.Interfaces.Map; -using Robust.Shared.Interfaces.Physics; using Robust.Shared.IoC; -using Robust.Shared.Localization; using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Players; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.GameObjects.EntitySystems.Click { - /// - /// This interface gives components behavior when being clicked on by a user with an object in their hand - /// who is in range and has unobstructed reach of the target entity (allows inside blockers). - /// - public interface IInteractUsing - { - /// - /// Called when using one object on another when user is in range of the target entity. - /// - bool InteractUsing(InteractUsingEventArgs eventArgs); - } - - public class InteractUsingEventArgs : EventArgs, ITargetedInteractEventArgs - { - public IEntity User { get; set; } - public GridCoordinates ClickLocation { get; set; } - public IEntity Using { get; set; } - public IEntity Target { get; set; } - } - - public interface ITargetedInteractEventArgs - { - /// - /// Performer of the attack - /// - IEntity User { get; } - /// - /// Target of the attack - /// - IEntity Target { get; } - - } - - /// - /// This interface gives components behavior when being clicked on by a user with an empty hand - /// who is in range and has unobstructed reach of the target entity (allows inside blockers). - /// - public interface IInteractHand - { - /// - /// Called when a player directly interacts with an empty hand when user is in range of the target entity. - /// - bool InteractHand(InteractHandEventArgs eventArgs); - } - - public class InteractHandEventArgs : EventArgs, ITargetedInteractEventArgs - { - public IEntity User { get; set; } - public IEntity Target { get; set; } - } - - /// - /// This interface gives components behavior when being clicked on by a user with an object - /// outside the range of direct use - /// - public interface IRangedInteract - { - /// - /// Called when we try to interact with an entity out of range - /// - /// - bool RangedInteract(RangedInteractEventArgs eventArgs); - } - - [PublicAPI] - public class RangedInteractEventArgs : EventArgs - { - public IEntity User { get; set; } - public IEntity Using { get; set; } - public GridCoordinates ClickLocation { get; set; } - } - - /// - /// This interface gives components a behavior when clicking on another object and no interaction occurs, - /// at any range. - /// - public interface IAfterInteract - { - /// - /// Called when we interact with nothing, or when we interact with an entity out of range that has no behavior - /// - void AfterInteract(AfterInteractEventArgs eventArgs); - } - - public class AfterInteractEventArgs : EventArgs - { - public IEntity User { get; set; } - public GridCoordinates ClickLocation { get; set; } - public IEntity Target { get; set; } - } - - /// - /// This interface gives components behavior when using the entity in your hands - /// - public interface IUse - { - /// - /// Called when we activate an object we are holding to use it - /// - /// - bool UseEntity(UseEntityEventArgs eventArgs); - } - - public class UseEntityEventArgs : EventArgs - { - public IEntity User { get; set; } - } - - /// - /// This interface gives components behavior when being activated in the world when the user - /// is in range and has unobstructed access to the target entity (allows inside blockers). - /// - public interface IActivate - { - /// - /// Called when this component is activated by another entity who is in range. - /// - void Activate(ActivateEventArgs eventArgs); - } - - public class ActivateEventArgs : EventArgs, ITargetedInteractEventArgs - { - public IEntity User { get; set; } - public IEntity Target { get; set; } - } - - /// - /// This interface gives components behavior when thrown. - /// - public interface IThrown - { - void Thrown(ThrownEventArgs eventArgs); - } - - public class ThrownEventArgs : EventArgs - { - public ThrownEventArgs(IEntity user) - { - User = user; - } - - public IEntity User { get; } - } - - /// - /// This interface gives components behavior when landing after being thrown. - /// - public interface ILand - { - void Land(LandEventArgs eventArgs); - } - - public class LandEventArgs : EventArgs - { - public LandEventArgs(IEntity user, GridCoordinates landingLocation) - { - User = user; - LandingLocation = landingLocation; - } - - public IEntity User { get; } - public GridCoordinates LandingLocation { get; } - } - - /// - /// This interface gives components behavior when their owner is put in an inventory slot. - /// - public interface IEquipped - { - void Equipped(EquippedEventArgs eventArgs); - } - - public class EquippedEventArgs : EventArgs - { - public EquippedEventArgs(IEntity user, EquipmentSlotDefines.Slots slot) - { - User = user; - Slot = slot; - } - - public IEntity User { get; } - public EquipmentSlotDefines.Slots Slot { get; } - } - - /// - /// This interface gives components behavior when their owner is removed from an inventory slot. - /// - public interface IUnequipped - { - void Unequipped(UnequippedEventArgs eventArgs); - } - - public class UnequippedEventArgs : EventArgs - { - public UnequippedEventArgs(IEntity user, EquipmentSlotDefines.Slots slot) - { - User = user; - Slot = slot; - } - - public IEntity User { get; } - public EquipmentSlotDefines.Slots Slot { get; } - } - - /// - /// This interface gives components behavior when being used to "attack". - /// - public interface IAttack - { - void Attack(AttackEventArgs eventArgs); - } - - public class AttackEventArgs : EventArgs - { - public AttackEventArgs(IEntity user, GridCoordinates clickLocation) - { - User = user; - ClickLocation = clickLocation; - } - - public IEntity User { get; } - public GridCoordinates ClickLocation { get; } - } - - /// - /// This interface gives components behavior when they're held on the selected hand. - /// - public interface IHandSelected - { - void HandSelected(HandSelectedEventArgs eventArgs); - } - - public class HandSelectedEventArgs : EventArgs - { - public HandSelectedEventArgs(IEntity user) - { - User = user; - } - - public IEntity User { get; } - } - - /// - /// This interface gives components behavior when they're held on a deselected hand. - /// - public interface IHandDeselected - { - void HandDeselected(HandDeselectedEventArgs eventArgs); - } - - public class HandDeselectedEventArgs : EventArgs - { - public HandDeselectedEventArgs(IEntity user) - { - User = user; - } - - public IEntity User { get; } - } - - /// - /// This interface gives components behavior when they're dropped by a mob. - /// - public interface IDropped - { - void Dropped(DroppedEventArgs eventArgs); - } - - public class DroppedEventArgs : EventArgs - { - public DroppedEventArgs(IEntity user) - { - User = user; - } - - public IEntity User { get; } - } - /// /// Governs interactions during clicking on entities /// @@ -318,6 +40,8 @@ namespace Content.Server.GameObjects.EntitySystems public override void Initialize() { + SubscribeNetworkEvent(HandleDragDropMessage); + CommandBinds.Builder .Bind(EngineKeyFunctions.Use, new PointerInputCmdHandler(HandleClientUseItemInHand)) @@ -334,6 +58,30 @@ namespace Content.Server.GameObjects.EntitySystems base.Shutdown(); } + private void HandleDragDropMessage(DragDropMessage msg, EntitySessionEventArgs args) + { + var performer = args.SenderSession.AttachedEntity; + if (!EntityManager.TryGetEntity(msg.Dropped, out var dropped)) return; + if (!EntityManager.TryGetEntity(msg.Target, out var target)) return; + + var interactionArgs = new DragDropEventArgs(performer, msg.DropLocation, dropped, target); + + // must be in range of both the target and the object they are drag / dropping + if (!InteractionChecks.InRangeUnobstructed(interactionArgs)) return; + + // trigger dragdrops on the dropped entity + foreach (var dragDrop in dropped.GetAllComponents()) + { + if (dragDrop.DragDrop(interactionArgs)) return; + } + + // trigger dragdropons on the targeted entity + foreach (var dragDropOn in target.GetAllComponents()) + { + if (dragDropOn.DragDropOn(interactionArgs)) return; + } + } + private bool HandleActivateItemInWorld(ICommonSession session, GridCoordinates coords, EntityUid uid) { if (!EntityManager.TryGetEntity(uid, out var used)) @@ -572,7 +320,7 @@ namespace Content.Server.GameObjects.EntitySystems /// private void InteractAfter(IEntity user, IEntity weapon, GridCoordinates clickLocation) { - var message = new AfterAttackMessage(user, weapon, null, clickLocation); + var message = new AfterInteractMessage(user, weapon, null, clickLocation); RaiseLocalEvent(message); if (message.Handled) { @@ -594,7 +342,7 @@ namespace Content.Server.GameObjects.EntitySystems /// public void Interaction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clickLocation) { - var attackMsg = new AttackByMessage(user, weapon, attacked, clickLocation); + var attackMsg = new InteractUsingMessage(user, weapon, attacked, clickLocation); RaiseLocalEvent(attackMsg); if (attackMsg.Handled) { @@ -620,7 +368,7 @@ namespace Content.Server.GameObjects.EntitySystems } } - var afterAtkMsg = new AfterAttackMessage(user, weapon, attacked, clickLocation); + var afterAtkMsg = new AfterInteractMessage(user, weapon, attacked, clickLocation); RaiseLocalEvent(afterAtkMsg); if (afterAtkMsg.Handled) { @@ -906,7 +654,7 @@ namespace Content.Server.GameObjects.EntitySystems /// public void RangedInteraction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clickLocation) { - var rangedMsg = new RangedAttackMessage(user, weapon, attacked, clickLocation); + var rangedMsg = new RangedInteractMessage(user, weapon, attacked, clickLocation); RaiseLocalEvent(rangedMsg); if (rangedMsg.Handled) return; @@ -927,7 +675,7 @@ namespace Content.Server.GameObjects.EntitySystems } } - var afterAtkMsg = new AfterAttackMessage(user, weapon, attacked, clickLocation); + var afterAtkMsg = new AfterInteractMessage(user, weapon, attacked, clickLocation); RaiseLocalEvent(afterAtkMsg); if (afterAtkMsg.Handled) return; @@ -988,422 +736,4 @@ namespace Content.Server.GameObjects.EntitySystems } } } - - /// - /// Raised when being clicked on or "attacked" by a user with an object in their hand - /// - [PublicAPI] - public class AttackByMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that triggered the attack. - /// - public IEntity User { get; } - - /// - /// Entity that the User attacked with. - /// - public IEntity ItemInHand { get; } - - /// - /// Entity that was attacked. - /// - public IEntity Attacked { get; } - - /// - /// The original location that was clicked by the user. - /// - public GridCoordinates ClickLocation { get; } - - public AttackByMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) - { - User = user; - ItemInHand = itemInHand; - Attacked = attacked; - ClickLocation = clickLocation; - } - } - - /// - /// Raised when being clicked on or "attacked" by a user with an empty hand. - /// - [PublicAPI] - public class AttackHandMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that triggered the attack. - /// - public IEntity User { get; } - - /// - /// Entity that was attacked. - /// - public IEntity Attacked { get; } - - public AttackHandMessage(IEntity user, IEntity attacked) - { - User = user; - Attacked = attacked; - } - } - - /// - /// Raised when being clicked by objects outside the range of direct use. - /// - [PublicAPI] - public class RangedAttackMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that triggered the attack. - /// - public IEntity User { get; } - - /// - /// Entity that the User attacked with. - /// - public IEntity ItemInHand { get; set; } - - /// - /// Entity that was attacked. - /// - public IEntity Attacked { get; } - - /// - /// Location that the user clicked outside of their interaction range. - /// - public GridCoordinates ClickLocation { get; } - - public RangedAttackMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) - { - User = user; - ItemInHand = itemInHand; - ClickLocation = clickLocation; - Attacked = attacked; - } - } - - /// - /// Raised when clicking on another object and no attack event was handled. - /// - [PublicAPI] - public class AfterAttackMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that triggered the attack. - /// - public IEntity User { get; } - - /// - /// Entity that the User attacked with. - /// - public IEntity ItemInHand { get; set; } - - /// - /// Entity that was attacked. This can be null if the attack did not click on an entity. - /// - public IEntity Attacked { get; } - - /// - /// Location that the user clicked outside of their interaction range. - /// - public GridCoordinates ClickLocation { get; } - - public AfterAttackMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) - { - User = user; - Attacked = attacked; - ClickLocation = clickLocation; - ItemInHand = itemInHand; - } - } - - /// - /// Raised when using the entity in your hands. - /// - [PublicAPI] - public class UseInHandMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity holding the item in their hand. - /// - public IEntity User { get; } - - /// - /// Item that was used. - /// - public IEntity Used { get; } - - public UseInHandMessage(IEntity user, IEntity used) - { - User = user; - Used = used; - } - } - - /// - /// Raised when throwing the entity in your hands. - /// - [PublicAPI] - public class ThrownMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that threw the item. - /// - public IEntity User { get; } - - /// - /// Item that was thrown. - /// - public IEntity Thrown { get; } - - public ThrownMessage(IEntity user, IEntity thrown) - { - User = user; - Thrown = thrown; - } - } - - /// - /// Raised when an entity that was thrown lands. - /// - [PublicAPI] - public class LandMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that threw the item. - /// - public IEntity User { get; } - - /// - /// Item that was thrown. - /// - public IEntity Thrown { get; } - - /// - /// Location where the item landed. - /// - public GridCoordinates LandLocation { get; } - - public LandMessage(IEntity user, IEntity thrown, GridCoordinates landLocation) - { - User = user; - Thrown = thrown; - LandLocation = landLocation; - } - } - - /// - /// Raised when equipping the entity in an inventory slot. - /// - [PublicAPI] - public class EquippedMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that equipped the item. - /// - public IEntity User { get; } - - /// - /// Item that was equipped. - /// - public IEntity Equipped { get; } - - /// - /// Slot where the item was placed. - /// - public EquipmentSlotDefines.Slots Slot { get; } - - public EquippedMessage(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) - { - User = user; - Equipped = equipped; - Slot = slot; - } - } - - /// - /// Raised when removing the entity from an inventory slot. - /// - [PublicAPI] - public class UnequippedMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that equipped the item. - /// - public IEntity User { get; } - - /// - /// Item that was equipped. - /// - public IEntity Equipped { get; } - - /// - /// Slot where the item was removed from. - /// - public EquipmentSlotDefines.Slots Slot { get; } - - public UnequippedMessage(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) - { - User = user; - Equipped = equipped; - Slot = slot; - } - } - - /// - /// Raised when an entity that was thrown lands. - /// - [PublicAPI] - public class DroppedMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that dropped the item. - /// - public IEntity User { get; } - - /// - /// Item that was dropped. - /// - public IEntity Dropped { get; } - - public DroppedMessage(IEntity user, IEntity dropped) - { - User = user; - Dropped = dropped; - } - } - - /// - /// Raised when an entity item in a hand is selected. - /// - [PublicAPI] - public class HandSelectedMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that owns the selected hand. - /// - public IEntity User { get; } - - /// - /// The item in question. - /// - public IEntity Item { get; } - - public HandSelectedMessage(IEntity user, IEntity item) - { - User = user; - Item = item; - } - } - - /// - /// Raised when an entity item in a hand is deselected. - /// - [PublicAPI] - public class HandDeselectedMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that owns the deselected hand. - /// - public IEntity User { get; } - - /// - /// The item in question. - /// - public IEntity Item { get; } - - public HandDeselectedMessage(IEntity user, IEntity item) - { - User = user; - Item = item; - } - } - - /// - /// Raised when an entity is activated in the world. - /// - [PublicAPI] - public class ActivateInWorldMessage : EntitySystemMessage - { - /// - /// If this message has already been "handled" by a previous system. - /// - public bool Handled { get; set; } - - /// - /// Entity that activated the world entity. - /// - public IEntity User { get; } - - /// - /// Entity that was activated in the world. - /// - public IEntity Activated { get; } - - public ActivateInWorldMessage(IEntity user, IEntity activated) - { - User = user; - Activated = activated; - } - } } diff --git a/Content.Server/GameObjects/EntitySystems/CombatModeSystem.cs b/Content.Server/GameObjects/EntitySystems/CombatModeSystem.cs index 926dbc15a2..f8fd65915e 100644 --- a/Content.Server/GameObjects/EntitySystems/CombatModeSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/CombatModeSystem.cs @@ -11,7 +11,7 @@ using Robust.Shared.Log; using Robust.Shared.Players; using Robust.Shared.Random; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] public sealed class CombatModeSystem : SharedCombatModeSystem diff --git a/Content.Server/GameObjects/EntitySystems/ConstructionSystem.cs b/Content.Server/GameObjects/EntitySystems/ConstructionSystem.cs index 7e656d7cd1..b3c390909a 100644 --- a/Content.Server/GameObjects/EntitySystems/ConstructionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ConstructionSystem.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Construction; using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Stack; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces; using Content.Server.Utility; using Content.Shared.Construction; @@ -52,7 +53,7 @@ namespace Content.Server.GameObjects.EntitySystems SubscribeNetworkEvent(HandleStartStructureConstruction); SubscribeNetworkEvent(HandleStartItemConstruction); - SubscribeLocalEvent(HandleToolInteraction); + SubscribeLocalEvent(HandleToolInteraction); } private void HandleStartStructureConstruction(TryStartStructureConstructionMessage msg, EntitySessionEventArgs args) @@ -71,7 +72,7 @@ namespace Content.Server.GameObjects.EntitySystems TryStartItemConstruction(placingEnt, msg.PrototypeName); } - private void HandleToolInteraction(AfterAttackMessage msg) + private void HandleToolInteraction(AfterInteractMessage msg) { if(msg.Handled) return; @@ -238,7 +239,7 @@ namespace Content.Server.GameObjects.EntitySystems var prototype = _prototypeManager.Index(prototypeName); if (!InteractionChecks.InRangeUnobstructed(placingEnt, loc.ToMap(_mapManager), - ignoredEnt: placingEnt, insideBlockerValid: prototype.CanBuildInImpassable)) + ignoredEnt: placingEnt, ignoreInsideBlocker: prototype.CanBuildInImpassable)) { return false; } @@ -436,7 +437,7 @@ namespace Content.Server.GameObjects.EntitySystems { return false; } - + var sound = EntitySystemManager.GetEntitySystem(); switch (step) diff --git a/Content.Server/GameObjects/EntitySystems/DoorSystem.cs b/Content.Server/GameObjects/EntitySystems/DoorSystem.cs index 4455f8b3a7..fbe47ad5cc 100644 --- a/Content.Server/GameObjects/EntitySystems/DoorSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/DoorSystem.cs @@ -1,7 +1,8 @@ -using Robust.Shared.GameObjects; +using Content.Server.GameObjects; +using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { class DoorSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/GravitySystem.cs b/Content.Server/GameObjects/EntitySystems/GravitySystem.cs index d257bcec53..27eb28a6c5 100644 --- a/Content.Server/GameObjects/EntitySystems/GravitySystem.cs +++ b/Content.Server/GameObjects/EntitySystems/GravitySystem.cs @@ -16,7 +16,7 @@ using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Random; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] public class GravitySystem: EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/HandHeldLightSystem.cs b/Content.Server/GameObjects/EntitySystems/HandHeldLightSystem.cs index a6df7eaae8..8dd40458c3 100644 --- a/Content.Server/GameObjects/EntitySystems/HandHeldLightSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/HandHeldLightSystem.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.Interactable; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class HandHeldLightSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/HandsSystem.cs b/Content.Server/GameObjects/EntitySystems/HandsSystem.cs index a78c90043a..7cb3f9481c 100644 --- a/Content.Server/GameObjects/EntitySystems/HandsSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/HandsSystem.cs @@ -19,8 +19,10 @@ using Robust.Shared.Map; using Robust.Shared.Players; using System; using Content.Shared.GameObjects.EntitySystems; +using Content.Server.GameObjects; +using Content.Server.GameObjects.EntitySystems.Click; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] internal sealed class HandsSystem : EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/HungerSystem.cs b/Content.Server/GameObjects/EntitySystems/HungerSystem.cs index 671bc7f051..08d2c9bf98 100644 --- a/Content.Server/GameObjects/EntitySystems/HungerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/HungerSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] public class HungerSystem : EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/InstrumentSystem.cs b/Content.Server/GameObjects/EntitySystems/InstrumentSystem.cs index a64f1fec01..61e0b598a4 100644 --- a/Content.Server/GameObjects/EntitySystems/InstrumentSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/InstrumentSystem.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.Instruments; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class InstrumentSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/LatheSystem.cs b/Content.Server/GameObjects/EntitySystems/LatheSystem.cs index b85a251a4a..7c39ae0cc3 100644 --- a/Content.Server/GameObjects/EntitySystems/LatheSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/LatheSystem.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.Research; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class LatheSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs b/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs index 54c90381c0..8dc8379b0d 100644 --- a/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MedicalScannerSystem.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.Medical; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class MedicalScannerSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs index 82ba72537a..9dfd278add 100644 --- a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -5,7 +5,7 @@ using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Maths; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public sealed class MeleeWeaponSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/MicrowaveSystem.cs b/Content.Server/GameObjects/EntitySystems/MicrowaveSystem.cs index 0e5c1f782d..8bb7d80bdd 100644 --- a/Content.Server/GameObjects/EntitySystems/MicrowaveSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MicrowaveSystem.cs @@ -2,7 +2,7 @@ using Content.Server.GameObjects.Components.Kitchen; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class MicrowaveSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/MoverSystem.cs b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs index f33243f5be..626e86a18e 100644 --- a/Content.Server/GameObjects/EntitySystems/MoverSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs @@ -1,4 +1,5 @@ -using Content.Server.GameObjects.Components; +using Content.Server.GameObjects; +using Content.Server.GameObjects.Components; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Movement; using Content.Server.GameObjects.Components.Sound; diff --git a/Content.Server/GameObjects/EntitySystems/PortalSystem.cs b/Content.Server/GameObjects/EntitySystems/PortalSystem.cs index 77eaf9bdcd..7ffc532422 100644 --- a/Content.Server/GameObjects/EntitySystems/PortalSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/PortalSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] public class PortalSystem : EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/PowerApcSystem.cs b/Content.Server/GameObjects/EntitySystems/PowerApcSystem.cs index 00e0ed20f1..cbaaaa981e 100644 --- a/Content.Server/GameObjects/EntitySystems/PowerApcSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/PowerApcSystem.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using Robust.Shared.IoC; using Robust.Server.Interfaces.Timing; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public sealed class ApcSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/PowerSmesSystem.cs b/Content.Server/GameObjects/EntitySystems/PowerSmesSystem.cs index db0068fec6..84f87f76b7 100644 --- a/Content.Server/GameObjects/EntitySystems/PowerSmesSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/PowerSmesSystem.cs @@ -2,7 +2,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { internal class PowerSmesSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/PowerSolarSystem.cs b/Content.Server/GameObjects/EntitySystems/PowerSolarSystem.cs index fc01bada12..604e475d9c 100644 --- a/Content.Server/GameObjects/EntitySystems/PowerSolarSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/PowerSolarSystem.cs @@ -16,7 +16,7 @@ using CannyFastMath; using Math = CannyFastMath.Math; using MathF = CannyFastMath.MathF; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// Responsible for maintaining the solar-panel sun angle and updating coverage. diff --git a/Content.Server/GameObjects/EntitySystems/ProjectileSystem.cs b/Content.Server/GameObjects/EntitySystems/ProjectileSystem.cs index a1e4713aa5..6dd87f8b24 100644 --- a/Content.Server/GameObjects/EntitySystems/ProjectileSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ProjectileSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] internal sealed class ProjectileSystem : EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/PuddleSystem.cs b/Content.Server/GameObjects/EntitySystems/PuddleSystem.cs index 4cb51c3f6e..77133b8462 100644 --- a/Content.Server/GameObjects/EntitySystems/PuddleSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/PuddleSystem.cs @@ -6,7 +6,7 @@ using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; using Robust.Shared.Map; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class PuddleSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/ResearchSystem.cs b/Content.Server/GameObjects/EntitySystems/ResearchSystem.cs index 6e4734139b..e67bd34895 100644 --- a/Content.Server/GameObjects/EntitySystems/ResearchSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ResearchSystem.cs @@ -4,7 +4,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class ResearchSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/RoundEndSystem.cs b/Content.Server/GameObjects/EntitySystems/RoundEndSystem.cs index 9077e94184..485ccb6b6f 100644 --- a/Content.Server/GameObjects/EntitySystems/RoundEndSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/RoundEndSystem.cs @@ -6,7 +6,7 @@ using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; using Timer = Robust.Shared.Timers.Timer; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class RoundEndSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/StomachSystem.cs b/Content.Server/GameObjects/EntitySystems/StomachSystem.cs index 9e7e12aac7..bbdc796c98 100644 --- a/Content.Server/GameObjects/EntitySystems/StomachSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/StomachSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// Triggers digestion updates on diff --git a/Content.Server/GameObjects/EntitySystems/StorageSystem.cs b/Content.Server/GameObjects/EntitySystems/StorageSystem.cs index 9a57e99fe9..867c7dc50c 100644 --- a/Content.Server/GameObjects/EntitySystems/StorageSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/StorageSystem.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; +using Content.Server.GameObjects; +using Content.Server.GameObjects.EntitySystems.Click; using Robust.Server.GameObjects.EntitySystemMessages; using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { class StorageSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/StunSystem.cs b/Content.Server/GameObjects/EntitySystems/StunSystem.cs index fea2a19502..ad5db08de4 100644 --- a/Content.Server/GameObjects/EntitySystems/StunSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/StunSystem.cs @@ -4,7 +4,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class StunSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs b/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs index 76ddd151e3..a60c561bdf 100644 --- a/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs @@ -1,7 +1,8 @@ -using Robust.Shared.GameObjects; +using Content.Server.GameObjects; +using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { class TemperatureSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/ThirstSystem.cs b/Content.Server/GameObjects/EntitySystems/ThirstSystem.cs index 1312b4e8ac..fa2b860f70 100644 --- a/Content.Server/GameObjects/EntitySystems/ThirstSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ThirstSystem.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { [UsedImplicitly] public class ThirstSystem : EntitySystem diff --git a/Content.Server/GameObjects/EntitySystems/TriggerSystem.cs b/Content.Server/GameObjects/EntitySystems/TriggerSystem.cs index 79b306c7d1..5a8bba0802 100644 --- a/Content.Server/GameObjects/EntitySystems/TriggerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/TriggerSystem.cs @@ -5,7 +5,7 @@ using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Timers; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// This interface gives components behavior when being "triggered" by timer or other conditions @@ -50,4 +50,4 @@ namespace Content.Server.GameObjects.EntitySystems }); } } -} \ No newline at end of file +} diff --git a/Content.Server/GameObjects/EntitySystems/VerbSystem.cs b/Content.Server/GameObjects/EntitySystems/VerbSystem.cs index 3a19749cc8..047a16c7c6 100644 --- a/Content.Server/GameObjects/EntitySystems/VerbSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/VerbSystem.cs @@ -8,7 +8,7 @@ using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using static Content.Shared.GameObjects.EntitySystemMessages.VerbSystemMessages; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class VerbSystem : EntitySystem { diff --git a/Content.Server/GameObjects/EntitySystems/WelderSystem.cs b/Content.Server/GameObjects/EntitySystems/WelderSystem.cs index 411e3546fc..e35cb6144a 100644 --- a/Content.Server/GameObjects/EntitySystems/WelderSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/WelderSystem.cs @@ -3,7 +3,7 @@ using System.Linq; using Content.Server.GameObjects.Components.Interactable; using Robust.Shared.GameObjects.Systems; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { /// /// Despite the name, it's only really used for the welder logic in tools. Go figure. diff --git a/Content.Server/GameObjects/EntitySystems/WireHackingSystem.cs b/Content.Server/GameObjects/EntitySystems/WireHackingSystem.cs index f13ae1c0a4..a8da8aff92 100644 --- a/Content.Server/GameObjects/EntitySystems/WireHackingSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/WireHackingSystem.cs @@ -3,7 +3,7 @@ using Robust.Shared.GameObjects.Systems; using Robust.Shared.ViewVariables; using static Content.Shared.GameObjects.Components.SharedWiresComponent; -namespace Content.Server.GameObjects.EntitySystems +namespace Content.Server.Interfaces.GameObjects.Components.Interaction { public class WireHackingSystem : EntitySystem { diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 759914db40..8dca1a22a1 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -9,6 +9,7 @@ using Content.Server.GameObjects.Components.Markers; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Observer; using Content.Server.GameObjects.Components.PDA; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems.AI.Pathfinding; using Content.Server.GameTicking.GamePresets; diff --git a/Content.Server/Health/BodySystem/BodyManagerComponent.cs b/Content.Server/Health/BodySystem/BodyManagerComponent.cs index 0c491f02e4..c7e299b1f8 100644 --- a/Content.Server/Health/BodySystem/BodyManagerComponent.cs +++ b/Content.Server/Health/BodySystem/BodyManagerComponent.cs @@ -9,7 +9,7 @@ using Robust.Shared.ViewVariables; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Map; using System.Linq; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; namespace Content.Server.BodySystem { diff --git a/Content.Server/Health/BodySystem/BodyPart/DroppedBodyPartComponent.cs b/Content.Server/Health/BodySystem/BodyPart/DroppedBodyPartComponent.cs index cb83dfea3f..ffad52bc07 100644 --- a/Content.Server/Health/BodySystem/BodyPart/DroppedBodyPartComponent.cs +++ b/Content.Server/Health/BodySystem/BodyPart/DroppedBodyPartComponent.cs @@ -15,6 +15,7 @@ using Robust.Server.Interfaces.Player; using Content.Shared.Interfaces; using Robust.Shared.Interfaces.Random; using System.Linq; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.Localization; namespace Content.Server.BodySystem @@ -22,7 +23,7 @@ namespace Content.Server.BodySystem /// /// Component representing a dropped, tangible entity. - /// + /// [RegisterComponent] public class DroppedBodyPartComponent : Component, IAfterInteract, IBodyPartContainer { diff --git a/Content.Server/Health/BodySystem/BodyScanner/BodyScannerComponent.cs b/Content.Server/Health/BodySystem/BodyScanner/BodyScannerComponent.cs index f28f683e9b..4fe2a5f309 100644 --- a/Content.Server/Health/BodySystem/BodyScanner/BodyScannerComponent.cs +++ b/Content.Server/Health/BodySystem/BodyScanner/BodyScannerComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Server.GameObjects.Components.UserInterface; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/Health/BodySystem/Mechanism/DroppedMechanismComponent.cs b/Content.Server/Health/BodySystem/Mechanism/DroppedMechanismComponent.cs index cf93a592a0..32c788d233 100644 --- a/Content.Server/Health/BodySystem/Mechanism/DroppedMechanismComponent.cs +++ b/Content.Server/Health/BodySystem/Mechanism/DroppedMechanismComponent.cs @@ -16,13 +16,14 @@ using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.Random; using Robust.Shared.Interfaces.GameObjects; using System.Diagnostics; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.Localization; namespace Content.Server.BodySystem { /// /// Component representing a dropped, tangible entity. - /// + /// [RegisterComponent] public class DroppedMechanismComponent : Component, IAfterInteract { @@ -130,7 +131,7 @@ namespace Content.Server.BodySystem { } /// - /// Called after the client chooses from a list of possible BodyParts that can be operated on. + /// Called after the client chooses from a list of possible BodyParts that can be operated on. /// private void HandleReceiveBodyPart(int key) { diff --git a/Content.Server/Health/BodySystem/Surgery/Surgeon/SurgeryToolComponent.cs b/Content.Server/Health/BodySystem/Surgery/Surgeon/SurgeryToolComponent.cs index 457a9fb55c..d908a053fe 100644 --- a/Content.Server/Health/BodySystem/Surgery/Surgeon/SurgeryToolComponent.cs +++ b/Content.Server/Health/BodySystem/Surgery/Surgeon/SurgeryToolComponent.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.BodySystem; using Content.Shared.GameObjects; using Content.Shared.Interfaces; @@ -65,7 +66,7 @@ namespace Content.Server.BodySystem { var toSend = new Dictionary(); //Create dictionary to send to client (text to be shown : data sent back if selected) foreach (var(key, value) in bodyManager.PartDictionary) { //For each limb in the target, add it to our cache if it is a valid option. - if (value.SurgeryCheck(_surgeryType)) + if (value.SurgeryCheck(_surgeryType)) { _optionsCache.Add(_idHash, value); toSend.Add(key + ": " + value.Name, _idHash++); @@ -171,7 +172,7 @@ namespace Content.Server.BodySystem } /// - /// Called after the client chooses from a list of possible BodyParts that can be operated on. + /// Called after the client chooses from a list of possible BodyParts that can be operated on. /// private void HandleReceiveBodyPart(int key) { diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IActivate.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IActivate.cs new file mode 100644 index 0000000000..13e8c171ab --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IActivate.cs @@ -0,0 +1,53 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when being activated in the world when the user + /// is in range and has unobstructed access to the target entity (allows inside blockers). + /// + public interface IActivate + { + /// + /// Called when this component is activated by another entity who is in range. + /// + void Activate(ActivateEventArgs eventArgs); + } + + public class ActivateEventArgs : EventArgs, ITargetedInteractEventArgs + { + public IEntity User { get; set; } + public IEntity Target { get; set; } + } + + /// + /// Raised when an entity is activated in the world. + /// + [PublicAPI] + public class ActivateInWorldMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that activated the world entity. + /// + public IEntity User { get; } + + /// + /// Entity that was activated in the world. + /// + public IEntity Activated { get; } + + public ActivateInWorldMessage(IEntity user, IEntity activated) + { + User = user; + Activated = activated; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IAfterInteract.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IAfterInteract.cs new file mode 100644 index 0000000000..ed0a167850 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IAfterInteract.cs @@ -0,0 +1,68 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components a behavior when clicking on another object and no interaction occurs, + /// at any range. + /// + public interface IAfterInteract + { + /// + /// Called when we interact with nothing, or when we interact with an entity out of range that has no behavior + /// + void AfterInteract(AfterInteractEventArgs eventArgs); + } + + public class AfterInteractEventArgs : EventArgs + { + public IEntity User { get; set; } + public GridCoordinates ClickLocation { get; set; } + public IEntity Target { get; set; } + } + + /// + /// Raised when clicking on another object and no attack event was handled. + /// + [PublicAPI] + public class AfterInteractMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that the User attacked with. + /// + public IEntity ItemInHand { get; set; } + + /// + /// Entity that was attacked. This can be null if the attack did not click on an entity. + /// + public IEntity Attacked { get; } + + /// + /// Location that the user clicked outside of their interaction range. + /// + public GridCoordinates ClickLocation { get; } + + public AfterInteractMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) + { + User = user; + Attacked = attacked; + ClickLocation = clickLocation; + ItemInHand = itemInHand; + } + } + +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IAttack.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IAttack.cs new file mode 100644 index 0000000000..1df2790bcb --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IAttack.cs @@ -0,0 +1,26 @@ +using System; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when being used to "attack". + /// + public interface IAttack + { + void Attack(AttackEventArgs eventArgs); + } + + public class AttackEventArgs : EventArgs + { + public AttackEventArgs(IEntity user, GridCoordinates clickLocation) + { + User = user; + ClickLocation = clickLocation; + } + + public IEntity User { get; } + public GridCoordinates ClickLocation { get; } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDrop.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDrop.cs new file mode 100644 index 0000000000..b9d47eef12 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDrop.cs @@ -0,0 +1,40 @@ +using System; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface allows the component's entity to be dragged and dropped by mouse onto another entity and gives it + /// behavior when that occurs. + /// + public interface IDragDrop + { + /// + /// Invoked server-side when this component's entity is being dragged and dropped on another. + /// + /// There is no other server-side drag and drop check other than a range check, so make sure to validate + /// if this object can be dropped on the target object! + /// + /// true iff an interaction occurred and no further interaction should + /// be processed for this drop. + bool DragDrop(DragDropEventArgs eventArgs); + } + + public class DragDropEventArgs : EventArgs + { + public DragDropEventArgs(IEntity user, GridCoordinates dropLocation, IEntity dropped, IEntity target) + { + User = user; + DropLocation = dropLocation; + Dropped = dropped; + Target = target; + } + + public IEntity User { get; } + public GridCoordinates DropLocation { get; } + public IEntity Dropped { get; } + public IEntity Target { get; } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDropOn.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDropOn.cs new file mode 100644 index 0000000000..00ac843dda --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IDragDropOn.cs @@ -0,0 +1,24 @@ +using System; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface allows the component's entity to be dragged and dropped onto by another entity and gives it + /// behavior when that occurs. + /// + public interface IDragDropOn + { + /// + /// Invoked server-side when another entity is being dragged and dropped onto this one + /// + /// There is no other server-side drag and drop check other than a range check, so make sure to validate + /// if this object can be dropped on the dropped object! + /// + /// true iff an interaction occurred and no further interaction should + /// be processed for this drop. + bool DragDropOn(DragDropEventArgs eventArgs); + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IDropped.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IDropped.cs new file mode 100644 index 0000000000..a28c31dfe8 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IDropped.cs @@ -0,0 +1,53 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when they're dropped by a mob. + /// + public interface IDropped + { + void Dropped(DroppedEventArgs eventArgs); + } + + public class DroppedEventArgs : EventArgs + { + public DroppedEventArgs(IEntity user) + { + User = user; + } + + public IEntity User { get; } + } + + /// + /// Raised when an entity is dropped + /// + [PublicAPI] + public class DroppedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that dropped the item. + /// + public IEntity User { get; } + + /// + /// Item that was dropped. + /// + public IEntity Dropped { get; } + + public DroppedMessage(IEntity user, IEntity dropped) + { + User = user; + Dropped = dropped; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IEquipped.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IEquipped.cs new file mode 100644 index 0000000000..ce99fed577 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IEquipped.cs @@ -0,0 +1,62 @@ +using System; +using Content.Shared.GameObjects.Components.Inventory; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when their owner is put in an inventory slot. + /// + public interface IEquipped + { + void Equipped(EquippedEventArgs eventArgs); + } + + public class EquippedEventArgs : EventArgs + { + public EquippedEventArgs(IEntity user, EquipmentSlotDefines.Slots slot) + { + User = user; + Slot = slot; + } + + public IEntity User { get; } + public EquipmentSlotDefines.Slots Slot { get; } + } + + /// + /// Raised when equipping the entity in an inventory slot. + /// + [PublicAPI] + public class EquippedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that equipped the item. + /// + public IEntity User { get; } + + /// + /// Item that was equipped. + /// + public IEntity Equipped { get; } + + /// + /// Slot where the item was placed. + /// + public EquipmentSlotDefines.Slots Slot { get; } + + public EquippedMessage(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) + { + User = user; + Equipped = equipped; + Slot = slot; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IHandDeselected.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IHandDeselected.cs new file mode 100644 index 0000000000..a6e481613d --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IHandDeselected.cs @@ -0,0 +1,53 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when they're held on a deselected hand. + /// + public interface IHandDeselected + { + void HandDeselected(HandDeselectedEventArgs eventArgs); + } + + public class HandDeselectedEventArgs : EventArgs + { + public HandDeselectedEventArgs(IEntity user) + { + User = user; + } + + public IEntity User { get; } + } + + /// + /// Raised when an entity item in a hand is deselected. + /// + [PublicAPI] + public class HandDeselectedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that owns the deselected hand. + /// + public IEntity User { get; } + + /// + /// The item in question. + /// + public IEntity Item { get; } + + public HandDeselectedMessage(IEntity user, IEntity item) + { + User = user; + Item = item; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IHandSelected.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IHandSelected.cs new file mode 100644 index 0000000000..846ee64dd0 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IHandSelected.cs @@ -0,0 +1,53 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when they're held on the selected hand. + /// + public interface IHandSelected + { + void HandSelected(HandSelectedEventArgs eventArgs); + } + + public class HandSelectedEventArgs : EventArgs + { + public HandSelectedEventArgs(IEntity user) + { + User = user; + } + + public IEntity User { get; } + } + + /// + /// Raised when an entity item in a hand is selected. + /// + [PublicAPI] + public class HandSelectedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that owns the selected hand. + /// + public IEntity User { get; } + + /// + /// The item in question. + /// + public IEntity Item { get; } + + public HandSelectedMessage(IEntity user, IEntity item) + { + User = user; + Item = item; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractHand.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractHand.cs new file mode 100644 index 0000000000..b4820980bd --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractHand.cs @@ -0,0 +1,54 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when being clicked on by a user with an empty hand + /// who is in range and has unobstructed reach of the target entity (allows inside blockers). + /// + public interface IInteractHand + { + /// + /// Called when a player directly interacts with an empty hand when user is in range of the target entity. + /// + bool InteractHand(InteractHandEventArgs eventArgs); + } + + public class InteractHandEventArgs : EventArgs, ITargetedInteractEventArgs + { + public IEntity User { get; set; } + public IEntity Target { get; set; } + } + + + /// + /// Raised when being clicked on or "attacked" by a user with an empty hand. + /// + [PublicAPI] + public class AttackHandMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that was attacked. + /// + public IEntity Attacked { get; } + + public AttackHandMessage(IEntity user, IEntity attacked) + { + User = user; + Attacked = attacked; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractUsing.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractUsing.cs new file mode 100644 index 0000000000..466b984fbf --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IInteractUsing.cs @@ -0,0 +1,68 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when being clicked on by a user with an object in their hand + /// who is in range and has unobstructed reach of the target entity (allows inside blockers). + /// + public interface IInteractUsing + { + /// + /// Called when using one object on another when user is in range of the target entity. + /// + bool InteractUsing(InteractUsingEventArgs eventArgs); + } + + public class InteractUsingEventArgs : EventArgs, ITargetedInteractEventArgs + { + public IEntity User { get; set; } + public GridCoordinates ClickLocation { get; set; } + public IEntity Using { get; set; } + public IEntity Target { get; set; } + } + + /// + /// Raised when being clicked on or "attacked" by a user with an object in their hand + /// + [PublicAPI] + public class InteractUsingMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that the User attacked with. + /// + public IEntity ItemInHand { get; } + + /// + /// Entity that was attacked. + /// + public IEntity Attacked { get; } + + /// + /// The original location that was clicked by the user. + /// + public GridCoordinates ClickLocation { get; } + + public InteractUsingMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) + { + User = user; + ItemInHand = itemInHand; + Attacked = attacked; + ClickLocation = clickLocation; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/ILand.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/ILand.cs new file mode 100644 index 0000000000..1915f5fc69 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/ILand.cs @@ -0,0 +1,62 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when landing after being thrown. + /// + public interface ILand + { + void Land(LandEventArgs eventArgs); + } + + public class LandEventArgs : EventArgs + { + public LandEventArgs(IEntity user, GridCoordinates landingLocation) + { + User = user; + LandingLocation = landingLocation; + } + + public IEntity User { get; } + public GridCoordinates LandingLocation { get; } + } + + /// + /// Raised when an entity that was thrown lands. + /// + [PublicAPI] + public class LandMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that threw the item. + /// + public IEntity User { get; } + + /// + /// Item that was thrown. + /// + public IEntity Thrown { get; } + + /// + /// Location where the item landed. + /// + public GridCoordinates LandLocation { get; } + + public LandMessage(IEntity user, IEntity thrown, GridCoordinates landLocation) + { + User = user; + Thrown = thrown; + LandLocation = landLocation; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IRangedInteract.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IRangedInteract.cs new file mode 100644 index 0000000000..d1f188cd4e --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IRangedInteract.cs @@ -0,0 +1,69 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when being clicked on by a user with an object + /// outside the range of direct use + /// + public interface IRangedInteract + { + /// + /// Called when we try to interact with an entity out of range + /// + /// + bool RangedInteract(RangedInteractEventArgs eventArgs); + } + + [PublicAPI] + public class RangedInteractEventArgs : EventArgs + { + public IEntity User { get; set; } + public IEntity Using { get; set; } + public GridCoordinates ClickLocation { get; set; } + } + + /// + /// Raised when being clicked by objects outside the range of direct use. + /// + [PublicAPI] + public class RangedInteractMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that the User attacked with. + /// + public IEntity ItemInHand { get; set; } + + /// + /// Entity that was attacked. + /// + public IEntity Attacked { get; } + + /// + /// Location that the user clicked outside of their interaction range. + /// + public GridCoordinates ClickLocation { get; } + + public RangedInteractMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) + { + User = user; + ItemInHand = itemInHand; + ClickLocation = clickLocation; + Attacked = attacked; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/ITargetedInteractEventArgs.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/ITargetedInteractEventArgs.cs new file mode 100644 index 0000000000..028e3d3643 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/ITargetedInteractEventArgs.cs @@ -0,0 +1,17 @@ +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + public interface ITargetedInteractEventArgs + { + /// + /// Performer of the attack + /// + IEntity User { get; } + /// + /// Target of the attack + /// + IEntity Target { get; } + + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IThrown.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IThrown.cs new file mode 100644 index 0000000000..ca3a798963 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IThrown.cs @@ -0,0 +1,53 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when thrown. + /// + public interface IThrown + { + void Thrown(ThrownEventArgs eventArgs); + } + + public class ThrownEventArgs : EventArgs + { + public ThrownEventArgs(IEntity user) + { + User = user; + } + + public IEntity User { get; } + } + + /// + /// Raised when throwing the entity in your hands. + /// + [PublicAPI] + public class ThrownMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that threw the item. + /// + public IEntity User { get; } + + /// + /// Item that was thrown. + /// + public IEntity Thrown { get; } + + public ThrownMessage(IEntity user, IEntity thrown) + { + User = user; + Thrown = thrown; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IUnequipped.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IUnequipped.cs new file mode 100644 index 0000000000..32f2efa087 --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IUnequipped.cs @@ -0,0 +1,64 @@ +using System; +using Content.Shared.GameObjects.Components.Inventory; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when their owner is removed from an inventory slot. + /// + public interface IUnequipped + { + void Unequipped(UnequippedEventArgs eventArgs); + } + + public class UnequippedEventArgs : EventArgs + { + public UnequippedEventArgs(IEntity user, EquipmentSlotDefines.Slots slot) + { + User = user; + Slot = slot; + } + + public IEntity User { get; } + public EquipmentSlotDefines.Slots Slot { get; } + } + + /// + /// Raised when removing the entity from an inventory slot. + /// + [PublicAPI] + public class UnequippedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that equipped the item. + /// + public IEntity User { get; } + + /// + /// Item that was equipped. + /// + public IEntity Equipped { get; } + + /// + /// Slot where the item was removed from. + /// + public EquipmentSlotDefines.Slots Slot { get; } + + public UnequippedMessage(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) + { + User = user; + Equipped = equipped; + Slot = slot; + } + } + + +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Interaction/IUse.cs b/Content.Server/Interfaces/GameObjects/Components/Interaction/IUse.cs new file mode 100644 index 0000000000..6da5926e6c --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Interaction/IUse.cs @@ -0,0 +1,52 @@ +using System; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects.Components.Interaction +{ + /// + /// This interface gives components behavior when using the entity in your hands + /// + public interface IUse + { + /// + /// Called when we activate an object we are holding to use it + /// + /// + bool UseEntity(UseEntityEventArgs eventArgs); + } + + public class UseEntityEventArgs : EventArgs + { + public IEntity User { get; set; } + } + + /// + /// Raised when using the entity in your hands. + /// + [PublicAPI] + public class UseInHandMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity holding the item in their hand. + /// + public IEntity User { get; } + + /// + /// Item that was used. + /// + public IEntity Used { get; } + + public UseInHandMessage(IEntity user, IEntity used) + { + User = user; + Used = used; + } + } +} diff --git a/Content.Server/Mobs/Mind.cs b/Content.Server/Mobs/Mind.cs index 5e631f68ec..17a453b0e5 100644 --- a/Content.Server/Mobs/Mind.cs +++ b/Content.Server/Mobs/Mind.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Players; using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.Player; diff --git a/Content.Server/Mobs/Role.cs b/Content.Server/Mobs/Role.cs index d1980956a5..c5dff2391f 100644 --- a/Content.Server/Mobs/Role.cs +++ b/Content.Server/Mobs/Role.cs @@ -1,7 +1,7 @@ // Hey look, // Antag Datums. -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Robust.Shared.Utility; namespace Content.Server.Mobs diff --git a/Content.Server/Observer/Ghost.cs b/Content.Server/Observer/Ghost.cs index 31a1d42bd3..7924d9f704 100644 --- a/Content.Server/Observer/Ghost.cs +++ b/Content.Server/Observer/Ghost.cs @@ -1,6 +1,6 @@ using Content.Server.GameObjects; using Content.Server.GameObjects.Components.Observer; -using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameTicking; using Content.Server.Players; using Content.Shared.GameObjects; diff --git a/Content.Server/Utility/InteractionChecks.cs b/Content.Server/Utility/InteractionChecks.cs index 17fdf6f54b..b79952a5bb 100644 --- a/Content.Server/Utility/InteractionChecks.cs +++ b/Content.Server/Utility/InteractionChecks.cs @@ -1,6 +1,7 @@ using System; using Content.Server.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.Interfaces; using Content.Shared.Physics; using Robust.Shared.GameObjects.Systems; @@ -22,14 +23,15 @@ namespace Content.Server.Utility /// /// Default interaction check for targeted attack interaction types. - /// Same as , but defaults to allow inside blockers. + /// Same as , but defaults to ignore inside blockers + /// (making the check less restrictive). /// Validates that attacker is in range of the attacked entity. Additionally shows a popup if /// validation fails. /// - public static bool InRangeUnobstructed(ITargetedInteractEventArgs eventArgs, bool insideBlockerValid = true) + public static bool InRangeUnobstructed(ITargetedInteractEventArgs eventArgs, bool ignoreInsideBlocker = true) { if (!EntitySystem.Get().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, - eventArgs.Target.Transform.MapPosition, ignoredEnt: eventArgs.Target, insideBlockerValid: insideBlockerValid)) + eventArgs.Target.Transform.MapPosition, ignoredEnt: eventArgs.Target, ignoreInsideBlocker: ignoreInsideBlocker)) { var localizationManager = IoCManager.Resolve(); eventArgs.Target.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); @@ -39,19 +41,46 @@ namespace Content.Server.Utility return true; } + /// + /// Default interaction check for Drag drop interaction types. + /// Same as , but defaults to ignore inside blockers + /// (making the check less restrictive) and checks reachability of both the target and the dragged / dropped object. + /// Additionally shows a popup if validation fails. + /// + public static bool InRangeUnobstructed(DragDropEventArgs eventArgs, bool ignoreInsideBlocker = true) + { + if (!EntitySystem.Get().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, + eventArgs.Target.Transform.MapPosition, ignoredEnt: eventArgs.Target, ignoreInsideBlocker: ignoreInsideBlocker)) + { + var localizationManager = IoCManager.Resolve(); + eventArgs.Target.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); + return false; + } + if (!EntitySystem.Get().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, + eventArgs.Dropped.Transform.MapPosition, ignoredEnt: eventArgs.Dropped, ignoreInsideBlocker: ignoreInsideBlocker)) + { + var localizationManager = IoCManager.Resolve(); + eventArgs.Dropped.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); + return false; + } + + return true; + } + /// /// Default interaction check for after attack interaction types. - /// Same as , but defaults to allow inside blockers. + /// Same as , but defaults to ignore inside blockers + /// (making the check less restrictive). /// Validates that attacker is in range of the attacked entity, if there is such an entity. /// If there is no attacked entity, validates that they are in range of the clicked position. /// Additionally shows a popup if validation fails. /// - public static bool InRangeUnobstructed(AfterInteractEventArgs eventArgs, bool insideBlockerValid = true) + public static bool InRangeUnobstructed(AfterInteractEventArgs eventArgs, bool ignoreInsideBlocker = true) { if (eventArgs.Target != null) { if (!EntitySystem.Get().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, - eventArgs.Target.Transform.MapPosition, ignoredEnt: eventArgs.Target, insideBlockerValid: insideBlockerValid)) + eventArgs.Target.Transform.MapPosition, ignoredEnt: eventArgs.Target, ignoreInsideBlocker: ignoreInsideBlocker)) { var localizationManager = IoCManager.Resolve(); eventArgs.Target.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); @@ -61,7 +90,7 @@ namespace Content.Server.Utility else { if (!EntitySystem.Get().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, - eventArgs.ClickLocation.ToMap(IoCManager.Resolve()), ignoredEnt: eventArgs.User, insideBlockerValid: insideBlockerValid)) + eventArgs.ClickLocation.ToMap(IoCManager.Resolve()), ignoredEnt: eventArgs.User, ignoreInsideBlocker: ignoreInsideBlocker)) { var localizationManager = IoCManager.Resolve(); eventArgs.User.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); @@ -80,12 +109,12 @@ namespace Content.Server.Utility public static bool InRangeUnobstructed(IEntity user, MapCoordinates otherCoords, float range = SharedInteractionSystem.InteractionRange, int collisionMask = (int) CollisionGroup.Impassable, IEntity ignoredEnt = null, - bool insideBlockerValid = false) + bool ignoreInsideBlocker = false) { var mapManager = IoCManager.Resolve(); var interactionSystem = EntitySystem.Get(); if (!interactionSystem.InRangeUnobstructed(user.Transform.MapPosition, otherCoords, range, collisionMask, - ignoredEnt, insideBlockerValid)) + ignoredEnt, ignoreInsideBlocker)) { var localizationManager = IoCManager.Resolve(); user.PopupMessage(user, localizationManager.GetString("You can't reach there!")); diff --git a/Content.Shared/GameObjects/Components/SharedPlaceableSurfaceComponent.cs b/Content.Shared/GameObjects/Components/SharedPlaceableSurfaceComponent.cs new file mode 100644 index 0000000000..2461021357 --- /dev/null +++ b/Content.Shared/GameObjects/Components/SharedPlaceableSurfaceComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameObjects; + +namespace Content.Shared.GameObjects.Components +{ + public abstract class SharedPlaceableSurfaceComponent : Component + { + public override string Name => "PlaceableSurface"; + } +} diff --git a/Content.Shared/GameObjects/EntitySystemMessages/DragDropMessage.cs b/Content.Shared/GameObjects/EntitySystemMessages/DragDropMessage.cs new file mode 100644 index 0000000000..8b5648e401 --- /dev/null +++ b/Content.Shared/GameObjects/EntitySystemMessages/DragDropMessage.cs @@ -0,0 +1,25 @@ +using System; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.EntitySystemMessages +{ + /// + /// Requests a drag / drop interaction to be performed + /// + [Serializable, NetSerializable] + public class DragDropMessage : EntitySystemMessage + { + public GridCoordinates DropLocation { get; } + public EntityUid Dropped { get; } + public EntityUid Target { get; } + + public DragDropMessage(GridCoordinates dropLocation, EntityUid dropped, EntityUid target) + { + DropLocation = dropLocation; + Dropped = dropped; + Target = target; + } + } +} diff --git a/Content.Shared/GameObjects/EntitySystems/ExamineSystemShared.cs b/Content.Shared/GameObjects/EntitySystems/ExamineSystemShared.cs index 80f4c88e7c..9b1946fc6f 100644 --- a/Content.Shared/GameObjects/EntitySystems/ExamineSystemShared.cs +++ b/Content.Shared/GameObjects/EntitySystems/ExamineSystemShared.cs @@ -2,7 +2,6 @@ using Content.Shared.GameObjects.Components.Mobs; using JetBrains.Annotations; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Utility; namespace Content.Shared.GameObjects.EntitySystems { @@ -31,7 +30,7 @@ namespace Content.Shared.GameObjects.EntitySystems return EntitySystem.Get() .InRangeUnobstructed(examiner.Transform.MapPosition, examined.Transform.MapPosition, - ExamineRange, predicate: entity => entity == examiner || entity == examined, insideBlockerValid:true); + ExamineRange, predicate: entity => entity == examiner || entity == examined, ignoreInsideBlocker:true); } } } diff --git a/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs index 872cddbc5f..ca1fc0a5b9 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs @@ -72,10 +72,13 @@ namespace Content.Shared.GameObjects.EntitySystems /// maximum distance between the two sets of coordinates. /// the mask to check for collisions /// A predicate to check whether to ignore an entity or not. If it returns true, it will be ignored. - /// if coordinates inside obstructions count as obstructed or not + /// if true and the coordinates are inside the obstruction, ignores the obstruction and + /// considers the interaction unobstructed. Therefore, setting this to true makes this check more permissive, such + /// as allowing an interaction to occur inside something impassable (like a wall). The default, false, + /// makes the check more restrictive. /// True if the two points are within a given range without being obstructed. public bool InRangeUnobstructed(MapCoordinates coords, MapCoordinates otherCoords, float range = InteractionRange, - int collisionMask = (int)CollisionGroup.Impassable, Func predicate = null, bool insideBlockerValid = false) + int collisionMask = (int)CollisionGroup.Impassable, Func predicate = null, bool ignoreInsideBlocker = false) { if (!coords.InRange(otherCoords, range)) return false; @@ -87,7 +90,7 @@ namespace Content.Shared.GameObjects.EntitySystems var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask); var rayResults = _physicsManager.IntersectRayWithPredicate(coords.MapId, ray, dir.Length, predicate, returnOnFirstHit: false).ToList(); - return rayResults.Count == 0 || (insideBlockerValid && rayResults.Count > 0 && (rayResults[0].HitPos - otherCoords.Position).Length < 1f); + return rayResults.Count == 0 || (ignoreInsideBlocker && rayResults.Count > 0 && (rayResults[0].HitPos - otherCoords.Position).Length < 1f); } /// @@ -101,11 +104,14 @@ namespace Content.Shared.GameObjects.EntitySystems /// maximum distance between the two sets of coordinates. /// the mask to check for collisions /// the entity to be ignored when checking for collisions. - /// if coordinates inside obstructions count as obstructed or not + /// if true and the coordinates are inside the obstruction, ignores the obstruction and + /// considers the interaction unobstructed. Therefore, setting this to true makes this check more permissive, such + /// as allowing an interaction to occur inside something impassable (like a wall). The default, false, + /// makes the check more restrictive. /// True if the two points are within a given range without being obstructed. public bool InRangeUnobstructed(MapCoordinates coords, MapCoordinates otherCoords, float range = InteractionRange, - int collisionMask = (int)CollisionGroup.Impassable, IEntity ignoredEnt = null, bool insideBlockerValid = false) => + int collisionMask = (int)CollisionGroup.Impassable, IEntity ignoredEnt = null, bool ignoreInsideBlocker = false) => InRangeUnobstructed(coords, otherCoords, range, collisionMask, - ignoredEnt == null ? null : (Func)(entity => ignoredEnt == entity), insideBlockerValid); + ignoredEnt == null ? null : (Func)(entity => ignoredEnt == entity), ignoreInsideBlocker); } } diff --git a/Resources/Prototypes/Entities/Markers/drag_shadow.yml b/Resources/Prototypes/Entities/Markers/drag_shadow.yml new file mode 100644 index 0000000000..29643c4204 --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/drag_shadow.yml @@ -0,0 +1,7 @@ +- type: entity + name: drag shadow + id: dragshadow + components: + - type: Sprite + layers: + - shader: unshaded diff --git a/RobustToolbox b/RobustToolbox index af4c920606..9e5374ac86 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit af4c920606932d0083ef794cdacd1cacb1e3a817 +Subproject commit 9e5374ac867e08a98046c2e71d772af6bedd7818 From 88f49961d8296056a403ae40e51cbf5b4fd2ad2f Mon Sep 17 00:00:00 2001 From: "R. Neuser" Date: Mon, 6 Jul 2020 16:37:39 -0500 Subject: [PATCH 15/18] OverlayManager refactor and Flash (#1218) * Flash component, overlay and shader Add BeginDraw method to Overlay.cs * Add flash icons, sounds * Progress * Multiple overlays without enums * This is probably the worst way to do this IDK * Remove nullable reference type * Add AttackEventArgs as parameter to OnHitEntities MeleeWeaponComponent.Attack now continues when OnHitEntities returns true (it hit something) Add OverlayType enum so client and server can agree on overlay ids Move IConfigurable to its own file Add AoE flash with shorter duration Flashing someone slows them down * Add arc to flash Set item size to something reasonable Remove chat log message when flash burns out * Remove unused interface --- .../Mobs/ClientOverlayEffectsComponent.cs | 139 +++++++------ .../Graphics/Overlays/CircleMaskOverlay.cs | 5 +- .../Graphics/Overlays/FlashOverlay.cs | 73 +++++++ .../Graphics/Overlays/GradientCircleMask.cs | 7 +- .../DamageThresholdTemplates/HumanTemplate.cs | 9 +- .../Mobs/ServerOverlayEffectsComponent.cs | 46 ++++- .../Components/Mobs/SpeciesComponent.cs | 2 +- .../Components/Weapon/Melee/FlashComponent.cs | 182 ++++++++++++++++++ .../Weapon/Melee/MeleeWeaponComponent.cs | 6 +- .../Weapon/Melee/StunbatonComponent.cs | 4 +- Content.Server/Mobs/Commands.cs | 49 +++++ .../Mobs/SharedOverlayEffectsComponent.cs | 73 ++++++- Content.Shared/Interfaces/IConfigurable.cs | 7 + Resources/Audio/weapons/flash.ogg | Bin 0 -> 9891 bytes Resources/Groups/groups.yml | 4 + .../Entities/Items/Weapons/security.yml | 27 +++ Resources/Prototypes/Shaders/shaders.yml | 5 + Resources/Shaders/flashed_effect.swsl | 18 ++ .../Objects/Melee/flash.rsi/burnt.png | Bin 0 -> 354 bytes .../Objects/Melee/flash.rsi/flash.png | Bin 0 -> 368 bytes .../Objects/Melee/flash.rsi/flashing.png | Bin 0 -> 385 bytes .../Objects/Melee/flash.rsi/inhand-left.png | Bin 0 -> 280 bytes .../Objects/Melee/flash.rsi/inhand-right.png | Bin 0 -> 296 bytes .../Objects/Melee/flash.rsi/meta.json | 76 ++++++++ 24 files changed, 647 insertions(+), 85 deletions(-) create mode 100644 Content.Client/Graphics/Overlays/FlashOverlay.cs create mode 100644 Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs create mode 100644 Content.Shared/Interfaces/IConfigurable.cs create mode 100644 Resources/Audio/weapons/flash.ogg create mode 100644 Resources/Shaders/flashed_effect.swsl create mode 100644 Resources/Textures/Objects/Melee/flash.rsi/burnt.png create mode 100644 Resources/Textures/Objects/Melee/flash.rsi/flash.png create mode 100644 Resources/Textures/Objects/Melee/flash.rsi/flashing.png create mode 100644 Resources/Textures/Objects/Melee/flash.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Melee/flash.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Melee/flash.rsi/meta.json diff --git a/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs b/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs index 5b5c24d579..e1a1cb8b38 100644 --- a/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs +++ b/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs @@ -1,18 +1,21 @@ -using System.Collections.Generic; -using Content.Client.Graphics.Overlays; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; using Content.Shared.GameObjects.Components.Mobs; +using Content.Shared.Interfaces; using Robust.Client.GameObjects; using Robust.Client.Graphics.Overlays; using Robust.Client.Interfaces.Graphics.Overlays; -using Robust.Client.Player; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Network; +using Robust.Shared.Interfaces.Reflection; using Robust.Shared.IoC; using Robust.Shared.Log; -using Robust.Shared.Players; +using Robust.Shared.Utility; +using Robust.Shared.ViewVariables; -namespace Content.Client.GameObjects +namespace Content.Client.GameObjects.Components.Mobs { /// /// A character UI component which shows the current damage state of the mob (living/dead) @@ -21,48 +24,33 @@ namespace Content.Client.GameObjects [ComponentReference(typeof(SharedOverlayEffectsComponent))] public sealed class ClientOverlayEffectsComponent : SharedOverlayEffectsComponent//, ICharacterUI { - /// /// An enum representing the current state being applied to the user /// - private ScreenEffects _currentEffect = ScreenEffects.None; + private readonly List _currentEffects = new List(); + + [ViewVariables(VVAccess.ReadOnly)] + public List ActiveOverlays + { + get => _currentEffects; + set => SetEffects(value); + } #pragma warning disable 649 // Required dependencies [Dependency] private readonly IOverlayManager _overlayManager; - [Dependency] private readonly IPlayerManager _playerManager; + [Dependency] private readonly IReflectionManager _reflectionManager; #pragma warning restore 649 - /// - /// Holds the screen effects that can be applied mapped ot their relevant overlay - /// - private Dictionary _effectsDictionary; - - /// - /// Allows calculating if we need to act due to this component being controlled by the current mob - /// - private bool CurrentlyControlled => _playerManager.LocalPlayer.ControlledEntity == Owner; - - public override void OnAdd() - { - base.OnAdd(); - - _effectsDictionary = new Dictionary() - { - { ScreenEffects.CircleMask, new CircleMaskOverlay() }, - { ScreenEffects.GradientCircleMask, new GradientCircleMask() } - }; - } - public override void HandleMessage(ComponentMessage message, IComponent component) { switch (message) { case PlayerAttachedMsg _: - SetOverlay(_currentEffect); + SetEffects(ActiveOverlays); break; case PlayerDetachedMsg _: - RemoveOverlay(); + ActiveOverlays = new List(); break; } } @@ -70,42 +58,77 @@ namespace Content.Client.GameObjects public override void HandleComponentState(ComponentState curState, ComponentState nextState) { base.HandleComponentState(curState, nextState); - if (!(curState is OverlayEffectComponentState state) || _currentEffect == state.ScreenEffect) return; - SetOverlay(state.ScreenEffect); - } - - private void SetOverlay(ScreenEffects effect) - { - RemoveOverlay(); - - _currentEffect = effect; - - ApplyOverlay(); - } - - private void RemoveOverlay() - { - if (CurrentlyControlled && _currentEffect != ScreenEffects.None) + if (!(curState is OverlayEffectComponentState state) || ActiveOverlays.Equals(state.Overlays)) { - var appliedEffect = _effectsDictionary[_currentEffect]; - _overlayManager.RemoveOverlay(appliedEffect.ID); + return; } - _currentEffect = ScreenEffects.None; + ActiveOverlays = state.Overlays; } - private void ApplyOverlay() + private void SetEffects(List newOverlays) { - if (CurrentlyControlled && _currentEffect != ScreenEffects.None) + foreach (var container in ActiveOverlays.ShallowClone()) { - var overlay = _effectsDictionary[_currentEffect]; - if (_overlayManager.HasOverlay(overlay.ID)) + if (!newOverlays.Contains(container)) { - return; + RemoveOverlay(container); } - _overlayManager.AddOverlay(overlay); - Logger.InfoS("overlay", $"Changed overlay to {overlay}"); } + + foreach (var container in newOverlays) + { + if (!ActiveOverlays.Contains(container)) + { + AddOverlay(container); + } + } + } + + private void RemoveOverlay(OverlayContainer container) + { + ActiveOverlays.Remove(container); + _overlayManager.RemoveOverlay(container.ID); + } + + private void AddOverlay(OverlayContainer container) + { + ActiveOverlays.Add(container); + if (TryCreateOverlay(container, out var overlay)) + { + _overlayManager.AddOverlay(overlay); + } + else + { + Logger.ErrorS("overlay", $"Could not add overlay {container.ID}"); + } + } + + private bool TryCreateOverlay(OverlayContainer container, out Overlay overlay) + { + var overlayTypes = _reflectionManager.GetAllChildren(); + var foundType = overlayTypes.FirstOrDefault(t => t.Name == container.ID); + + if (foundType != null) + { + overlay = Activator.CreateInstance(foundType) as Overlay; + var configurable = foundType + .GetInterfaces() + .FirstOrDefault(type => + type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IConfigurable<>) + && type.GenericTypeArguments.First() == container.GetType()); + + if (configurable != null) + { + var method = overlay?.GetType().GetMethod("Configure"); + method?.Invoke(overlay, new []{ container }); + } + + return true; + } + + overlay = default; + return false; } } } diff --git a/Content.Client/Graphics/Overlays/CircleMaskOverlay.cs b/Content.Client/Graphics/Overlays/CircleMaskOverlay.cs index 3b0a1358ce..ef6832480a 100644 --- a/Content.Client/Graphics/Overlays/CircleMaskOverlay.cs +++ b/Content.Client/Graphics/Overlays/CircleMaskOverlay.cs @@ -1,4 +1,5 @@ -using Robust.Client.Graphics.Drawing; +using Content.Shared.GameObjects.Components.Mobs; +using Robust.Client.Graphics.Drawing; using Robust.Client.Graphics.Overlays; using Robust.Client.Graphics.Shaders; using Robust.Client.Interfaces.Graphics.ClientEye; @@ -17,7 +18,7 @@ namespace Content.Client.Graphics.Overlays public override OverlaySpace Space => OverlaySpace.WorldSpace; - public CircleMaskOverlay() : base(nameof(CircleMaskOverlay)) + public CircleMaskOverlay() : base(nameof(OverlayType.CircleMaskOverlay)) { IoCManager.InjectDependencies(this); Shader = _prototypeManager.Index("CircleMask").Instance(); diff --git a/Content.Client/Graphics/Overlays/FlashOverlay.cs b/Content.Client/Graphics/Overlays/FlashOverlay.cs new file mode 100644 index 0000000000..f156225434 --- /dev/null +++ b/Content.Client/Graphics/Overlays/FlashOverlay.cs @@ -0,0 +1,73 @@ +using System.Net.Mime; +using Content.Shared.GameObjects.Components.Mobs; +using Content.Shared.Interfaces; +using Robust.Client.Graphics; +using Robust.Client.Graphics.Drawing; +using Robust.Client.Graphics.Overlays; +using Robust.Client.Graphics.Shaders; +using Robust.Client.Interfaces.Graphics; +using Robust.Client.Interfaces.Graphics.ClientEye; +using Robust.Shared.Interfaces.Timing; +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using Color = Robust.Shared.Maths.Color; + +namespace Content.Client.Graphics.Overlays +{ + public class FlashOverlay : Overlay, IConfigurable + { +#pragma warning disable 649 + [Dependency] private readonly IPrototypeManager _prototypeManager; + [Dependency] private readonly IClyde _displayManager; + [Dependency] private readonly IGameTiming _gameTiming; +#pragma warning restore 649 + + public override OverlaySpace Space => OverlaySpace.ScreenSpace; + private double _startTime; + private int lastsFor = 5000; + private Texture _screenshotTexture; + + public FlashOverlay() : base(nameof(OverlayType.FlashOverlay)) + { + IoCManager.InjectDependencies(this); + Shader = _prototypeManager.Index("FlashedEffect").Instance().Duplicate(); + + _startTime = _gameTiming.CurTime.TotalMilliseconds; + _displayManager.Screenshot(ScreenshotType.BeforeUI, image => + { + var rgba32Image = image.CloneAs(Configuration.Default); + _screenshotTexture = _displayManager.LoadTextureFromImage(rgba32Image); + }); + } + + protected override void Draw(DrawingHandleBase handle) + { + var percentComplete = (float) ((_gameTiming.CurTime.TotalMilliseconds - _startTime) / lastsFor); + Shader?.SetParameter("percentComplete", percentComplete); + + var screenSpaceHandle = handle as DrawingHandleScreen; + var screenSize = UIBox2.FromDimensions((0, 0), _displayManager.ScreenSize); + + if (_screenshotTexture != null) + { + screenSpaceHandle?.DrawTextureRect(_screenshotTexture, screenSize); + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _screenshotTexture = null; + } + + public void Configure(TimedOverlayContainer parameters) + { + lastsFor = parameters.Length; + } + } +} diff --git a/Content.Client/Graphics/Overlays/GradientCircleMask.cs b/Content.Client/Graphics/Overlays/GradientCircleMask.cs index 72b1a7e3c3..e95fe30d83 100644 --- a/Content.Client/Graphics/Overlays/GradientCircleMask.cs +++ b/Content.Client/Graphics/Overlays/GradientCircleMask.cs @@ -1,4 +1,5 @@ -using Robust.Client.Graphics.Drawing; +using Content.Shared.GameObjects.Components.Mobs; +using Robust.Client.Graphics.Drawing; using Robust.Client.Graphics.Overlays; using Robust.Client.Graphics.Shaders; using Robust.Client.Interfaces.Graphics.ClientEye; @@ -8,7 +9,7 @@ using Robust.Shared.Prototypes; namespace Content.Client.Graphics.Overlays { - public class GradientCircleMask : Overlay + public class GradientCircleMaskOverlay : Overlay { #pragma warning disable 649 [Dependency] private readonly IPrototypeManager _prototypeManager; @@ -16,7 +17,7 @@ namespace Content.Client.Graphics.Overlays #pragma warning restore 649 public override OverlaySpace Space => OverlaySpace.WorldSpace; - public GradientCircleMask() : base(nameof(GradientCircleMask)) + public GradientCircleMaskOverlay() : base(nameof(OverlayType.GradientCircleMaskOverlay)) { IoCManager.InjectDependencies(this); Shader = _prototypeManager.Index("GradientCircleMask").Instance(); diff --git a/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs b/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs index 18a93231da..d800514df1 100644 --- a/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs +++ b/Content.Server/GameObjects/Components/Mobs/DamageThresholdTemplates/HumanTemplate.cs @@ -69,21 +69,24 @@ namespace Content.Server.GameObjects statusEffectsComponent?.ChangeStatusEffectIcon(StatusEffect.Health, "/Textures/Mob/UI/Human/human" + modifier + ".png"); - overlayComponent?.ChangeOverlay(ScreenEffects.None); + overlayComponent?.RemoveOverlay(OverlayType.GradientCircleMaskOverlay); + overlayComponent?.RemoveOverlay(OverlayType.CircleMaskOverlay); return; case ThresholdType.Critical: statusEffectsComponent?.ChangeStatusEffectIcon( StatusEffect.Health, "/Textures/Mob/UI/Human/humancrit-0.png"); - overlayComponent?.ChangeOverlay(ScreenEffects.GradientCircleMask); + overlayComponent?.ClearOverlays(); + overlayComponent?.AddOverlay(OverlayType.GradientCircleMaskOverlay); return; case ThresholdType.Death: statusEffectsComponent?.ChangeStatusEffectIcon( StatusEffect.Health, "/Textures/Mob/UI/Human/humandead.png"); - overlayComponent?.ChangeOverlay(ScreenEffects.CircleMask); + overlayComponent?.ClearOverlays(); + overlayComponent?.AddOverlay(OverlayType.CircleMaskOverlay); return; default: diff --git a/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs b/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs index 8cfcb33cb8..92c0b2d5d5 100644 --- a/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/ServerOverlayEffectsComponent.cs @@ -1,5 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; using Content.Shared.GameObjects.Components.Mobs; using Robust.Shared.GameObjects; +using Robust.Shared.Timers; +using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Mobs { @@ -7,20 +12,49 @@ namespace Content.Server.GameObjects.Components.Mobs [ComponentReference(typeof(SharedOverlayEffectsComponent))] public sealed class ServerOverlayEffectsComponent : SharedOverlayEffectsComponent { - private ScreenEffects _currentOverlay = ScreenEffects.None; + private readonly List _currentOverlays = new List(); + + [ViewVariables(VVAccess.ReadWrite)] + private List ActiveOverlays => _currentOverlays; public override ComponentState GetComponentState() { - return new OverlayEffectComponentState(_currentOverlay); + return new OverlayEffectComponentState(_currentOverlays); } - public void ChangeOverlay(ScreenEffects effect) + public void AddOverlay(OverlayContainer container) { - if (effect == _currentOverlay) + if (!ActiveOverlays.Contains(container)) { - return; + ActiveOverlays.Add(container); + Dirty(); } - _currentOverlay = effect; + } + + public void AddOverlay(string id) => AddOverlay(new OverlayContainer(id)); + public void AddOverlay(OverlayType type) => AddOverlay(new OverlayContainer(type)); + + public void RemoveOverlay(OverlayContainer container) + { + if (ActiveOverlays.RemoveAll(c => c.Equals(container)) > 0) + { + Dirty(); + } + } + + public void RemoveOverlay(string id) + { + if (ActiveOverlays.RemoveAll(container => container.ID == id) > 0) + { + Dirty(); + } + } + + public void RemoveOverlay(OverlayType type) => RemoveOverlay(type.ToString()); + + public void ClearOverlays() + { + ActiveOverlays.Clear(); Dirty(); } } diff --git a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs index 23342f3a15..ed64d334b6 100644 --- a/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/SpeciesComponent.cs @@ -79,7 +79,7 @@ namespace Content.Server.GameObjects statusEffectsComponent?.RemoveStatusEffect(StatusEffect.Health); Owner.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent); - overlayEffectsComponent?.ChangeOverlay(ScreenEffects.None); + overlayEffectsComponent?.ClearOverlays(); } bool IActionBlocker.CanMove() diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs new file mode 100644 index 0000000000..354974a685 --- /dev/null +++ b/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; +using Content.Shared.Chat; +using Content.Shared.GameObjects.Components.Mobs; +using Content.Shared.Interfaces; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.EntitySystems; +using Robust.Server.Interfaces.GameObjects; +using Robust.Server.Interfaces.Player; +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Network; +using Robust.Shared.Interfaces.Random; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Serialization; +using Robust.Shared.Utility; +using Robust.Shared.ViewVariables; +using Timer = Robust.Shared.Timers.Timer; + +namespace Content.Server.GameObjects.Components.Weapon.Melee +{ + [RegisterComponent] + public class FlashComponent : MeleeWeaponComponent, IUse, IExamine + { +#pragma warning disable 649 + [Dependency] private readonly ILocalizationManager _localizationManager; + [Dependency] private readonly IEntityManager _entityManager; + [Dependency] private readonly ISharedNotifyManager _notifyManager; +#pragma warning restore 649 + + public override string Name => "Flash"; + + [ViewVariables(VVAccess.ReadWrite)] private int _flashDuration = 5000; + [ViewVariables(VVAccess.ReadWrite)] private float _flashFalloffExp = 8f; + [ViewVariables(VVAccess.ReadWrite)] private int _uses = 5; + [ViewVariables(VVAccess.ReadWrite)] private float _range = 3f; + [ViewVariables(VVAccess.ReadWrite)] private int _aoeFlashDuration = 5000 / 3; + [ViewVariables(VVAccess.ReadWrite)] private float _slowTo = 0.75f; + private bool _flashing; + + private int Uses + { + get => _uses; + set + { + _uses = value; + Dirty(); + } + } + + private bool HasUses => _uses > 0; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _flashDuration, "duration", 5000); + serializer.DataField(ref _flashFalloffExp, "flashFalloffExp", 8f); + serializer.DataField(ref _uses, "uses", 5); + serializer.DataField(ref _range, "range", 3f); + serializer.DataField(ref _aoeFlashDuration, "aoeFlashDuration", _flashDuration / 3); + serializer.DataField(ref _slowTo, "slowTo", 0.75f); + } + + protected override bool OnHitEntities(IReadOnlyList entities, AttackEventArgs eventArgs) + { + if (entities.Count == 0) + { + return false; + } + + if (!Use(eventArgs.User)) + { + return false; + } + + foreach (var entity in entities) + { + Flash(entity, eventArgs.User); + } + + return true; + } + + public bool UseEntity(UseEntityEventArgs eventArgs) + { + if (!Use(eventArgs.User)) + { + return false; + } + + foreach (var entity in _entityManager.GetEntitiesInRange(Owner.Transform.GridPosition, _range)) + { + Flash(entity, eventArgs.User, _aoeFlashDuration); + } + + return true; + } + + private bool Use(IEntity user) + { + if (HasUses) + { + var sprite = Owner.GetComponent(); + if (--Uses == 0) + { + sprite.LayerSetState(0, "burnt"); + + _notifyManager.PopupMessage(Owner, user, "The flash burns out!"); + } + else if (!_flashing) + { + int animLayer = sprite.AddLayerWithState("flashing"); + _flashing = true; + + Timer.Spawn(400, () => + { + sprite.RemoveLayer(animLayer); + _flashing = false; + }); + } + + EntitySystem.Get().PlayAtCoords("/Audio/weapons/flash.ogg", Owner.Transform.GridPosition, + AudioParams.Default); + + return true; + } + + return false; + } + + private void Flash(IEntity entity, IEntity user) + { + Flash(entity, user, _flashDuration); + } + + // TODO: Check if target can be flashed (e.g. things like sunglasses would block a flash) + private void Flash(IEntity entity, IEntity user, int flashDuration) + { + if (entity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent)) + { + var container = new TimedOverlayContainer(nameof(OverlayType.FlashOverlay), flashDuration); + overlayEffectsComponent.AddOverlay(container); + container.StartTimer(() => overlayEffectsComponent.RemoveOverlay(container)); + } + + if (entity.TryGetComponent(out StunnableComponent stunnableComponent)) + { + stunnableComponent.Slowdown(flashDuration / 1000f, _slowTo, _slowTo); + } + + if (entity != user) + { + _notifyManager.PopupMessage(user, entity, $"{user.Name} blinds you with the {Owner.Name}"); + } + } + + public void Examine(FormattedMessage message, bool inDetailsRange) + { + if (!HasUses) + { + message.AddText("It's burnt out."); + return; + } + + if (inDetailsRange) + { + message.AddMarkup(_localizationManager.GetString( + $"The flash has [color=green]{Uses}[/color] uses remaining.")); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index 29dbe2f98c..121d755527 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -81,9 +81,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee serializer.DataField(ref _cooldownTime, "cooldownTime", 1f); } - public virtual bool OnHitEntities(IReadOnlyList entities) + protected virtual bool OnHitEntities(IReadOnlyList entities, AttackEventArgs eventArgs) { - return false; + return true; } void IAttack.Attack(AttackEventArgs eventArgs) @@ -112,7 +112,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee } } - if(OnHitEntities(hitEntities)) return; + if(!OnHitEntities(hitEntities, eventArgs)) return; var audioSystem = EntitySystem.Get(); var emitter = hitEntities.Count == 0 ? eventArgs.User : hitEntities[0]; diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs index 029610ba15..367c67fdac 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/StunbatonComponent.cs @@ -86,7 +86,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee serializer.DataField(ref _slowdownTime, "slowdownTime", 5f); } - public override bool OnHitEntities(IReadOnlyList entities) + protected override bool OnHitEntities(IReadOnlyList entities, AttackEventArgs eventArgs) { var cell = Cell; if (!Activated || entities.Count == 0 || cell == null) @@ -118,7 +118,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee TurnOff(); } - return false; + return true; } private bool ToggleStatus(IEntity user) diff --git a/Content.Server/Mobs/Commands.cs b/Content.Server/Mobs/Commands.cs index 2b04692431..a31eac223c 100644 --- a/Content.Server/Mobs/Commands.cs +++ b/Content.Server/Mobs/Commands.cs @@ -1,4 +1,5 @@ using System.Text; +using Content.Server.GameObjects.Components.Mobs; using Content.Server.Mobs.Roles; using Content.Server.Players; using Content.Shared.Jobs; @@ -117,4 +118,52 @@ namespace Content.Server.Mobs } } } + + public class AddOverlayCommand : IClientCommand + { + public string Command => "addoverlay"; + public string Description => "Adds an overlay by its ID"; + public string Help => "addoverlay "; + + public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) + { + if (args.Length != 1) + { + shell.SendText(player, "Expected 1 argument."); + return; + } + + if (player?.AttachedEntity != null) + { + if (player.AttachedEntity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent)) + { + overlayEffectsComponent.AddOverlay(args[0]); + } + } + } + } + + public class RemoveOverlayCommand : IClientCommand + { + public string Command => "rmoverlay"; + public string Description => "Removes an overlay by its ID"; + public string Help => "rmoverlay "; + + public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) + { + if (args.Length != 1) + { + shell.SendText(player, "Expected 1 argument."); + return; + } + + if (player?.AttachedEntity != null) + { + if (player.AttachedEntity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent)) + { + overlayEffectsComponent.RemoveOverlay(args[0]); + } + } + } + } } diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs index 07b2b839c2..fd68608336 100644 --- a/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs +++ b/Content.Shared/GameObjects/Components/Mobs/SharedOverlayEffectsComponent.cs @@ -1,6 +1,14 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; +using JetBrains.Annotations; using Robust.Shared.GameObjects; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; +using Robust.Shared.Timers; +using Robust.Shared.ViewVariables; +using YamlDotNet.RepresentationModel; +using Component = Robust.Shared.GameObjects.Component; namespace Content.Shared.GameObjects.Components.Mobs { @@ -13,21 +21,72 @@ namespace Content.Shared.GameObjects.Components.Mobs public sealed override uint? NetID => ContentNetIDs.OVERLAYEFFECTS; } - public enum ScreenEffects + [Serializable, NetSerializable] + public class OverlayContainer { - None, - CircleMask, - GradientCircleMask, + [ViewVariables(VVAccess.ReadOnly)] + public string ID { get; } + + public OverlayContainer([NotNull] string id) + { + ID = id; + } + + public OverlayContainer(OverlayType type) : this(type.ToString()) + { + + } + + public override bool Equals(object obj) + { + if (obj is OverlayContainer container) + { + return container.ID == ID; + } + + if (obj is string idString) + { + return idString == ID; + } + + return base.Equals(obj); + } + + public override int GetHashCode() + { + return (ID != null ? ID.GetHashCode() : 0); + } } [Serializable, NetSerializable] public class OverlayEffectComponentState : ComponentState { - public ScreenEffects ScreenEffect; + public List Overlays; - public OverlayEffectComponentState(ScreenEffects screenEffect) : base(ContentNetIDs.OVERLAYEFFECTS) + public OverlayEffectComponentState(List overlays) : base(ContentNetIDs.OVERLAYEFFECTS) { - ScreenEffect = screenEffect; + Overlays = overlays; } } + + [Serializable, NetSerializable] + public class TimedOverlayContainer : OverlayContainer + { + [ViewVariables(VVAccess.ReadOnly)] + public int Length { get; } + + public TimedOverlayContainer(string id, int length) : base(id) + { + Length = length; + } + + public void StartTimer(Action finished) => Timer.Spawn(Length, finished); + } + + public enum OverlayType + { + GradientCircleMaskOverlay, + CircleMaskOverlay, + FlashOverlay + } } diff --git a/Content.Shared/Interfaces/IConfigurable.cs b/Content.Shared/Interfaces/IConfigurable.cs new file mode 100644 index 0000000000..17fbe07880 --- /dev/null +++ b/Content.Shared/Interfaces/IConfigurable.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Interfaces +{ + public interface IConfigurable + { + public void Configure(T parameters); + } +} diff --git a/Resources/Audio/weapons/flash.ogg b/Resources/Audio/weapons/flash.ogg new file mode 100644 index 0000000000000000000000000000000000000000..eed2ed0d52410cb4047db0a99f9d2e08a664d32f GIT binary patch literal 9891 zcmeHtdpK0xzxbLl7?<2a5*ibkk=%KI?PaYtJ4}Piue% zzuP9wJ={A#$Aw{(0_vz=fU9>PGJ>XDUIuw|_4gIE2f_STLoiXW7dvrSRea;pKbtYn zG9`HkVC(JgrM@S?6L-kl)rLzSN5yGtYHDlhY3U*4P`t~)cq3yQND&2u>5_`d=Zt7> z#0)x}sJz-ujOJAk*h5mujp;FrZ;=^|(Ngbq_3;*`+bAlpwib5q%AhldysO>l2wX48 zG&fMvNTmhqmZaWT% z@D2%ATJmTUSK^W!Xg7Ob(^YFS814xzGK%3MrgI|>G%j2#*3JEK^wSh3A}1hYP+XY> z0l23rX=24f9+3F}3rLzAk!(AnWR|AZhUS8hp-KUeNgg32uOp?oQ?tjs3sn+IDkkeH zC+iNssquYNvm*B7Wi-G6fPJrfpTR@PO6@=wC{_S~0f2>d&vGSuJyZn<069TPh04xh z)7xEA)Yemrk-Ljo2IbV&d^Vj%EdJ{RpPF%>(p=eUrqqmV1TM#*jM|#_7YG8}eu8b_ zP3=Q)1K7G=k4liI>_W<;N8gJ60mok)F2*I_{vywDlFG%EDURLqHSE3zf+y{@#{x+PutHePgvM4MO^ zI;fMx!Ep5_24zu<5!QZ4xR_!jtTo2A-fgIy!B|$O7=TLyScG%Q6Y4&&viL)#ED z!YVFLMAABm#4jH!MicmJns7k@A>pEa@;mc1CA%~a@5~bK?2==JD#uGM9j_!L)_8?g zdM4Izj+b9LUS67AK9ODd0oqAAFi!Hb6Gw%@^Ggp0D%0XR7q;8bMnNUc`E;(5K z_XU6wBox{vkC~^9ho-%cM^sNZon3mmkN|=IUk4T{76TqarSeza%#JzBGNTz*T$>vR zn{JqU8p?aF$A0U(Tvv%e(G1Td>f@V13PyyDeObravTn!*j;%HlcD;Hoghn#o1Q*W; zV4na@a|xWcEIbg!z-FGu=T(UH%EK;qLE1Pf`#ma~04@B#-EhZbhfd?+@tYE46kjM9 zUk+E4+aQ-bBD%2be}tE}Z2rIJRW1-(2%YsWUWMN1!h`=4ynd7X-^>4M;6Ks;bSJDo z{8fnwuCNma4+LN|`k!n#0Gyj)QfZFWw)A?K0C2lO^N@ZfFN{b^h;Qqs6?sDtZ^V&V zCEkVqZSMbMNCP-Q(3~%m$5*As@<8dX$oB?aJfR9?NfZla95g?y6V~V|OY;+S-IakD zFL1V$e0*K4E2bDqWYn!|Az9#^r;_kgw@b$)G>>y`J&d-yR+bPF$^|J_OgIZkeOMd3 z%qL#cCl@GgK(SH)h#9fX9EU;nbfI^-s_v6n7|kuZb(vDxF^Lh4$;!56{9T*$KW@(*=lCd-3;!5%n>oDGL6g%Ch%rqkZc=-;^Q z+L{Qt7r`EOd|4&sFj2K@lbPIpCaS!=ymCYRbzw_pU$B#1rZ0fy&ULjnFv5t)!L*!| zpPr1# zL86Bk4NJ@rHX;^hFaUTN%>#dNaGjyrMF9&(A-2l6?J_Erbn7JXD>4$aI63K-+T%Ha zomAp#w+<4gh@C{@eKx zuLCfH;RpHXH8y7YL|Gv<#AZ@ZfGp;gL>E*nmNcRfW7%{pOdB$YPiYniOUhoygLo*t z%tZ#Q3ja~c{kw|oztHWm`Y!$Ww8$FY>u*4U(Zk<_yA~b4Qu_KLBbVD-m z3Mr!#s=rk_uoIf5YtrrUoSj5sudUA$Xr}fFH=%V`l8Rp*gw~xCc<9;~V%QvMhsT>Z zXrQ@94&WpX*~$+Wd8t)BP00Xca{yeD=tc%r;4$bv$25ZY|}E z0&4*f;1v@Wf8rR|!fSf6mCx){8^3uxAIG!()z0#X5mag3% zn?HY{$vQ-@d_!rp)0suHQo!*1RfYU&3rkCOf#(Hyyd*mI^s}cVH=UJAO5~*3K{LXd zyV>XKd=4Jid@ZQ{5&;B<+ly z`NCbVu#buBvNyCpBON)(&Z(8PGtd(8phGfp9~tuWO~>2w3is) zNk;dJH+^sV`ZxP_m%Nx5yc*@Vr+ae-&HAZJp7f<-^ZF-0=Z#PO*!|_p!ZurxwzgK8 z>9cFkF8uiUT?ah%K9VgmWWKFw*Y^+pclS0g%yPQ)G;1&Hh+3R!zv8nw4cBurSrm4+ zZ{4EMXKp9Z`tu`5Jn{bcv0FQ4&}yl391-C;h;t!2A%=ciia&huC#mi8s9mj~WR{d< z*8NW@EJMskHBl73xWBY4Hzij`Jn*M!q>-r^eJ)gHf56d>Yb-$E3HW1cP z(hxRvn=?+lbac0@MSt*4-~6gOm)lA{mYn@%VPRue!P1@V($+v@GVxV}q*ogQUEb~W z*=Nyho^{5)Xs2@Y&7z$&y6@T_)0=A5#Y$yVEmwnqy2iDm^_}Q&2|a&3yIh|ulM7mn zlWNT>M|eWgU);7aA?4GV6lS3+UR)Uu-@=ZxNpMON+FNt?PTA@)M4nkKd@0Lx*88Y( z2di*4wt z?^BB1atDHr@4wVNc(lIlXw#06-P+$f+|NsnOT>$by|gt-c&Br;zs#qyz{RXps?<4F z%koH~!gHsPe&gFRf@oEqfe-uC|LEH8a;GsQpd)+5Ui<#XV}HI)j z$(<$$4wD zcq<}eex_jRiK+kI={y*;oA#&-tew6zAL{AmV;aaApT1I7AGu_@e#rkPMEg7&L?L`S zKzaLVZkmyXP5Xnja7;dGWo3J4Z@|H$owue;1Y!rSUOXDr-PYqI$@XY2#DR5C^8;ON zp3eGr!sqQfV-6G^beiUj>S)UC+aA7=W2gfw%IjzlkcNHWD?yRMS)t=8g^Bu{R$Dd0 z@{5AO%I&Ds<_}LMUM_LI$DNp+u)ee7==N_fr_U^&5fDOq**5HN;M_K`W4HXg=@wAk znmbr|bMp_249%+JgSR8MZtXvu7akDEdDk=E(e$Q&bv=)m)%h+?_2$QOz3zQWKd1V| zB=J=g(D9L_rw64@ia+WO(G}O=-D{$c5gYo5F@Glk$}yH~ zjC1j#JbpzSd+z}5TgxU(rwRdHvaJ00U48c{-JqPdksaz!Z#V6^u!Hk5J2gE@=YjrN zH>$)jH08(s3p*~nBDKDB+mW{zR(|t)SS&gqd2Lr@@Rz|4)obdUHeblDs}MgLJ%2O^ zYFusCs$NsQC!G|O!sH^U-A_g_gJ0LaL#m}ND*4YfrsiX)Gtz-3OkPudu~fnaa|#2^ zQU&>xw5ekqEx~=w!ESaR9$wBmOz@SKCR0j-+Dz5TU>6zAbtj@+6xDvkX= zf6NRUpE-|Fm5gVO_#f|XYZB02g09-LaYn?f?JN{-`w#uiLw(u0Km6vV`UPzztpp3% z&Zxx?iw!MTJ&hjr4<6caD|G$Wrn)G<&y(lG0_ODIbZyL|{$fhik}2p{a6=d80DvV5 z#Or_kW$7Gjb?5SdkE<2XFI=5%%f_d2bK)%xZ#KPJ&|AMWi<1ym8rtB$U25(0$5B7~ zaD}xW1}co7$eZSc4rb*Y2?#Lz)f6~4WxDD{cjK8eXC9U14$jtx=%Mj@8tWDtdj9C* zJ!d>4XWtvQYj4Hm;LeEejwvKeSAmDq!yqOzTFx9FeaHsNqXPG*P@pHIy)s3G7!z=@ z9ur(xGI9RM?aAaezlH~$Z?Yo0I!Yw2wT4FBF|ljn*p-sw#sz`PI&iPdVU$}gl+&M``DU6YJPl#5gr z1X^ng1U-}2PT$bsaa0m-l_KV=Hp|N`wN6|rtJk(JdpoqDufD7y(5+{|FE93@*_77i z&9qyaUS$-Z2cQ70qB{H&7N#2`rl)r?u1pU4{L~Cg8F24;KDXFOVG{ST$Qi(Y1M+4F z6(f)(F1-1{f)}0X4VY--Cy_~uHDpJorvFbjF&2)Xgp#f`pW;N2&UcPq9a%aSso^ZY z^kI7Ix3I~Hy9e1oMKtp3~Xw%>byV7XFd7I-IM0% zvCt1^p#tQkCyKd@q0LdthsUw(OPz?fQRQ6-}>uWI~pCCf{~+&z9i1 zDa(8SeWKbh0+lwiO?I`u)zph$o-serO2c8g+Wv)(M_M)v0bCj;1@5W?WjOE1?}S3- z0~$ph#2)mm*2ljll9S)w>mLxernYM{nXe>=N$G-MsZu|XgLB|dXO+}mEIJuG->AhwZ(o$rd*y|QwQ*}??XQe+Aq2!K?8 zgAK(xw0H1~d zo5>UmU_+-j*?E8XXnPWVYYkr<#Ve<$K%=(EtY$~x zDVO-otjD~!P6$qKJ->T#_D23a{57QDxp;ImcS#uxK-MM^AY^{)dg_j%7r(+1e}Ji( zkX>n!=5a6M`Q?DQ1kkjHb3_;$Zyc9=_gsEk4>{LSY+g5Cb;41J>>9l_U@|0L`SiiH zPjyFi9o~-^B>SQ$Sbw{m!Ao{~x&p^vNpHC`7yNp5sj~kJmmw_zxKOP z*0o`_tW?9KD51f55Dhm)0C~-Z`M4={9X^J4K2G4Bt?{>$i-y-Ill!p8Bb)Z$nD8~A zg*;xN)r@!Qcbb^;+1hWBCM+z*lu`BXBu#JqepYntK?+V-|vzD>!As{C|V>?`@DANMWts3 zn&FEEzdqldU1}0X%xY4UBlj_&8$F5`)z?#jB1dm~M}KCDYbdaU02u%|r1B@DS$RP* zU%b?d9q5z{^^+sY`v^xv>-I`iyq_v3qDe5*@N zt8g`O)N!>0UM?cMX7LQKLj7XHc?}g*jgio{Ohu`G^q6G{fhbYP4QOg0XEORNGtP*( zVkeKDQM{n(@RO9*Lw!39J%}loof*n9hNhRF6xv9!7_WElZ~F3;K?LOPAel>~`-j@~ z&-%W}?CMt8F*kEw5C+HU7CmcL(Nm+rY~q#RU!IA6C4gEG*SN{ro@p>*fYt%#c)&uw zCIU;=$@}yxq?T`Nhs=ru3SY?Amok4GbQ@DW?s+2Bmaj(n+@Z|W9hXjzT)*F5CnfY= zbC3Kf#po8av_Q_D3;O~~Ixo7&q=B}x7Y6$Jd6BUEU2i>E>run0K(de1(!kF(EAzA7 z4csT?6KPBn=Y1fa4BwsA5zas$A>lmUR3N5Q8&hUz{n1u*Z(WHQi?s6W!ky{cA3UCS zv7Z<2yaC9kj(yNyfdW!O7)gCj`0*{WC5lwET-V{(^V_AMdLtfatRpAHJ-E87&$X}V z?7RoY{94L<#)Q4q1L>=n4OBd2wFcpbQ^Y(=?4He_NNp%BO!IgkD zW`}PZosD$V(Rc7ePaLg3Sg>Pv7cWXZK~QR2>-2pN=e`na?#l#cydMQQRu^lmW969t zY-daVy<;Qg_F#jHlz1xS1@jI}0G4v98?NJw#tT{IwH0q7uQqlN+1G7UgQKW%l2#w^ zBdxXvzg70EQU}?cPgbK<)r6(uYl-f19VZo~OSdm=%MgWC=3>K`-u>w9Df12@UNFl! zMC!=B=Q-Up#xgBd-6vj)Bf|{0{B4$BSv2U%F{LMzCEGmX3yH7323HodJ%XCjqE_@&8TG+hEgLua+(HIs7mpYhB`T38Y zqf&XOvL=rN+z?~&Ad@4zS~yhGHBTu~(uP#|bN3t3LKU0e+x5OazVk#HL55CnAWVki z3(4Ky3h6ANKL{u4%ha|H3N^x1(yJF^7`aR0dmdx1e4)#JP?+z#7WG{iy`MSMvH?HN z8y}B_F2VhZ;%teT{8Q(Vv+WcsfzY&CLBwsu75(9D%|g`nE_*jWjF$6*1gFd`i!F8F zsf(lSN8J?y04M9OELp`dm=$$GVqJBO=+W7H6&77pQz0`|E4k ztJ`-UmyCy9+#h^o_)7PPtswcXZ>!6$agpv6rR6XC7~C+IDt9vh(U{gPBVL@-emkZ$ z-PCBC1!eQD&AOX3H8s?UM1qQv(mE88G@hL zEVxY#+ad0mvPvyju`X7qC`{;&3T67WG}$>qpwB*EsgMW53TZDCYEzELwt2hAqTkPb z>0U6t0$&Ff8=&sVKS<_E4UAxzYOeV4MSlrQF+W~*P+VMUkGMYyx+j3S6=8s@vy88G zjeC41c%#hWpx~8-^J3W>-cA)Co0^Xap>m-xvj4>ccGWbuZl7JQBPIU z{lc7^zS$@v{Cv;?Ur=C7VKYpc1zpxOD`v-_-!8cn?zjRAc-%S<=Lvh1)Zvc{7Z*rqo=$v=L;Nz<{}gMwD@5Rm?D( z|5&&{)!#cTz%Ix9CaQ)IrP#_?3d>+(;(bZ{R36@#dQ-yazG$IRMt9%DC*8XTw{+as z>~wSBmc`?%c!rhE7&u>r>+z2D~+eH%n8cq`^)Q>bp;`7OK?;hRrMcx zDC$fn^eoa^TF}7Iv$^FO1hUZS81<3hsJhx8h?9%xfGO~QA} z_PoAs3BMSm#ba#|^xyj1d7@OX$Y_Y4PwKf#CI-N2!t>8#d0aWhR~h@K8lPVk0PW_9 z#>pZ4sm&TnfW^Y3{kF1BgHx##P~7)%FMt4{WBWuQZ$rzynxIAPv4u0pRPHrxu;Ks4q};sndsR zg<~2!Ay$Qbf77j>9s&?c3JangGcX4b@Z~gvi%zsQwK82L>$k6^tn{XT)N?*BLE5z& z2MFgAQTf)OiqpLTz-qpFY%L-|g=>FQ%}+N(0w_0`ti)QL1^0rpRA$$ccVkRR&qhb* z(1_e)qQ+H059e;yEgkxPUrbH@&j^HZJVsLpxh_XdRYz%%Z;c-67)bvYCy4U^!D&Nq zwn0d=Ir`!9hib0EFw$z4{#kp$sUzd7xJVogW6f>v7NB_Fpn^(Hg~J_J03?3LO76uu z+AC@k=vqQALcutC#+syeA^Q;c1K9Paeu^x^b3KUrryFn*W3IwG^VL@YnLaeg=BV@G zyDu+vL3>0k`Tj{l5CEt`%m{u*M7+ASO~9#_D^4E-AEY*}gqXi?xmgJOwmrZ_+N69Z z1ld!7AUm4_jUefLO=_qvn6r=uzvCbcq3hg%pOOCyaFb&1FVCy{Gg&^%oWXC0fJq3P zx(%zcWkBO*?Pb7|ERWxSGRyvlgT`yEr1@KI8=Fts&Ry6R<&D}53BdMyMG+A-x7#># i1>|UKY>xg7##Iyq;{tO}djBHzAHxLvCt%b?koIpqOV8;5 literal 0 HcmV?d00001 diff --git a/Resources/Groups/groups.yml b/Resources/Groups/groups.yml index d1b4d32d96..dc76b17683 100644 --- a/Resources/Groups/groups.yml +++ b/Resources/Groups/groups.yml @@ -74,6 +74,8 @@ - mindinfo - addrole - rmrole + - addoverlay + - rmoverlay - showtime - group - addai @@ -121,6 +123,8 @@ - mindinfo - addrole - rmrole + - addoverlay + - rmoverlay - srvpopupmsg - group - showtime diff --git a/Resources/Prototypes/Entities/Items/Weapons/security.yml b/Resources/Prototypes/Entities/Items/Weapons/security.yml index 43e28a9ef7..957bab088b 100644 --- a/Resources/Prototypes/Entities/Items/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Items/Weapons/security.yml @@ -23,3 +23,30 @@ HeldPrefix: off - type: ItemCooldown + +- type: entity + name: flash + parent: BaseItem + id: Flash + components: + - type: Sprite + sprite: Objects/Melee/flash.rsi + state: flash + + - type: Icon + sprite: Objects/Melee/flash.rsi + state: flash + + - type: Flash + damage: 0 + cooldownTime: 1 + arc: smash + hitSound: /Audio/weapons/flash.ogg + slowTo: 0.7 + + - type: Item + Size: 2 + sprite: Objects/Melee/flash.rsi + + - type: ItemCooldown + diff --git a/Resources/Prototypes/Shaders/shaders.yml b/Resources/Prototypes/Shaders/shaders.yml index e278d35c9a..b206811bc0 100644 --- a/Resources/Prototypes/Shaders/shaders.yml +++ b/Resources/Prototypes/Shaders/shaders.yml @@ -7,3 +7,8 @@ id: GradientCircleMask kind: source path: "/Shaders/gradient_circle_mask.swsl" + +- type: shader + id: FlashedEffect + kind: source + path: "/Shaders/flashed_effect.swsl" diff --git a/Resources/Shaders/flashed_effect.swsl b/Resources/Shaders/flashed_effect.swsl new file mode 100644 index 0000000000..fdbe860cb7 --- /dev/null +++ b/Resources/Shaders/flashed_effect.swsl @@ -0,0 +1,18 @@ +uniform float percentComplete; +uniform float fadeFalloffExp = 8; + +void fragment() { + // Higher exponent -> stronger blinding effect + float remaining = -pow(percentComplete, fadeFalloffExp) + 1; + + // Two ghost textures that spin around the character + vec4 tex1 = texture(TEXTURE, vec2(UV.x + (0.02) * sin(TIME * 3), UV.y + (0.02) * cos(TIME * 3))); + vec4 tex2 = texture(TEXTURE, vec2(UV.x + (0.01) * sin(TIME * 2), UV.y + (0.01) * cos(TIME * 2))); + + vec4 textureMix = mix(tex1, tex2, 0.5); + + // Gradually mixes between the texture mix and a full-white texture, causing the "blinding" effect + vec4 mixed = mix(vec4(1, 1, 1, 1), textureMix, percentComplete); + + COLOR = vec4(mixed.rgb, remaining); +} diff --git a/Resources/Textures/Objects/Melee/flash.rsi/burnt.png b/Resources/Textures/Objects/Melee/flash.rsi/burnt.png new file mode 100644 index 0000000000000000000000000000000000000000..b35979f0f75bff0c35d3cdae3530bced037b2bc0 GIT binary patch literal 354 zcmV-o0iFJdP)EqzL|BvIoJ1`gw{~b%G`Mgp|v-)APQQE7j(&RKdDZmRbvv;`~j{#B@ z3F!u>*-5>@1pp$B@cjUQM7;8uB;^a#>$UvYd&3bTj(CqgST9#f5<9Zt-M&Y+?{U<2 zxxc=|sWkww5B6lXk{8Ir+pY`1ajTU}oSmL1g-Z!!Ou|q(Oj}?!oo=l~94QO@dJGqf z*aFhx+S??gHyrW!^jyBcHi=^RdbuiJ0N|@?Q+x+>!a?B@ig{q&-rVK$uZy(6U!x^( z*w_cuA0cglBC3CZ(r+l{f#v@gNtJMe!C(OR2D(&pMl2!uD*ylh07*qoM6N<$f-FX& Ah5!Hn literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Melee/flash.rsi/flash.png b/Resources/Textures/Objects/Melee/flash.rsi/flash.png new file mode 100644 index 0000000000000000000000000000000000000000..a5afbcdae9d167b0ebea95769ee2c859ab356ff4 GIT binary patch literal 368 zcmV-$0gwKPP)A#;;^N>U?Wq*1pP-YG*a!HCk)dq{**TCBQTA zTAbsu*8`9y650)Zr791P4ge6tm@te0NW=?YNs_;Sx4D{adn2eLhB0sP2jjuWNMc4e zyw++`Yc-ia-s8M`fxlb^ptw@fSxR3Z4L@Dn1z=}uJCg`D){Vlo1X4~u?~KE&1v(G+ zKaRyPHWv8xHI(7IH=!*%N^Nr1rV-TXK0f6yph~23HGDi6>uin zTvRVO?L6h1(`MLyN;FYg0-9Ie01 ziZb~5U*Usb(at-^r|*8qCm;v}nX1QkIi7zSex@Sv?moTs&71yT-2C_Z|B|fF8!i{W zp^wHbw@8ee)SlRCK7kIr4Jnm*B(GA5E>xda=AM{aMr1t{>iU z>}Mu7{PCEn&iGm7!Qr!(t3@~V3*Tl7&+jk&wfb#sW#xtMk*Wzcb8~w8Q-i172@EcI a&7W{`*$RzKncBdhW$<+Mb6Mw<&;$Tle6Xhg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Melee/flash.rsi/inhand-left.png b/Resources/Textures/Objects/Melee/flash.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..950195a37d41d514ff09b7b29a5544a4d2d7d211 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=_dQ)4Ln`LHy`{)^$U&g>p*T;I z@s$a({aWkl-e2ClRs123hsX=p31+qjq=OFqpSf%M$u}iudsu)v85m^d)!zR$XM5=h zj=eT=yU*SJB%bgh%4Nlrq@7!Xyt+9uUj*$s5Z$ma`>#n>-Q6`CKfhj9Cl%b4@V?>o zOC8TH4)1%DHa~fH|H9U&)nAuot$k}=$LRUA?oUl`{sA*_umvEZdXnY&^7)^Ie>2W} z{v*Bl$?0N6+Id3>M=lOb{Y7Wi(hAH;v%ik*kwLZAN YhmpU|x3#6}d_Bl0Pgg&ebxsLQ0GCsHhX4Qo literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Melee/flash.rsi/inhand-right.png b/Resources/Textures/Objects/Melee/flash.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..7a17666d9cd7c615deb6649fb3228eea50a35448 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=?>$`{Ln`LHy`?MEY#`9~aPF+G zd5o7&{?dB&s963SoA^VXsVf!*i(c2{{MmSJPk-A<^V33`wV8lA85s6ee&1_v<=i!8 z&-5AXa;G=hpJfdClqYsT;&Eu`k+T06S+{*&rFCq^iamj{25UEed0g;M>BhP5j}g}TZ+%k|M!}G+vjsTi>4?1n11HbP0l+XkK)J=b6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Melee/flash.rsi/meta.json b/Resources/Textures/Objects/Melee/flash.rsi/meta.json new file mode 100644 index 0000000000..c0299aa63d --- /dev/null +++ b/Resources/Textures/Objects/Melee/flash.rsi/meta.json @@ -0,0 +1,76 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC BY-SA 3.0", + "copyright": "Taken from CEV Eris", + "states": [ + { + "name": "flash", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "flashing", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.3 + ] + ] + }, + { + "name": "burnt", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "inhand-right", + "directions": 4, + "delays": [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4, + "delays": [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ] + } + ] +} From cf400da4b64d29b97785f3d8b0e84e6b63f6b22b Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 6 Jul 2020 23:43:04 +0200 Subject: [PATCH 16/18] Update submodule --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 9e5374ac86..cc9391c029 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 9e5374ac867e08a98046c2e71d772af6bedd7818 +Subproject commit cc9391c029e155b2ef4ec7b89230e64ed69d4e47 From 5056ded35e8738eb698c6087969b545d5f8a3cf0 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 6 Jul 2020 23:44:29 +0200 Subject: [PATCH 17/18] Fix compile --- .../Components/Weapon/Melee/FlashComponent.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs index 354974a685..e5c20ae24a 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/FlashComponent.cs @@ -1,24 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; -using Content.Server.Interfaces; -using Content.Shared.Chat; +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects.Components.Mobs; using Content.Shared.Interfaces; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; -using Robust.Server.Interfaces.GameObjects; -using Robust.Server.Interfaces.Player; using Robust.Shared.Audio; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Network; -using Robust.Shared.Interfaces.Random; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Serialization; From c78ce3e27aaf8b0b4e150ea1239211a9462d1765 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Tue, 7 Jul 2020 00:04:30 +0200 Subject: [PATCH 18/18] Add click dragging for buckle (#1290) --- .../Components/Mobs/BuckleComponent.cs | 16 +++++++++++-- .../Components/Mobs/BuckleVisualizer2D.cs | 2 +- .../Components/Strap/StrapComponent.cs | 22 ++++++++++++++++++ Content.Client/IgnoredComponents.cs | 1 - .../Components/Mobs/BuckleComponent.cs | 7 +++++- .../Components/Strap/StrapComponent.cs | 8 +++++-- .../Components/Strap/SharedStrapComponent.cs | 23 +++++++++++++++---- Content.Shared/GameObjects/ContentNetIDs.cs | 1 + 8 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 Content.Client/GameObjects/Components/Strap/StrapComponent.cs diff --git a/Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs b/Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs index e22b23c0d0..0525ffaf5d 100644 --- a/Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs +++ b/Content.Client/GameObjects/Components/Mobs/BuckleComponent.cs @@ -1,10 +1,12 @@ -using Content.Shared.GameObjects.Components.Mobs; +using Content.Client.GameObjects.Components.Strap; +using Content.Client.Interfaces.GameObjects.Components.Interaction; +using Content.Shared.GameObjects.Components.Mobs; using Robust.Shared.GameObjects; namespace Content.Client.GameObjects.Components.Mobs { [RegisterComponent] - public class BuckleComponent : SharedBuckleComponent + public class BuckleComponent : SharedBuckleComponent, IClientDraggable { private bool _buckled; @@ -19,5 +21,15 @@ namespace Content.Client.GameObjects.Components.Mobs } protected override bool Buckled => _buckled; + + bool IClientDraggable.ClientCanDropOn(CanDropEventArgs eventArgs) + { + return eventArgs.Target.HasComponent(); + } + + bool IClientDraggable.ClientCanDrag(CanDragEventArgs eventArgs) + { + return true; + } } } diff --git a/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs b/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs index 3dfe3d10a4..755439c753 100644 --- a/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs +++ b/Content.Client/GameObjects/Components/Mobs/BuckleVisualizer2D.cs @@ -17,7 +17,7 @@ namespace Content.Client.GameObjects.Components.Mobs return; } - if (!component.TryGetData(SharedStrapComponent.StrapVisuals.RotationAngle, out var angle)) + if (!component.TryGetData(StrapVisuals.RotationAngle, out var angle)) { return; } diff --git a/Content.Client/GameObjects/Components/Strap/StrapComponent.cs b/Content.Client/GameObjects/Components/Strap/StrapComponent.cs new file mode 100644 index 0000000000..eabb96b01c --- /dev/null +++ b/Content.Client/GameObjects/Components/Strap/StrapComponent.cs @@ -0,0 +1,22 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Strap; +using Robust.Shared.GameObjects; + +namespace Content.Client.GameObjects.Components.Strap +{ + [RegisterComponent] + public class StrapComponent : SharedStrapComponent + { + public override StrapPosition Position { get; protected set; } + + public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) + { + if (!(curState is StrapComponentState strap)) + { + return; + } + + Position = strap.Position; + } + } +} diff --git a/Content.Client/IgnoredComponents.cs b/Content.Client/IgnoredComponents.cs index 961e34eae8..ce60d6b7f5 100644 --- a/Content.Client/IgnoredComponents.cs +++ b/Content.Client/IgnoredComponents.cs @@ -115,7 +115,6 @@ "Utensil", "UnarmedCombat", "TimedSpawner", - "Strap", "NodeContainer", "PowerSupplier", "PowerConsumer", diff --git a/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs b/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs index 747737cea4..a943e8a438 100644 --- a/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs +++ b/Content.Server/GameObjects/Components/Mobs/BuckleComponent.cs @@ -22,7 +22,7 @@ using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Mobs { [RegisterComponent] - public class BuckleComponent : SharedBuckleComponent, IInteractHand + public class BuckleComponent : SharedBuckleComponent, IInteractHand, IDragDrop { #pragma warning disable 649 [Dependency] private readonly IEntitySystemManager _entitySystem; @@ -299,6 +299,11 @@ namespace Content.Server.GameObjects.Components.Mobs return TryUnbuckle(eventArgs.User); } + bool IDragDrop.DragDrop(DragDropEventArgs eventArgs) + { + return TryBuckle(eventArgs.User, eventArgs.Target); + } + [Verb] private sealed class BuckleVerb : Verb { diff --git a/Content.Server/GameObjects/Components/Strap/StrapComponent.cs b/Content.Server/GameObjects/Components/Strap/StrapComponent.cs index 97da26fce6..539c605a8b 100644 --- a/Content.Server/GameObjects/Components/Strap/StrapComponent.cs +++ b/Content.Server/GameObjects/Components/Strap/StrapComponent.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Strap; @@ -35,7 +34,7 @@ namespace Content.Server.GameObjects.Components.Strap public override StrapPosition Position { get => _position; - set + protected set { _position = value; Dirty(); @@ -150,6 +149,11 @@ namespace Content.Server.GameObjects.Components.Strap OccupiedSize = 0; } + public override ComponentState GetComponentState() + { + return new StrapComponentState(Position); + } + [Verb] private sealed class StrapVerb : Verb { diff --git a/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs b/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs index febdbbb3e8..4ec1463c1a 100644 --- a/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs +++ b/Content.Shared/GameObjects/Components/Strap/SharedStrapComponent.cs @@ -26,12 +26,27 @@ namespace Content.Shared.GameObjects.Components.Strap { public sealed override string Name => "Strap"; - public virtual StrapPosition Position { get; set; } + public sealed override uint? NetID => ContentNetIDs.STRAP; - [Serializable, NetSerializable] - public enum StrapVisuals + public abstract StrapPosition Position { get; protected set; } + } + + [Serializable, NetSerializable] + public sealed class StrapComponentState : ComponentState + { + public readonly StrapPosition Position; + + public StrapComponentState(StrapPosition position) : base(ContentNetIDs.BUCKLE) { - RotationAngle + Position = position; } + + public bool Buckled { get; } + } + + [Serializable, NetSerializable] + public enum StrapVisuals + { + RotationAngle } } diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs index 566185c7e8..3d2dc7e9b3 100644 --- a/Content.Shared/GameObjects/ContentNetIDs.cs +++ b/Content.Shared/GameObjects/ContentNetIDs.cs @@ -59,6 +59,7 @@ public const uint BUCKLE = 1052; public const uint PROJECTILE = 1053; public const uint THROWN_ITEM = 1054; + public const uint STRAP = 1055; // Net IDs for integration tests. public const uint PREDICTION_TEST = 10001;