Refactor Context Menus and make them use XAML & stylesheets (#4768)

* XAML verb menu

* fix ghost FOV

* spacing

* rename missed "ContextMenu"->"EntityMenu" instances

* move visibility checks to verb system

* update comment

* Remove CanSeeContainerCheck

* use ScrollContainer measure option

* MaxWidth / texxt line wrapping

* verb category default

Now when you click on a verb category, it should default to running the first member of that category.

This makes it much more convenient to eject/insert when there is only a single option

* only apply style to first verb category entry

* Use new visibility flags

* FoV -> Fov

* Revert "only apply style to first verb category entry"

This reverts commit 9a6a17dba600e3ae0421caed59fcab145c260c99.

* make all entity menu visibility checks clientside

* Fix empty unbuckle category

* fix merge
This commit is contained in:
Leon Friedrich
2021-10-28 18:21:19 +13:00
committed by GitHub
parent 224952110e
commit 49296e33a0
36 changed files with 1421 additions and 1535 deletions

View File

@@ -1,79 +1,15 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.Examine;
using Content.Shared.Interaction.Helpers;
using Content.Shared.Tag;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Content.Shared.Verbs
{
public class SharedVerbSystem : EntitySystem
{
[Dependency] private readonly IEntityLookup _lookup = default!;
/// <summary>
/// Get all of the entities in an area for displaying on the context menu.
/// Raises a number of events in order to get all verbs of the given type(s) defined in local systems. This
/// does not request verbs from the server.
/// </summary>
/// <param name="buffer">Whether we should slightly extend the entity search area.</param>
public bool TryGetContextEntities(IEntity player, MapCoordinates targetPos,
[NotNullWhen(true)] out List<IEntity>? contextEntities, bool buffer = false, bool ignoreVisibility = false)
{
contextEntities = null;
// Check if we have LOS to the clicked-location.
if (!ignoreVisibility && !player.InRangeUnOccluded(targetPos, range: ExamineSystemShared.ExamineRange))
return false;
// Get entities
var length = buffer ? 1.0f : 0.5f;
var entities = _lookup.GetEntitiesIntersecting(
targetPos.MapId,
Box2.CenteredAround(targetPos.Position, (length, length)))
.ToList();
if (entities.Count == 0) return false;
if (ignoreVisibility)
{
contextEntities = entities;
return true;
}
// perform visibility checks
var playerPos = player.Transform.MapPosition;
foreach (var entity in entities.ToList())
{
if (entity.HasTag("HideContextMenu"))
{
entities.Remove(entity);
continue;
}
if (!ExamineSystemShared.InRangeUnOccluded(
playerPos,
entity.Transform.MapPosition,
ExamineSystemShared.ExamineRange,
null) )
{
entities.Remove(entity);
}
}
if (entities.Count == 0)
return false;
contextEntities = entities;
return true;
}
/// <summary>
/// Raises a number of events in order to get all verbs of the given type(s)
/// </summary>
public Dictionary<VerbType, SortedSet<Verb>> GetVerbs(IEntity target, IEntity user, VerbType verbTypes)
public virtual Dictionary<VerbType, SortedSet<Verb>> GetLocalVerbs(IEntity target, IEntity user, VerbType verbTypes)
{
Dictionary<VerbType, SortedSet<Verb>> verbs = new();
@@ -109,41 +45,24 @@ namespace Content.Shared.Verbs
}
/// <summary>
/// Execute actions associated with the given verb.
/// Execute the provided verb.
/// </summary>
/// <remarks>
/// This will try to call delegates and raise any events for the given verb.
/// This will try to call the action delegates and raise the local events for the given verb.
/// </remarks>
public bool TryExecuteVerb(Verb verb)
public void ExecuteVerb(Verb verb)
{
var executed = false;
// Maybe run a delegate
if (verb.Act != null)
{
executed = true;
verb.Act.Invoke();
}
verb.Act?.Invoke();
// Maybe raise a local event
if (verb.LocalVerbEventArgs != null)
if (verb.ExecutionEventArgs != null)
{
executed = true;
if (verb.LocalEventTarget.IsValid())
RaiseLocalEvent(verb.LocalEventTarget, verb.LocalVerbEventArgs);
if (verb.EventTarget.IsValid())
RaiseLocalEvent(verb.EventTarget, verb.ExecutionEventArgs);
else
RaiseLocalEvent(verb.LocalVerbEventArgs);
RaiseLocalEvent(verb.ExecutionEventArgs);
}
// maybe raise a network event
if (verb.NetworkVerbEventArgs != null)
{
executed = true;
RaiseNetworkEvent(verb.NetworkVerbEventArgs);
}
// return false if all of these were null
return executed;
}
}
}