перенос файлов клиента из папки White в _White
This commit is contained in:
239
Content.Client/_White/Radials/RadialSystem.cs
Normal file
239
Content.Client/_White/Radials/RadialSystem.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Client.Examine;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Popups;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.White.Radials;
|
||||
using Content.Shared.White.Radials.Systems;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.State;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._White.Radials;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class RadialSystem : SharedRadialSystem
|
||||
{
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly ExamineSystem _examineSystem = default!;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
[Dependency] private readonly IStateManager _stateManager = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// When a user right clicks somewhere, how large is the box we use to get entities for the context menu?
|
||||
/// </summary>
|
||||
public const float EntityMenuLookupSize = 0.25f;
|
||||
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// These flags determine what entities the user can see on the context menu.
|
||||
/// </summary>
|
||||
public MenuVisibility Visibility;
|
||||
|
||||
public Action<RadialsResponseEvent>? OnRadialsResponse;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<RadialsResponseEvent>(HandleRadialsResponse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all of the entities in an area for displaying on the context menu.
|
||||
/// </summary>
|
||||
public bool TryGetEntityMenuEntities(MapCoordinates targetPos, [NotNullWhen(true)] out List<EntityUid>? result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (_stateManager.CurrentState is not GameplayStateBase gameScreenBase)
|
||||
return false;
|
||||
|
||||
var player = _playerManager.LocalPlayer?.ControlledEntity;
|
||||
if (player == null)
|
||||
return false;
|
||||
|
||||
// If FOV drawing is disabled, we will modify the visibility option to ignore visiblity checks.
|
||||
var visibility = _eyeManager.CurrentEye.DrawFov
|
||||
? Visibility
|
||||
: Visibility | MenuVisibility.NoFov;
|
||||
|
||||
|
||||
// Get entities
|
||||
List<EntityUid> entities;
|
||||
|
||||
// Do we have to do FoV checks?
|
||||
if ((visibility & MenuVisibility.NoFov) == 0)
|
||||
{
|
||||
var entitiesUnderMouse = gameScreenBase.GetClickableEntities(targetPos).ToHashSet();
|
||||
bool Predicate(EntityUid e) => e == player || entitiesUnderMouse.Contains(e);
|
||||
|
||||
// first check the general location.
|
||||
if (!_examineSystem.CanExamine(player.Value, targetPos, Predicate))
|
||||
return false;
|
||||
|
||||
TryComp(player.Value, out ExaminerComponent? examiner);
|
||||
|
||||
// Then check every entity
|
||||
entities = new();
|
||||
foreach (var ent in _entityLookup.GetEntitiesInRange(targetPos, EntityMenuLookupSize))
|
||||
{
|
||||
if (_examineSystem.CanExamine(player.Value, targetPos, Predicate, ent, examiner))
|
||||
entities.Add(ent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entities = _entityLookup.GetEntitiesInRange(targetPos, EntityMenuLookupSize).ToList();
|
||||
}
|
||||
|
||||
if (entities.Count == 0)
|
||||
return false;
|
||||
|
||||
if (visibility == MenuVisibility.All)
|
||||
{
|
||||
result = entities;
|
||||
return true;
|
||||
}
|
||||
|
||||
// remove any entities in containers
|
||||
if ((visibility & MenuVisibility.InContainer) == 0)
|
||||
{
|
||||
for (var i = entities.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var entity = entities[i];
|
||||
|
||||
if (ContainerSystem.IsInSameOrTransparentContainer(player.Value, entity))
|
||||
continue;
|
||||
|
||||
entities.RemoveSwap(i);
|
||||
}
|
||||
}
|
||||
|
||||
// remove any invisible entities
|
||||
if ((visibility & MenuVisibility.Invisible) == 0)
|
||||
{
|
||||
var spriteQuery = GetEntityQuery<SpriteComponent>();
|
||||
var tagQuery = GetEntityQuery<TagComponent>();
|
||||
|
||||
for (var i = entities.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var entity = entities[i];
|
||||
|
||||
if (!spriteQuery.TryGetComponent(entity, out var spriteComponent) ||
|
||||
!spriteComponent.Visible ||
|
||||
_tagSystem.HasTag(entity, "HideContextMenu", tagQuery))
|
||||
{
|
||||
entities.RemoveSwap(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any entities that do not have LOS
|
||||
if ((visibility & MenuVisibility.NoFov) == 0)
|
||||
{
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
var playerPos = xformQuery.GetComponent(player.Value).MapPosition;
|
||||
|
||||
for (var i = entities.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var entity = entities[i];
|
||||
|
||||
if (!ExamineSystemShared.InRangeUnOccluded(
|
||||
playerPos,
|
||||
xformQuery.GetComponent(entity).MapPosition,
|
||||
ExamineSystemShared.ExamineRange,
|
||||
null))
|
||||
{
|
||||
entities.RemoveSwap(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entities.Count == 0)
|
||||
return false;
|
||||
|
||||
result = entities;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asks the server to send back a list of server-side verbs, for the given verb type.
|
||||
/// </summary>
|
||||
public SortedSet<Radial> GetRadials(EntityUid target, EntityUid user, Type type, bool force = false)
|
||||
{
|
||||
return GetRadials(target, user, new List<Type>() { type }, force);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ask the server to send back a list of server-side verbs, and for now return an incomplete list of verbs
|
||||
/// (only those defined locally).
|
||||
/// </summary>
|
||||
public SortedSet<Radial> GetRadials(EntityUid target, EntityUid user, List<Type> verbTypes,
|
||||
bool force = false)
|
||||
{
|
||||
if (!IsClientSide(target))
|
||||
{
|
||||
RaiseNetworkEvent(new RequestServerRadialsEvent(GetNetEntity(target), verbTypes, adminRequest: force));
|
||||
}
|
||||
|
||||
// Some admin menu interactions will try get verbs for entities that have not yet been sent to the player.
|
||||
if (!Exists(target))
|
||||
return new();
|
||||
|
||||
return GetLocalRadials(target, user, verbTypes, force);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute actions associated with the given verb.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Unless this is a client-exclusive verb, this will also tell the server to run the same verb.
|
||||
/// </remarks>
|
||||
public void ExecuteRadial(EntityUid target, Radial radial)
|
||||
{
|
||||
var user = _playerManager.LocalPlayer?.ControlledEntity;
|
||||
if (user == null)
|
||||
return;
|
||||
|
||||
// is this verb actually valid?
|
||||
if (radial.Disabled)
|
||||
{
|
||||
// maybe send an informative pop-up message.
|
||||
if (!string.IsNullOrWhiteSpace(radial.Message))
|
||||
_popupSystem.PopupEntity(radial.Message, user.Value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (radial.ClientExclusive || IsClientSide(target))
|
||||
ExecuteRadial(radial, user.Value, target);
|
||||
else
|
||||
EntityManager.RaisePredictiveEvent(new ExecuteRadialEvent(GetNetEntity(target), radial));
|
||||
}
|
||||
|
||||
private void HandleRadialsResponse(RadialsResponseEvent msg)
|
||||
{
|
||||
OnRadialsResponse?.Invoke(msg);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum MenuVisibility
|
||||
{
|
||||
// What entities can a user see on the entity menu?
|
||||
Default = 0, // They can only see entities in FoV.
|
||||
NoFov = 1 << 0, // They ignore FoV restrictions
|
||||
InContainer = 1 << 1, // They can see through containers.
|
||||
Invisible = 1 << 2, // They can see entities without sprites and the "HideContextMenu" tag is ignored.
|
||||
All = NoFov | InContainer | Invisible
|
||||
}
|
||||
114
Content.Client/_White/Radials/RadialUIController.cs
Normal file
114
Content.Client/_White/Radials/RadialUIController.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Content.Client._White.UserInterface.Radial;
|
||||
using Content.Client.CombatMode;
|
||||
using Content.Client.ContextMenu.UI;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Shared.White.Radials;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
|
||||
namespace Content.Client._White.Radials;
|
||||
|
||||
public sealed class RadialUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
[UISystemDependency] private readonly CombatModeSystem _combatMode = default!;
|
||||
[UISystemDependency] private readonly RadialSystem _radialSystem = default!;
|
||||
|
||||
public EntityUid CurrentTarget;
|
||||
public SortedSet<Radial> CurrentRadials = new();
|
||||
|
||||
/// <summary>
|
||||
/// Separate from <see cref="ContextMenuUIController.RootMenu"/>, since we can open a verb menu as a submenu
|
||||
/// of an entity menu element. If that happens, we need to be aware and close it properly.
|
||||
/// </summary>
|
||||
public RadialContainer? OpenMenu;
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
//_context.OnContextClosed += Close;
|
||||
_radialSystem.OnRadialsResponse += HandleVerbsResponse;
|
||||
}
|
||||
|
||||
public void OnStateExited(GameplayState state)
|
||||
{
|
||||
//_context.OnContextClosed -= Close;
|
||||
_radialSystem.OnRadialsResponse -= HandleVerbsResponse;
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a verb menu and fill it with verbs applicable to the given target entity.
|
||||
/// </summary>
|
||||
/// <param name="target">Entity to get verbs on.</param>
|
||||
/// <param name="force">Used to force showing all verbs (mostly for admins).</param>
|
||||
public void OpenRadialMenu(EntityUid target, bool force = false)
|
||||
{
|
||||
if (_playerManager.LocalSession?.AttachedEntity is not { Valid: true } user ||
|
||||
_combatMode.IsInCombatMode(user))
|
||||
return;
|
||||
|
||||
Close();
|
||||
|
||||
CurrentTarget = target;
|
||||
CurrentRadials = _radialSystem.GetRadials(target, user, Radial.RadialTypes, force);
|
||||
OpenMenu = new RadialContainer();
|
||||
OpenMenu.NormalSize = 50;
|
||||
OpenMenu.FocusSize = 64;
|
||||
|
||||
//Feat: Disable action text, while im not fixed it
|
||||
OpenMenu.IsAction = false;
|
||||
}
|
||||
|
||||
private void FillRadial()
|
||||
{
|
||||
OpenMenu ??= new RadialContainer();
|
||||
|
||||
OpenMenu.CloseButton.Controller.OnPressed += _ => Close();
|
||||
|
||||
foreach (var radial in CurrentRadials)
|
||||
{
|
||||
var button = OpenMenu.AddButton(radial.Text, radial.Icon ?? null);
|
||||
button.Controller.OnPressed += _ => { ExecuteRadial(radial); };
|
||||
}
|
||||
|
||||
OpenMenu.Open(_userInterfaceManager.MousePositionScaled.Position);
|
||||
}
|
||||
|
||||
public void AddServerRadials(List<Radial> radials)
|
||||
{
|
||||
CurrentRadials.UnionWith(radials);
|
||||
FillRadial();
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
if (OpenMenu == null)
|
||||
return;
|
||||
|
||||
OpenMenu.Close();
|
||||
OpenMenu = null;
|
||||
}
|
||||
|
||||
private void HandleVerbsResponse(RadialsResponseEvent msg)
|
||||
{
|
||||
if (OpenMenu == null || CurrentTarget != _entityManager.GetEntity(msg.Entity))
|
||||
return;
|
||||
|
||||
if (msg.Radials == null)
|
||||
return;
|
||||
|
||||
AddServerRadials(msg.Radials);
|
||||
}
|
||||
|
||||
private void ExecuteRadial(Radial radial)
|
||||
{
|
||||
_radialSystem.ExecuteRadial(CurrentTarget, radial);
|
||||
|
||||
if (radial.CloseMenu ?? radial.CloseMenuDefault)
|
||||
Close(); //_context.Close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user