From 1ba222142a4344318518c3f871779995cf86ac93 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 22 Apr 2020 00:58:31 +1000 Subject: [PATCH] Created SharedInteractionSystem + Partial Fix #782 (#833) --- Content.Client/State/GameScreenBase.cs | 6 +- .../EntitySystems/Click/InteractionSystem.cs | 33 +--------- .../EntitySystems/SharedInteractionSystem.cs | 64 +++++++++++++++++++ 3 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs diff --git a/Content.Client/State/GameScreenBase.cs b/Content.Client/State/GameScreenBase.cs index 3e277799dd..28c1bf6a46 100644 --- a/Content.Client/State/GameScreenBase.cs +++ b/Content.Client/State/GameScreenBase.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Content.Client.GameObjects.Components; +using Content.Server.GameObjects.EntitySystems; using Content.Shared.GameObjects; using Robust.Client.GameObjects.EntitySystems; using Robust.Client.Interfaces.GameObjects; @@ -56,9 +57,10 @@ namespace Content.Client.State var inRange = false; if (_playerManager.LocalPlayer.ControlledEntity != null && entityToClick != null) { - var playerPos = _playerManager.LocalPlayer.ControlledEntity.Transform.WorldPosition; + var playerPos = _playerManager.LocalPlayer.ControlledEntity.Transform.MapPosition; var entityPos = entityToClick.Transform.WorldPosition; - inRange = (entityPos - playerPos).Length <= VerbUtility.InteractionRange; + inRange = _entitySystemManager.GetEntitySystem() + .InRangeUnobstructed(playerPos,entityPos,ignoredEnt: _playerManager.LocalPlayer.ControlledEntity); } InteractionOutlineComponent outline; diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index 5045d364d8..e42c37978c 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -287,7 +287,7 @@ namespace Content.Server.GameObjects.EntitySystems /// Governs interactions during clicking on entities /// [UsedImplicitly] - public sealed class InteractionSystem : EntitySystem + public sealed class InteractionSystem : SharedInteractionSystem { #pragma warning disable 649 [Dependency] private readonly IMapManager _mapManager; @@ -308,38 +308,7 @@ namespace Content.Server.GameObjects.EntitySystems new PointerInputCmdHandler(HandleActivateItemInWorld)); } - /// - /// Checks that these coordinates are within a certain distance without any - /// entity that matches the collision mask obstructing them. - /// If the is zero or negative, - /// this method will only check if nothing obstructs the two sets of coordinates.. - /// - /// Set of coordinates to use. - /// Other set of coordinates to use. - /// maximum distance between the two sets of coordinates. - /// the mask to check for collisions - /// the entity to be ignored when checking for collisions. - /// Map manager containing the two GridIds. - /// if coordinates inside obstructions count as obstructed or not - /// True if the two points are within a given range without being obstructed. - public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange, - int collisionMask = (int) CollisionGroup.Impassable, IEntity ignoredEnt = null, bool insideBlockerValid = false) - { - var dir = otherCoords - coords.Position; - if (dir.LengthSquared.Equals(0f)) - return true; - - if (range > 0f && !(dir.LengthSquared <= range*range)) - return false; - - var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask); - var rayResults = _physicsManager.IntersectRay(coords.MapId, ray, dir.Length, ignoredEnt, true); - - - - return !rayResults.DidHitObject || (insideBlockerValid && rayResults.DidHitObject && rayResults.Distance < 1f); - } private bool HandleActivateItemInWorld(ICommonSession session, GridCoordinates coords, EntityUid uid) { diff --git a/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs new file mode 100644 index 0000000000..9aaddba8a6 --- /dev/null +++ b/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs @@ -0,0 +1,64 @@ +using Content.Shared.Physics; +using JetBrains.Annotations; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.Interfaces.Physics; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; + +namespace Content.Server.GameObjects.EntitySystems +{ + /// + /// Governs interactions during clicking on entities + /// + [UsedImplicitly] + public class SharedInteractionSystem : EntitySystem + { + #pragma warning disable 649 + [Dependency] private readonly IMapManager _mapManager; + [Dependency] private readonly IPhysicsManager _physicsManager; + #pragma warning restore 649 + + public const float InteractionRange = 2; + public const float InteractionRangeSquared = InteractionRange * InteractionRange; + + /// + /// Checks that these coordinates are within a certain distance without any + /// entity that matches the collision mask obstructing them. + /// If the is zero or negative, + /// this method will only check if nothing obstructs the two sets of coordinates.. + /// + /// Set of coordinates to use. + /// Other set of coordinates to use. + /// maximum distance between the two sets of coordinates. + /// the mask to check for collisions + /// the entity to be ignored when checking for collisions. + /// Map manager containing the two GridIds. + /// if coordinates inside obstructions count as obstructed or not + /// True if the two points are within a given range without being obstructed. + public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange, + int collisionMask = (int)CollisionGroup.Impassable, IEntity ignoredEnt = null, bool insideBlockerValid = false) + { + var dir = otherCoords - coords.Position; + + if (dir.LengthSquared.Equals(0f)) return true; + if (range > 0f && !(dir.LengthSquared <= range * range)) return false; + + var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask); + var rayResults = _physicsManager.IntersectRay(coords.MapId, ray, dir.Length, ignoredEnt, true); + if(!rayResults.DidHitObject || (insideBlockerValid && rayResults.DidHitObject && rayResults.Distance < 1f)) + { + _mapManager.TryFindGridAt(coords, out var mapGrid); + var srcPos = mapGrid.MapToGrid(coords); + var destPos = new GridCoordinates(otherCoords, mapGrid); + if (srcPos.InRange(_mapManager, destPos, InteractionRange)) + { + return true; + } + } + return false; + } + } +}