Revert "Gamerule Entities" (#15724)
This commit is contained in:
23
Content.Client/Suspicion/SuspicionEndTimerSystem.cs
Normal file
23
Content.Client/Suspicion/SuspicionEndTimerSystem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using Content.Shared.Suspicion;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.Suspicion
|
||||
{
|
||||
public sealed class SuspicionEndTimerSystem : EntitySystem
|
||||
{
|
||||
public TimeSpan? EndTime { get; private set; }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<SuspicionMessages.SetSuspicionEndTimerMessage>(RxTimerMessage);
|
||||
}
|
||||
|
||||
private void RxTimerMessage(SuspicionMessages.SetSuspicionEndTimerMessage ev)
|
||||
{
|
||||
EndTime = ev.EndTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Content.Client/Suspicion/SuspicionGui.xaml
Normal file
8
Content.Client/Suspicion/SuspicionGui.xaml
Normal file
@@ -0,0 +1,8 @@
|
||||
<sus:SuspicionGui xmlns="https://spacestation14.io"
|
||||
xmlns:sus="clr-namespace:Content.Client.Suspicion">
|
||||
<BoxContainer Orientation="Vertical" SeparationOverride="0">
|
||||
<Button Name="RoleButton">
|
||||
<Label Name="TimerLabel" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
|
||||
</Button>
|
||||
</BoxContainer>
|
||||
</sus:SuspicionGui>
|
||||
126
Content.Client/Suspicion/SuspicionGui.xaml.cs
Normal file
126
Content.Client/Suspicion/SuspicionGui.xaml.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||
|
||||
namespace Content.Client.Suspicion
|
||||
{
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class SuspicionGui : UIWidget
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
private string? _previousRoleName;
|
||||
private bool _previousAntagonist;
|
||||
|
||||
public SuspicionGui()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
RoleButton.OnPressed += RoleButtonPressed;
|
||||
RoleButton.MinSize = (200, 60);
|
||||
}
|
||||
|
||||
private void RoleButtonPressed(ButtonEventArgs obj)
|
||||
{
|
||||
if (!TryGetComponent(out var role))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!role.Antagonist ?? false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var allies = string.Join(", ", role.Allies.Select(tuple => tuple.name));
|
||||
|
||||
role.Owner.PopupMessage(
|
||||
Loc.GetString(
|
||||
"suspicion-ally-count-display",
|
||||
("allyCount", role.Allies.Count),
|
||||
("allyNames", allies)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private bool TryGetComponent([NotNullWhen(true)] out SuspicionRoleComponent? suspicion)
|
||||
{
|
||||
suspicion = default;
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _entManager.TryGetComponent(_playerManager.LocalPlayer.ControlledEntity, out suspicion);
|
||||
}
|
||||
|
||||
public void UpdateLabel()
|
||||
{
|
||||
if (!TryGetComponent(out var suspicion))
|
||||
{
|
||||
Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (suspicion.Role == null || suspicion.Antagonist == null)
|
||||
{
|
||||
Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var endTime = _entManager.System<SuspicionEndTimerSystem>().EndTime;
|
||||
if (endTime == null)
|
||||
{
|
||||
TimerLabel.Visible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = endTime.Value - _timing.CurTime;
|
||||
if (diff < TimeSpan.Zero)
|
||||
{
|
||||
diff = TimeSpan.Zero;
|
||||
}
|
||||
TimerLabel.Visible = true;
|
||||
TimerLabel.Text = $"{diff:mm\\:ss}";
|
||||
}
|
||||
|
||||
if (_previousRoleName == suspicion.Role && _previousAntagonist == suspicion.Antagonist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_previousRoleName = suspicion.Role;
|
||||
_previousAntagonist = suspicion.Antagonist.Value;
|
||||
|
||||
var buttonText = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(_previousRoleName);
|
||||
buttonText = Loc.GetString(buttonText);
|
||||
|
||||
RoleButton.Text = buttonText;
|
||||
RoleButton.ModulateSelfOverride = _previousAntagonist ? Color.Red : Color.LimeGreen;
|
||||
|
||||
Visible = true;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
UpdateLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
128
Content.Client/Suspicion/SuspicionRoleComponent.cs
Normal file
128
Content.Client/Suspicion/SuspicionRoleComponent.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using Content.Shared.Suspicion;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using static Robust.Client.UserInterface.Controls.LayoutContainer;
|
||||
|
||||
namespace Content.Client.Suspicion
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class SuspicionRoleComponent : SharedSuspicionRoleComponent
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _ui = default!;
|
||||
|
||||
private SuspicionGui? _gui;
|
||||
private string? _role;
|
||||
private bool? _antagonist;
|
||||
private bool _overlayActive;
|
||||
|
||||
public string? Role
|
||||
{
|
||||
get => _role;
|
||||
set
|
||||
{
|
||||
if (_role == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_role = value;
|
||||
_gui?.UpdateLabel();
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public bool? Antagonist
|
||||
{
|
||||
get => _antagonist;
|
||||
set
|
||||
{
|
||||
if (_antagonist == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_antagonist = value;
|
||||
_gui?.UpdateLabel();
|
||||
|
||||
if (value ?? false)
|
||||
{
|
||||
AddTraitorOverlay();
|
||||
}
|
||||
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
public List<(string name, EntityUid uid)> Allies { get; } = new();
|
||||
|
||||
private void AddTraitorOverlay()
|
||||
{
|
||||
if (_overlayManager.HasOverlay<TraitorOverlay>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_overlayActive = true;
|
||||
var entManager = IoCManager.Resolve<IEntityManager>();
|
||||
var overlay = new TraitorOverlay(entManager, IoCManager.Resolve<IPlayerManager>(), _resourceCache, entManager.System<EntityLookupSystem>());
|
||||
_overlayManager.AddOverlay(overlay);
|
||||
}
|
||||
|
||||
private void RemoveTraitorOverlay()
|
||||
{
|
||||
if (!_overlayActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_overlayManager.RemoveOverlay<TraitorOverlay>();
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
|
||||
if (curState is not SuspicionRoleComponentState state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Role = state.Role;
|
||||
Antagonist = state.Antagonist;
|
||||
Allies.Clear();
|
||||
Allies.AddRange(state.Allies);
|
||||
}
|
||||
|
||||
public void RemoveUI()
|
||||
{
|
||||
_gui?.Parent?.RemoveChild(_gui);
|
||||
RemoveTraitorOverlay();
|
||||
}
|
||||
|
||||
public void AddUI()
|
||||
{
|
||||
// TODO move this out of the component
|
||||
_gui = _ui.ActiveScreen?.GetOrAddWidget<SuspicionGui>();
|
||||
_gui!.UpdateLabel();
|
||||
SetAnchorAndMarginPreset(_gui, LayoutPreset.BottomLeft);
|
||||
|
||||
if (_antagonist ?? false)
|
||||
{
|
||||
AddTraitorOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
|
||||
_gui?.Dispose();
|
||||
RemoveTraitorOverlay();
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Content.Client/Suspicion/SuspicionRoleSystem.cs
Normal file
18
Content.Client/Suspicion/SuspicionRoleSystem.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Suspicion
|
||||
{
|
||||
sealed class SuspicionRoleSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SuspicionRoleComponent, ComponentAdd>((_, component, _) => component.AddUI());
|
||||
SubscribeLocalEvent<SuspicionRoleComponent, ComponentRemove>((_, component, _) => component.RemoveUI());
|
||||
|
||||
SubscribeLocalEvent<SuspicionRoleComponent, PlayerAttachedEvent>((_, component, _) => component.AddUI());
|
||||
SubscribeLocalEvent<SuspicionRoleComponent, PlayerDetachedEvent>((_, component, _) => component.RemoveUI());
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Content.Client/Suspicion/TraitorOverlay.cs
Normal file
95
Content.Client/Suspicion/TraitorOverlay.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using Content.Shared.Examine;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
|
||||
namespace Content.Client.Suspicion
|
||||
{
|
||||
public sealed class TraitorOverlay : Overlay
|
||||
{
|
||||
private readonly IEntityManager _entityManager;
|
||||
private readonly IPlayerManager _playerManager;
|
||||
private readonly EntityLookupSystem _lookup;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
|
||||
private readonly Font _font;
|
||||
|
||||
private readonly string _traitorText = Loc.GetString("traitor-overlay-traitor-text");
|
||||
|
||||
public TraitorOverlay(
|
||||
IEntityManager entityManager,
|
||||
IPlayerManager playerManager,
|
||||
IResourceCache resourceCache,
|
||||
EntityLookupSystem lookup)
|
||||
{
|
||||
_playerManager = playerManager;
|
||||
_entityManager = entityManager;
|
||||
_lookup = lookup;
|
||||
|
||||
_font = new VectorFont(resourceCache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Regular.ttf"), 10);
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
var viewport = args.WorldAABB;
|
||||
|
||||
var ent = _playerManager.LocalPlayer?.ControlledEntity;
|
||||
if (_entityManager.TryGetComponent(ent, out SuspicionRoleComponent? sus) != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var (_, ally) in sus.Allies)
|
||||
{
|
||||
// Otherwise the entity can not exist yet
|
||||
if (!_entityManager.EntityExists(ally))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_entityManager.TryGetComponent(ally, out PhysicsComponent? physics))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var allyXform = _entityManager.GetComponent<TransformComponent>(ally);
|
||||
|
||||
var entPosition = _entityManager.GetComponent<TransformComponent>(ent.Value).MapPosition;
|
||||
var allyPosition = allyXform.MapPosition;
|
||||
if (!ExamineSystemShared.InRangeUnOccluded(entPosition, allyPosition, 15,
|
||||
entity => entity == ent || entity == ally))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if not on the same map, continue
|
||||
if (allyXform.MapID != args.Viewport.Eye!.Position.MapId
|
||||
|| physics.Owner.IsInContainer())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var (allyWorldPos, allyWorldRot) = allyXform.GetWorldPositionRotation();
|
||||
|
||||
var worldBox = _lookup.GetWorldAABB(ally, allyXform);
|
||||
|
||||
// if not on screen, or too small, continue
|
||||
if (!worldBox.Intersects(in viewport) || worldBox.IsEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var screenCoordinates = args.ViewportControl!.WorldToScreen(worldBox.TopLeft + (0, 0.5f));
|
||||
args.ScreenHandle.DrawString(_font, screenCoordinates, _traitorText, Color.OrangeRed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user