No context menu through occluder (#1934)
* No context menu through occluder * Fix disabled occluders * Comment * Server-side verb ray check Decided to add a buffer because the entity is at the very edge of the context box (0.5, 0.5) then need to make sure that entities at the other end of the box are ignored. Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
@@ -7,13 +7,16 @@ using Content.Client.State;
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Client.Utility;
|
||||
using Content.Shared.GameObjects.EntitySystemMessages;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Physics;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects.EntitySystems;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Graphics.Drawing;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using Robust.Client.Interfaces.Graphics.ClientEye;
|
||||
using Robust.Client.Interfaces.Input;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Client.Interfaces.State;
|
||||
@@ -29,6 +32,7 @@ using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.Interfaces.Physics;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
@@ -40,7 +44,7 @@ using Timer = Robust.Shared.Timers.Timer;
|
||||
namespace Content.Client.GameObjects.EntitySystems
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public sealed class VerbSystem : EntitySystem
|
||||
public sealed class VerbSystem : SharedVerbSystem
|
||||
{
|
||||
[Dependency] private readonly IStateManager _stateManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
@@ -63,7 +67,7 @@ namespace Content.Client.GameObjects.EntitySystems
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
|
||||
SubscribeNetworkEvent<VerbSystemMessages.VerbsResponseMessage>(FillEntityPopup);
|
||||
|
||||
IoCManager.InjectDependencies(this);
|
||||
@@ -114,12 +118,11 @@ namespace Content.Client.GameObjects.EntitySystems
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var mapCoordinates = args.Coordinates.ToMap(_mapManager);
|
||||
var entities = _entityManager.GetEntitiesIntersecting(mapCoordinates.MapId,
|
||||
Box2.CenteredAround(mapCoordinates.Position, (0.5f, 0.5f))).ToList();
|
||||
|
||||
if (entities.Count == 0)
|
||||
var playerEntity = _playerManager.LocalPlayer?.ControlledEntity;
|
||||
|
||||
if (playerEntity == null || !TryGetContextEntities(playerEntity, mapCoordinates, out var entities))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ using static Content.Shared.GameObjects.EntitySystemMessages.VerbSystemMessages;
|
||||
|
||||
namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
public class VerbSystem : EntitySystem
|
||||
public class VerbSystem : SharedVerbSystem
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
@@ -93,6 +93,11 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetContextEntities(userEntity, entity.Transform.MapPosition, out var entities, true) || !entities.Contains(entity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var data = new List<VerbsResponseMessage.NetVerbData>();
|
||||
//Get verbs, component dependent.
|
||||
foreach (var (component, verb) in VerbUtility.GetVerbs(entity))
|
||||
|
||||
71
Content.Shared/GameObjects/Verbs/SharedVerbSystem.cs
Normal file
71
Content.Shared/GameObjects/Verbs/SharedVerbSystem.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.Shared.GameObjects.Verbs
|
||||
{
|
||||
public class SharedVerbSystem : EntitySystem
|
||||
{
|
||||
private SharedInteractionSystem _interactionSystem = null!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_interactionSystem = Get<SharedInteractionSystem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all of the entities relevant for the contextmenu
|
||||
/// </summary>
|
||||
/// <param name="player"></param>
|
||||
/// <param name="targetPos"></param>
|
||||
/// <param name="contextEntities"></param>
|
||||
/// <param name="buffer">Whether we should slightly extend out the ignored range for the ray predicated</param>
|
||||
/// <returns></returns>
|
||||
protected bool TryGetContextEntities(IEntity player, MapCoordinates targetPos, [NotNullWhen(true)] out List<IEntity>? contextEntities, bool buffer = false)
|
||||
{
|
||||
contextEntities = null;
|
||||
var length = buffer ? 1.0f: 0.5f;
|
||||
|
||||
var entities = EntityManager.GetEntitiesIntersecting(targetPos.MapId,
|
||||
Box2.CenteredAround(targetPos.Position, (length, length))).ToList();
|
||||
|
||||
if (entities.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if we have LOS to the clicked-location, otherwise no popup.
|
||||
var vectorDiff = player.Transform.MapPosition.Position - targetPos.Position;
|
||||
var distance = vectorDiff.Length + 0.01f;
|
||||
Func<IEntity, bool> ignored = entity => entities.Contains(entity) ||
|
||||
entity == player ||
|
||||
!entity.TryGetComponent(out OccluderComponent? occluder) ||
|
||||
!occluder.Enabled;
|
||||
|
||||
var result = _interactionSystem.InRangeUnobstructed(
|
||||
player.Transform.MapPosition,
|
||||
targetPos,
|
||||
distance,
|
||||
(int) CollisionGroup.Opaque,
|
||||
ignored);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
contextEntities = entities;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user