add ghostnado button to warp menu (#27556)
* add ghostnado button to warp menu * translator ops --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<DefaultWindow xmlns="https://spacestation14.io" Title="{Loc 'ghost-target-window-title'}" MinSize="450 450" SetSize="450 450">
|
<DefaultWindow xmlns="https://spacestation14.io" Title="{Loc 'ghost-target-window-title'}" MinSize="450 450" SetSize="450 450">
|
||||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
|
||||||
|
<Button Name="GhostnadoButton" Text="{Loc 'ghost-target-window-warp-to-most-followed'}" HorizontalAlignment="Center" Margin="0 4" />
|
||||||
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True" Margin="0 4" />
|
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True" Margin="0 4" />
|
||||||
<ScrollContainer VerticalExpand="True" HorizontalExpand="True" HScrollEnabled="False">
|
<ScrollContainer VerticalExpand="True" HorizontalExpand="True" HScrollEnabled="False">
|
||||||
<BoxContainer Name="ButtonContainer" Orientation="Vertical" VerticalExpand="True" SeparationOverride="5">
|
<BoxContainer Name="ButtonContainer" Orientation="Vertical" VerticalExpand="True" SeparationOverride="5">
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ namespace Content.Client.UserInterface.Systems.Ghost.Controls
|
|||||||
private string _searchText = string.Empty;
|
private string _searchText = string.Empty;
|
||||||
|
|
||||||
public event Action<NetEntity>? WarpClicked;
|
public event Action<NetEntity>? WarpClicked;
|
||||||
|
public event Action? OnGhostnadoClicked;
|
||||||
|
|
||||||
public GhostTargetWindow()
|
public GhostTargetWindow()
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
SearchBar.OnTextChanged += OnSearchTextChanged;
|
SearchBar.OnTextChanged += OnSearchTextChanged;
|
||||||
|
|
||||||
|
GhostnadoButton.OnPressed += _ => OnGhostnadoClicked?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateWarps(IEnumerable<GhostWarp> warps)
|
public void UpdateWarps(IEnumerable<GhostWarp> warps)
|
||||||
|
|||||||
@@ -111,6 +111,12 @@ public sealed class GhostUIController : UIController, IOnSystemChanged<GhostSyst
|
|||||||
_net.SendSystemNetworkMessage(msg);
|
_net.SendSystemNetworkMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGhostnadoClicked()
|
||||||
|
{
|
||||||
|
var msg = new GhostnadoRequestEvent();
|
||||||
|
_net.SendSystemNetworkMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadGui()
|
public void LoadGui()
|
||||||
{
|
{
|
||||||
if (Gui == null)
|
if (Gui == null)
|
||||||
@@ -120,6 +126,7 @@ public sealed class GhostUIController : UIController, IOnSystemChanged<GhostSyst
|
|||||||
Gui.ReturnToBodyPressed += ReturnToBody;
|
Gui.ReturnToBodyPressed += ReturnToBody;
|
||||||
Gui.GhostRolesPressed += GhostRolesPressed;
|
Gui.GhostRolesPressed += GhostRolesPressed;
|
||||||
Gui.TargetWindow.WarpClicked += OnWarpClicked;
|
Gui.TargetWindow.WarpClicked += OnWarpClicked;
|
||||||
|
Gui.TargetWindow.OnGhostnadoClicked += OnGhostnadoClicked;
|
||||||
|
|
||||||
UpdateGui();
|
UpdateGui();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,10 +43,16 @@ namespace Content.Server.Ghost
|
|||||||
[Dependency] private readonly TransformSystem _transformSystem = default!;
|
[Dependency] private readonly TransformSystem _transformSystem = default!;
|
||||||
[Dependency] private readonly VisibilitySystem _visibilitySystem = default!;
|
[Dependency] private readonly VisibilitySystem _visibilitySystem = default!;
|
||||||
|
|
||||||
|
private EntityQuery<GhostComponent> _ghostQuery;
|
||||||
|
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
|
_ghostQuery = GetEntityQuery<GhostComponent>();
|
||||||
|
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||||
|
|
||||||
SubscribeLocalEvent<GhostComponent, ComponentStartup>(OnGhostStartup);
|
SubscribeLocalEvent<GhostComponent, ComponentStartup>(OnGhostStartup);
|
||||||
SubscribeLocalEvent<GhostComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<GhostComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<GhostComponent, ComponentShutdown>(OnGhostShutdown);
|
SubscribeLocalEvent<GhostComponent, ComponentShutdown>(OnGhostShutdown);
|
||||||
@@ -62,6 +68,7 @@ namespace Content.Server.Ghost
|
|||||||
SubscribeNetworkEvent<GhostWarpsRequestEvent>(OnGhostWarpsRequest);
|
SubscribeNetworkEvent<GhostWarpsRequestEvent>(OnGhostWarpsRequest);
|
||||||
SubscribeNetworkEvent<GhostReturnToBodyRequest>(OnGhostReturnToBodyRequest);
|
SubscribeNetworkEvent<GhostReturnToBodyRequest>(OnGhostReturnToBodyRequest);
|
||||||
SubscribeNetworkEvent<GhostWarpToTargetRequestEvent>(OnGhostWarpToTargetRequest);
|
SubscribeNetworkEvent<GhostWarpToTargetRequestEvent>(OnGhostWarpToTargetRequest);
|
||||||
|
SubscribeNetworkEvent<GhostnadoRequestEvent>(OnGhostnadoRequest);
|
||||||
|
|
||||||
SubscribeLocalEvent<GhostComponent, BooActionEvent>(OnActionPerform);
|
SubscribeLocalEvent<GhostComponent, BooActionEvent>(OnActionPerform);
|
||||||
SubscribeLocalEvent<GhostComponent, ToggleGhostHearingActionEvent>(OnGhostHearingAction);
|
SubscribeLocalEvent<GhostComponent, ToggleGhostHearingActionEvent>(OnGhostHearingAction);
|
||||||
@@ -241,7 +248,7 @@ namespace Content.Server.Ghost
|
|||||||
private void OnGhostReturnToBodyRequest(GhostReturnToBodyRequest msg, EntitySessionEventArgs args)
|
private void OnGhostReturnToBodyRequest(GhostReturnToBodyRequest msg, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.SenderSession.AttachedEntity is not {Valid: true} attached
|
if (args.SenderSession.AttachedEntity is not {Valid: true} attached
|
||||||
|| !TryComp(attached, out GhostComponent? ghost)
|
|| !_ghostQuery.TryComp(attached, out var ghost)
|
||||||
|| !ghost.CanReturnToBody
|
|| !ghost.CanReturnToBody
|
||||||
|| !TryComp(attached, out ActorComponent? actor))
|
|| !TryComp(attached, out ActorComponent? actor))
|
||||||
{
|
{
|
||||||
@@ -257,7 +264,7 @@ namespace Content.Server.Ghost
|
|||||||
private void OnGhostWarpsRequest(GhostWarpsRequestEvent msg, EntitySessionEventArgs args)
|
private void OnGhostWarpsRequest(GhostWarpsRequestEvent msg, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.SenderSession.AttachedEntity is not {Valid: true} entity
|
if (args.SenderSession.AttachedEntity is not {Valid: true} entity
|
||||||
|| !HasComp<GhostComponent>(entity))
|
|| !_ghostQuery.HasComp(entity))
|
||||||
{
|
{
|
||||||
Log.Warning($"User {args.SenderSession.Name} sent a {nameof(GhostWarpsRequestEvent)} without being a ghost.");
|
Log.Warning($"User {args.SenderSession.Name} sent a {nameof(GhostWarpsRequestEvent)} without being a ghost.");
|
||||||
return;
|
return;
|
||||||
@@ -270,7 +277,7 @@ namespace Content.Server.Ghost
|
|||||||
private void OnGhostWarpToTargetRequest(GhostWarpToTargetRequestEvent msg, EntitySessionEventArgs args)
|
private void OnGhostWarpToTargetRequest(GhostWarpToTargetRequestEvent msg, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.SenderSession.AttachedEntity is not {Valid: true} attached
|
if (args.SenderSession.AttachedEntity is not {Valid: true} attached
|
||||||
|| !TryComp(attached, out GhostComponent? _))
|
|| !_ghostQuery.HasComp(attached))
|
||||||
{
|
{
|
||||||
Log.Warning($"User {args.SenderSession.Name} tried to warp to {msg.Target} without being a ghost.");
|
Log.Warning($"User {args.SenderSession.Name} tried to warp to {msg.Target} without being a ghost.");
|
||||||
return;
|
return;
|
||||||
@@ -284,17 +291,37 @@ namespace Content.Server.Ghost
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((TryComp(target, out WarpPointComponent? warp) && warp.Follow) || HasComp<MobStateComponent>(target))
|
WarpTo(attached, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGhostnadoRequest(GhostnadoRequestEvent msg, EntitySessionEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.SenderSession.AttachedEntity is not {} uid
|
||||||
|
|| !_ghostQuery.HasComp(uid))
|
||||||
{
|
{
|
||||||
_followerSystem.StartFollowingEntity(attached, target);
|
Log.Warning($"User {args.SenderSession.Name} tried to ghostnado without being a ghost.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xform = Transform(attached);
|
if (_followerSystem.GetMostFollowed() is not {} target)
|
||||||
_transformSystem.SetCoordinates(attached, xform, Transform(target).Coordinates);
|
return;
|
||||||
_transformSystem.AttachToGridOrMap(attached, xform);
|
|
||||||
if (TryComp(attached, out PhysicsComponent? physics))
|
WarpTo(uid, target);
|
||||||
_physics.SetLinearVelocity(attached, Vector2.Zero, body: physics);
|
}
|
||||||
|
|
||||||
|
private void WarpTo(EntityUid uid, EntityUid target)
|
||||||
|
{
|
||||||
|
if ((TryComp(target, out WarpPointComponent? warp) && warp.Follow) || HasComp<MobStateComponent>(target))
|
||||||
|
{
|
||||||
|
_followerSystem.StartFollowingEntity(uid, target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var xform = Transform(uid);
|
||||||
|
_transformSystem.SetCoordinates(uid, xform, Transform(target).Coordinates);
|
||||||
|
_transformSystem.AttachToGridOrMap(uid, xform);
|
||||||
|
if (_physicsQuery.TryComp(uid, out var physics))
|
||||||
|
_physics.SetLinearVelocity(uid, Vector2.Zero, body: physics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<GhostWarp> GetLocationWarps()
|
private IEnumerable<GhostWarp> GetLocationWarps()
|
||||||
|
|||||||
@@ -247,6 +247,27 @@ public sealed class FollowerSystem : EntitySystem
|
|||||||
StopFollowingEntity(player, uid, followed);
|
StopFollowingEntity(player, uid, followed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the most followed entity.
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid? GetMostFollowed()
|
||||||
|
{
|
||||||
|
EntityUid? picked = null;
|
||||||
|
int most = 0;
|
||||||
|
var query = EntityQueryEnumerator<FollowedComponent>();
|
||||||
|
while (query.MoveNext(out var uid, out var comp))
|
||||||
|
{
|
||||||
|
var count = comp.Following.Count;
|
||||||
|
if (count > most)
|
||||||
|
{
|
||||||
|
picked = uid;
|
||||||
|
most = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return picked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class FollowEvent : EntityEventArgs
|
public abstract class FollowEvent : EntityEventArgs
|
||||||
|
|||||||
@@ -125,6 +125,12 @@ namespace Content.Shared.Ghost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A client to server request for their ghost to be warped to the most followed entity.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class GhostnadoRequestEvent : EntityEventArgs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A client to server request for their ghost to return to body
|
/// A client to server request for their ghost to return to body
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ ghost-gui-toggle-hearing-popup-off = You can now only hear radio and nearby mess
|
|||||||
|
|
||||||
ghost-target-window-title = Ghost Warp
|
ghost-target-window-title = Ghost Warp
|
||||||
ghost-target-window-current-button = Warp: {$name}
|
ghost-target-window-current-button = Warp: {$name}
|
||||||
|
ghost-target-window-warp-to-most-followed = Warp to Most Followed
|
||||||
|
|
||||||
ghost-roles-window-title = Ghost Roles
|
ghost-roles-window-title = Ghost Roles
|
||||||
ghost-roles-window-request-role-button = Request
|
ghost-roles-window-request-role-button = Request
|
||||||
|
|||||||
Reference in New Issue
Block a user