Adds even more smites and a bunch of tools. (#9825)

* Adds three new smites, headstand, locker stuff, and reptilian species swap.

* Localize all the smites.

* save work

* More smites...

* Final tweaks.

* oops

* !PLEH

* Adds disarm prone and improved hand removal options.

* fix chances.

* take out the trash.

* Add some admin TRICKS instead of more smites.

* oop

* Implements the admin test arena and associated trick.

* Tricks for granting/revoking access.

* e

* mfw

* Implement quick dialogs, for when you don't want to spend 20 minutes writing a simple dialog prompt.

* Forgot the rejuv icon.

* E

* docs

* augh

* Add rename/redescribe buttons.

* Adds objects menu, implements a couple tricks for stations.

* 1984

* Adds a trick for effectively infinite power.

* fixes some icon uggo.

* a

* HALT!

* Pause/unpause buttons.

* Forgor the textures.

* they broke every bone in their body.

* i added more

* more battery actions, touch up battery icon.

* Address reviews.
This commit is contained in:
Moony
2022-07-21 17:30:00 -05:00
committed by GitHub
parent ec18f438bc
commit f98df73fae
76 changed files with 3708 additions and 88 deletions

View File

@@ -1,3 +1,4 @@
using Content.Client.Administration.Systems;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.Enums;

View File

@@ -0,0 +1,10 @@
using Content.Shared.Administration.Components;
using Robust.Shared.GameStates;
namespace Content.Client.Administration.Components;
[RegisterComponent, NetworkedComponent]
public sealed class HeadstandComponent : SharedHeadstandComponent
{
}

View File

@@ -0,0 +1,154 @@
using System.Linq;
using Content.Client.UserInterface;
using Content.Shared.Administration;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.Administration;
/// <summary>
/// This handles the client portion of quick dialogs.
/// </summary>
public sealed class QuickDialogSystem : EntitySystem
{
/// <inheritdoc/>
public override void Initialize()
{
SubscribeNetworkEvent<QuickDialogOpenEvent>(OpenDialog);
}
private void OpenDialog(QuickDialogOpenEvent ev)
{
var window = new FancyWindow()
{
Title = ev.Title
};
var entryContainer = new BoxContainer()
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
Margin = new Thickness(8),
};
var promptsDict = new Dictionary<string, LineEdit>();
foreach (var entry in ev.Prompts)
{
var entryBox = new BoxContainer()
{
Orientation = BoxContainer.LayoutOrientation.Horizontal
};
entryBox.AddChild(new Label { Text = entry.Prompt, HorizontalExpand = true, SizeFlagsStretchRatio = 0.5f });
var edit = new LineEdit() { HorizontalExpand = true};
entryBox.AddChild(edit);
switch (entry.Type)
{
case QuickDialogEntryType.Integer:
edit.IsValid += VerifyInt;
edit.PlaceHolder = "Integer..";
break;
case QuickDialogEntryType.Float:
edit.IsValid += VerifyFloat;
edit.PlaceHolder = "Float..";
break;
case QuickDialogEntryType.ShortText:
edit.IsValid += VerifyShortText;
edit.PlaceHolder = "Short text..";
break;
case QuickDialogEntryType.LongText:
edit.IsValid += VerifyLongText;
edit.PlaceHolder = "Long text..";
break;
default:
throw new ArgumentOutOfRangeException();
}
promptsDict.Add(entry.FieldId, edit);
entryContainer.AddChild(entryBox);
}
var buttonsBox = new BoxContainer()
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
HorizontalAlignment = Control.HAlignment.Center,
};
var alreadyReplied = false;
if ((ev.Buttons & QuickDialogButtonFlag.OkButton) != 0)
{
var okButton = new Button()
{
Text = "Ok",
};
okButton.OnPressed += _ =>
{
RaiseNetworkEvent(new QuickDialogResponseEvent(ev.DialogId,
promptsDict.Select(x => (x.Key, x.Value.Text)).ToDictionary(x => x.Key, x => x.Text),
QuickDialogButtonFlag.OkButton));
alreadyReplied = true;
window.Close();
};
buttonsBox.AddChild(okButton);
}
if ((ev.Buttons & QuickDialogButtonFlag.OkButton) != 0)
{
var cancelButton = new Button()
{
Text = "Cancel",
};
cancelButton.OnPressed += _ =>
{
RaiseNetworkEvent(new QuickDialogResponseEvent(ev.DialogId,
new(),
QuickDialogButtonFlag.CancelButton));
alreadyReplied = true;
window.Close();
};
buttonsBox.AddChild(cancelButton);
}
window.OnClose += () =>
{
if (!alreadyReplied)
{
RaiseNetworkEvent(new QuickDialogResponseEvent(ev.DialogId,
new(),
QuickDialogButtonFlag.CancelButton));
}
};
entryContainer.AddChild(buttonsBox);
window.ContentsContainer.AddChild(entryContainer);
window.MinWidth *= 2; // Just double it.
window.OpenCentered();
}
private bool VerifyInt(string input)
{
return int.TryParse(input, out var _);
}
private bool VerifyFloat(string input)
{
return float.TryParse(input, out var _);
}
private bool VerifyShortText(string input)
{
return input.Length <= 100;
}
private bool VerifyLongText(string input)
{
return input.Length <= 2000;
}
}

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
using Content.Client.Administration.Managers;
using Content.Client.Administration.UI;
using Content.Client.Administration.UI.Tabs.ObjectsTab;
using Content.Client.Administration.UI.Tabs.PlayerTab;
using Content.Client.HUD;
using Content.Client.Verbs;
@@ -11,13 +11,11 @@ using Robust.Client.Input;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.Client.Administration
namespace Content.Client.Administration.Systems
{
public sealed partial class AdminSystem
{
@@ -101,13 +99,18 @@ namespace Content.Client.Administration
}
_window.PlayerTabControl.OnEntryPressed += PlayerTabEntryPressed;
_window.ObjectsTabControl.OnEntryPressed += ObjectsTabEntryPressed;
_window.OpenCentered();
}
public void Close()
{
if (_window != null)
{
_window.PlayerTabControl.OnEntryPressed -= PlayerTabEntryPressed;
_window.ObjectsTabControl.OnEntryPressed -= ObjectsTabEntryPressed;
}
_window?.Close();
foreach (var window in _commandWindows)
@@ -163,5 +166,23 @@ namespace Content.Client.Administration
args.Event.Handle();
}
private void ObjectsTabEntryPressed(BaseButton.ButtonEventArgs args)
{
if (args.Button is not ObjectsTabEntry button)
return;
var uid = button.AssocEntity;
var function = args.Event.Function;
if (function == EngineKeyFunctions.UIClick)
_clientConsoleHost.ExecuteCommand($"vv {uid}");
else if (function == ContentKeyFunctions.OpenContextMenu)
_verbSystem.VerbMenu.OpenVerbMenu(uid, true);
else
return;
args.Event.Handle();
}
}
}

View File

@@ -1,7 +1,7 @@
using Content.Client.Administration.Managers;
using Robust.Client.Graphics;
namespace Content.Client.Administration
namespace Content.Client.Administration.Systems
{
public sealed partial class AdminSystem
{

View File

@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Administration;
using Content.Shared.Administration.Events;
using Content.Shared.GameTicking;
using Robust.Shared.GameObjects;
using Robust.Shared.Network;
namespace Content.Client.Administration
namespace Content.Client.Administration.Systems
{
public sealed partial class AdminSystem : EntitySystem
{

View File

@@ -1,10 +1,7 @@
using Content.Shared.Verbs;
using Robust.Client.Console;
using Robust.Client.ViewVariables;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
namespace Content.Client.Verbs
namespace Content.Client.Administration.Systems
{
/// <summary>
/// Client-side admin verb system. These usually open some sort of UIs.

View File

@@ -1,7 +1,5 @@
#nullable enable
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Client.Administration.Managers;
using Content.Client.Administration.UI;
using Content.Client.Administration.UI.CustomControls;
@@ -9,16 +7,13 @@ using Content.Client.HUD;
using Content.Shared.Administration;
using JetBrains.Annotations;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Player;
using Robust.Shared.Localization;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Audio;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Player;
namespace Content.Client.Administration
namespace Content.Client.Administration.Systems
{
[UsedImplicitly]
public sealed class BwoinkSystem : SharedBwoinkSystem

View File

@@ -0,0 +1,35 @@
using Content.Client.Administration.Components;
using Robust.Client.GameObjects;
namespace Content.Client.Administration.Systems;
public sealed class HeadstandSystem : EntitySystem
{
public override void Initialize()
{
SubscribeLocalEvent<HeadstandComponent, ComponentStartup>(OnHeadstandAdded);
SubscribeLocalEvent<HeadstandComponent, ComponentShutdown>(OnHeadstandRemoved);
}
private void OnHeadstandAdded(EntityUid uid, HeadstandComponent component, ComponentStartup args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
foreach (var layer in sprite.AllLayers)
{
layer.Rotation += Angle.FromDegrees(180.0f);
}
}
private void OnHeadstandRemoved(EntityUid uid, HeadstandComponent component, ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
foreach (var layer in sprite.AllLayers)
{
layer.Rotation -= Angle.FromDegrees(180.0f);
}
}
}

View File

@@ -2,7 +2,7 @@
using Robust.Client.GameObjects;
using Robust.Shared.Utility;
namespace Content.Client.Administration;
namespace Content.Client.Administration.Systems;
public sealed class KillSignSystem : EntitySystem
{

View File

@@ -4,7 +4,8 @@
xmlns:adminbusTab="clr-namespace:Content.Client.Administration.UI.Tabs.AdminbusTab"
xmlns:atmosTab="clr-namespace:Content.Client.Administration.UI.Tabs.AtmosTab"
xmlns:tabs="clr-namespace:Content.Client.Administration.UI.Tabs"
xmlns:playerTab="clr-namespace:Content.Client.Administration.UI.Tabs.PlayerTab">
xmlns:playerTab="clr-namespace:Content.Client.Administration.UI.Tabs.PlayerTab"
xmlns:objectsTab="clr-namespace:Content.Client.Administration.UI.Tabs.ObjectsTab">
<TabContainer Name="MasterTabContainer">
<adminTab:AdminTab />
<adminbusTab:AdminbusTab />
@@ -12,5 +13,6 @@
<tabs:RoundTab />
<tabs:ServerTab />
<playerTab:PlayerTab Name="PlayerTabControl" Access="Public" />
<objectsTab:ObjectsTab Name="ObjectsTabControl" Access="Public" />
</TabContainer>
</DefaultWindow>

View File

@@ -25,6 +25,7 @@ namespace Content.Client.Administration.UI
MasterTabContainer.SetTabTitle(3, Loc.GetString("admin-menu-round-tab"));
MasterTabContainer.SetTabTitle(4, Loc.GetString("admin-menu-server-tab"));
MasterTabContainer.SetTabTitle(5, Loc.GetString("admin-menu-players-tab"));
MasterTabContainer.SetTabTitle(6, Loc.GetString("admin-menu-objects-tab"));
}
protected override void EnteredTree()

View File

@@ -3,6 +3,7 @@ using System.Linq;
using System.Text;
using System.Threading;
using Content.Client.Administration.Managers;
using Content.Client.Administration.Systems;
using Content.Client.Administration.UI.Tabs.AdminTab;
using Content.Client.Stylesheets;
using Content.Shared.Administration;

View File

@@ -1,5 +1,6 @@
#nullable enable
using System;
using Content.Client.Administration.Systems;
using Content.Shared.Administration;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Client.Administration.Systems;
using Content.Shared.Administration;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;

View File

@@ -0,0 +1,16 @@
<Control xmlns="https://spacestation14.io"
xmlns:pt="clr-namespace:Content.Client.Administration.UI.Tabs.PlayerTab"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label HorizontalExpand="True" SizeFlagsStretchRatio="0.50"
Text="{Loc Object type:}" />
<OptionButton Name="ObjectTypeOptions" HorizontalExpand="True" SizeFlagsStretchRatio="0.25"/>
</BoxContainer>
<cc:HSeparator/>
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Orientation="Vertical" Name="ObjectList">
</BoxContainer>
</ScrollContainer>
</BoxContainer>
</Control>

View File

@@ -0,0 +1,73 @@
using System.Linq;
using Content.Client.Station;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Administration.UI.Tabs.ObjectsTab;
[GenerateTypedNameReferences]
public sealed partial class ObjectsTab : Control
{
[Dependency] private readonly EntityManager _entityManager = default!;
private readonly List<ObjectsTabEntry> _objects = new();
private List<ObjectsTabSelection> _selections = new();
public event Action<BaseButton.ButtonEventArgs>? OnEntryPressed;
public ObjectsTab()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
ObjectTypeOptions.OnItemSelected += ev =>
{
ObjectTypeOptions.SelectId(ev.Id);
RefreshObjectList(_selections[ev.Id]);
};
foreach (var type in Enum.GetValues(typeof(ObjectsTabSelection)))
{
_selections.Add((ObjectsTabSelection)type!);
ObjectTypeOptions.AddItem(Enum.GetName((ObjectsTabSelection)type!)!);
}
RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]);
}
private void RefreshObjectList(ObjectsTabSelection selection)
{
var entities = selection switch
{
ObjectsTabSelection.Stations => _entityManager.EntitySysManager.GetEntitySystem<StationSystem>().Stations.ToList(),
ObjectsTabSelection.Grids => _entityManager.EntityQuery<IMapGridComponent>(true).Select(x => x.Owner).ToList(),
ObjectsTabSelection.Maps => _entityManager.EntityQuery<IMapComponent>(true).Select(x => x.Owner).ToList(),
_ => throw new ArgumentOutOfRangeException(nameof(selection), selection, null)
};
foreach (var control in _objects)
{
ObjectList.RemoveChild(control);
}
_objects.Clear();
foreach (var entity in entities)
{
var ctrl = new ObjectsTabEntry(_entityManager.GetComponent<MetaDataComponent>(entity).EntityName, entity);
_objects.Add(ctrl);
ObjectList.AddChild(ctrl);
ctrl.OnPressed += args => OnEntryPressed?.Invoke(args);
}
}
private enum ObjectsTabSelection
{
Grids,
Maps,
Stations,
}
}

View File

@@ -0,0 +1,18 @@
<ContainerButton xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
EnableAllKeybinds="True">
<PanelContainer Name="BackgroundColorPanel"/>
<BoxContainer Orientation="Horizontal"
HorizontalExpand="True"
SeparationOverride="4">
<Label Name="NameLabel"
SizeFlagsStretchRatio="3"
HorizontalExpand="True"
ClipText="True"/>
<customControls:VSeparator/>
<Label Name="EIDLabel"
SizeFlagsStretchRatio="3"
HorizontalExpand="True"
ClipText="True"/>
</BoxContainer>
</ContainerButton>

View File

@@ -0,0 +1,19 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Administration.UI.Tabs.ObjectsTab;
[GenerateTypedNameReferences]
public sealed partial class ObjectsTabEntry : ContainerButton
{
public EntityUid AssocEntity;
public ObjectsTabEntry(string name, EntityUid euid)
{
RobustXamlLoader.Load(this);
AssocEntity = euid;
EIDLabel.Text = euid.ToString();
NameLabel.Text = name;
}
}

View File

@@ -1,3 +1,4 @@
using Content.Client.Administration.Systems;
using Content.Shared.Administration;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;

View File

@@ -1,5 +1,6 @@
using System;
using Content.Client.Administration;
using Content.Client.Administration.Systems;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;

View File

@@ -3,6 +3,7 @@ using System.Linq;
using Content.Client.HUD.UI;
using Content.Client.Info;
using Content.Client.Administration;
using Content.Client.Administration.Systems;
using Content.Client.Resources;
using Content.Client.Targeting;
using Content.Shared.CCVar;

View File

@@ -0,0 +1,32 @@
using Content.Shared.Station;
namespace Content.Client.Station;
/// <summary>
/// This handles letting the client know stations are a thing. Only really used by an admin menu.
/// </summary>
public sealed class StationSystem : EntitySystem
{
private readonly HashSet<EntityUid> _stations = new();
/// <summary>
/// All stations that currently exist.
/// </summary>
/// <remarks>
/// I'd have this just invoke an entity query, but we're on the client and the client barely knows about stations.
/// </remarks>
public IReadOnlySet<EntityUid> Stations => _stations;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeNetworkEvent<StationsUpdatedEvent>(StationsUpdated);
}
private void StationsUpdated(StationsUpdatedEvent ev)
{
_stations.Clear();
_stations.UnionWith(ev.Stations);
}
}

View File

@@ -1,4 +1,5 @@
<ui:FancyWindow xmlns="https://spacestation14.io"
<ui:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface"
MouseFilter="Stop"
MinWidth="200" MinHeight="150">
@@ -15,6 +16,6 @@
</BoxContainer>
</Control>
<PanelContainer StyleClasses="LowDivider" />
<Control Name="ContentsContainer" Margin="0 2" RectClipContent="True" VerticalExpand="true" />
<Control Access="Public" Name="ContentsContainer" Margin="0 2" RectClipContent="True" VerticalExpand="true" />
</BoxContainer>
</ui:FancyWindow>