Files
wwdpublic/Content.Client/Verbs/VerbSystem.cs
SimpleStation14 a22601c7b5 Mirror: Obsolete Logger cleanup for EntitySystems part 2 (#237)
## Mirror of PR #26159: [Obsolete `Logger` cleanup for `EntitySystem`s
part 2](https://github.com/space-wizards/space-station-14/pull/26159)
from <img src="https://avatars.githubusercontent.com/u/10567778?v=4"
alt="space-wizards" width="22"/>
[space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14)

###### `7d275a4b5e4188db424cc417c609dced3f9aca89`

PR opened by <img
src="https://avatars.githubusercontent.com/u/27449516?v=4"
width="16"/><a href="https://github.com/LordCarve"> LordCarve</a> at
2024-03-15 20:15:41 UTC

---

PR changed 14 files with 36 additions and 25 deletions.

The PR had the following labels:
- Status: Needs Review


---

<details open="true"><summary><h1>Original Body</h1></summary>

> <!-- Please read these guidelines before opening your PR:
https://docs.spacestation14.io/en/getting-started/pr-guideline -->
> <!-- The text between the arrows are comments - they will not be
visible on your PR. -->
> 
> ## About the PR
> <!-- What did you change in this PR? -->
> Part 2 of 2, continuation of #25941 
> Gets rid of the remaining obsolete `Logger` method calls from all
`EntitySystem`s and uses the expected `Log` to get at the proper
sawmill.
> 
> In particular:
> 1. Make the `ExamineSystemShared`'s `InRangeUnObstructed` non-`static`
(so finally able to use instance-based `Log` rather than `Logger`) and
inject dependency to all systems that were using it as `static`.
> 2. Adjust 4 more `EntitySystem`s to use `Log` rather than `Logger`
that were missed in the previous PR.
> 
> Tested that the game runs and the affected systems direct logs to the
correct sawmill.
> 
> ## Why / Balance
> <!-- Why was it changed? Link any discussions or issues here. Please
discuss how this would affect game balance. -->
> Using Logger directly for logging is marked obsolete. Brings some
order to logs (i.e. all `EntitySystem` logs start with a preceding
`system.`).
> 
> ## Technical details
> <!-- If this is a code change, summarize at high level how your new
code works. This makes it easier to review. -->
> I'm pretty sure `ExamineSystemShared`'s `InRangeUnObstructed` not
being `static` is the intended way since it being `static` dodges the
IoC entirely. It even has dirty hacks such as getting the occluder
system inside to make it happen. I didn't fix any of that as it's beyond
the scope of this PR, but it's another thing that needs improving.
> 
> These are the changes to the log sawmills:
> `ExamineSystemShared.cs`: BEFORE: `root` -> NEW: `system.examine`
> `AtmosphereSystem.Monstermos.cs`: BEFORE: `root` -> NEW:
`system.atmosphere`
> `TypingIndicatorSystem.cs`: BEFORE: `root` -> NEW:
`system.typing_indicator`
> `PiratesRuleSystem.cs` BEFORE: `pirates` -> NEW: `system.pirates_rule`
> `TabletopSystem.Session.cs` BEFORE: `root` -> NEW: `system.tabletop`
> 
> ## Media
> <!-- 
> PRs which make ingame changes (adding clothing, items, new features,
etc) are required to have media attached that showcase the changes.
> Small fixes/refactors are exempt.
> Any media may be used in SS14 progress reports, with clear credit
given.
> 
> If you're unsure whether your PR will require media, ask a maintainer.
> 
> Check the box below to confirm that you have in fact seen this (put an
X in the brackets, like [X]):
> -->
> 
> - [X] I have added screenshots/videos to this PR showcasing its
changes ingame, **or** this PR does not require an ingame showcase
> 
> ## Breaking changes
> <!--
> List any breaking changes, including namespace, public
class/method/field changes, prototype renames; and provide instructions
for fixing them. This will be pasted in #codebase-changes.
> -->
> Some logs now fall under a different sawmill (more precise). Any
software that analyzes logs and makes assumptions on which sawmill do
these logs fall to will need to be adjusted.


</details>

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
Co-authored-by: SimpleStation14 <Unknown>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
2024-05-28 21:18:15 -04:00

250 lines
8.9 KiB
C#

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.Verbs;
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.Verbs
{
[UsedImplicitly]
public sealed class VerbSystem : SharedVerbSystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly ExamineSystem _examine = 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<VerbsResponseEvent>? OnVerbsResponse;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<VerbsResponseEvent>(HandleVerbResponse);
}
/// <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.LocalEntity;
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 (!_examine.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 (_examine.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 (!_examine.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<Verb> GetVerbs(EntityUid target, EntityUid user, Type type, bool force = false)
{
return GetVerbs(GetNetEntity(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<Verb> GetVerbs(NetEntity target, EntityUid user, List<Type> verbTypes,
bool force = false)
{
if (!target.IsClientSide())
RaiseNetworkEvent(new RequestServerVerbsEvent(target, verbTypes, adminRequest: force));
// Some admin menu interactions will try get verbs for entities that have not yet been sent to the player.
if (!TryGetEntity(target, out var local))
return new();
return GetLocalVerbs(local.Value, 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 ExecuteVerb(EntityUid target, Verb verb)
{
ExecuteVerb(GetNetEntity(target), verb);
}
/// <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 ExecuteVerb(NetEntity target, Verb verb)
{
if ( _playerManager.LocalEntity is not {} user)
return;
// is this verb actually valid?
if (verb.Disabled)
{
// maybe send an informative pop-up message.
if (!string.IsNullOrWhiteSpace(verb.Message))
_popupSystem.PopupEntity(verb.Message, user);
return;
}
if (verb.ClientExclusive || target.IsClientSide())
// is this a client exclusive (gui) verb?
ExecuteVerb(verb, user, GetEntity(target));
else
EntityManager.RaisePredictiveEvent(new ExecuteVerbEvent(target, verb));
}
private void HandleVerbResponse(VerbsResponseEvent msg)
{
OnVerbsResponse?.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
}
}