@@ -211,7 +211,7 @@ namespace Content.Client.Actions
|
||||
else
|
||||
{
|
||||
var request = new RequestPerformActionEvent(GetNetEntity(action));
|
||||
RaisePredictiveEvent(request);
|
||||
EntityManager.RaisePredictiveEvent(request);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections.Frozen;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Administration.Systems;
|
||||
@@ -25,7 +24,6 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
private readonly EntityLookupSystem _entityLookup;
|
||||
private readonly IUserInterfaceManager _userInterfaceManager;
|
||||
private readonly SharedRoleSystem _roles;
|
||||
private readonly IPrototypeManager _prototypeManager;
|
||||
private readonly Font _font;
|
||||
private readonly Font _fontBold;
|
||||
private AdminOverlayAntagFormat _overlayFormat;
|
||||
@@ -38,9 +36,8 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
private float _overlayMergeDistance;
|
||||
|
||||
//TODO make this adjustable via GUI?
|
||||
private static readonly FrozenSet<ProtoId<RoleTypePrototype>> Filter =
|
||||
new ProtoId<RoleTypePrototype>[] {"SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"}
|
||||
.ToFrozenSet();
|
||||
private readonly ProtoId<RoleTypePrototype>[] _filter =
|
||||
["SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"];
|
||||
|
||||
private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic");
|
||||
|
||||
@@ -52,8 +49,7 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
EntityLookupSystem entityLookup,
|
||||
IUserInterfaceManager userInterfaceManager,
|
||||
IConfigurationManager config,
|
||||
SharedRoleSystem roles,
|
||||
IPrototypeManager prototypeManager)
|
||||
SharedRoleSystem roles)
|
||||
{
|
||||
_system = system;
|
||||
_entityManager = entityManager;
|
||||
@@ -61,7 +57,6 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
_entityLookup = entityLookup;
|
||||
_userInterfaceManager = userInterfaceManager;
|
||||
_roles = roles;
|
||||
_prototypeManager = prototypeManager;
|
||||
ZIndex = 200;
|
||||
// Setting these to a specific ttf would break the antag symbols
|
||||
_font = resourceCache.NotoStack();
|
||||
@@ -130,14 +125,6 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
foreach (var info in sortable.OrderBy(s => s.Item4.Y).ToList())
|
||||
{
|
||||
var playerInfo = info.Item1;
|
||||
var rolePrototype = playerInfo.RoleProto == null
|
||||
? null
|
||||
: _prototypeManager.Index(playerInfo.RoleProto.Value);
|
||||
|
||||
var roleName = Loc.GetString(rolePrototype?.Name ?? RoleTypePrototype.FallbackName);
|
||||
var roleColor = rolePrototype?.Color ?? RoleTypePrototype.FallbackColor;
|
||||
var roleSymbol = rolePrototype?.Symbol ?? RoleTypePrototype.FallbackSymbol;
|
||||
|
||||
var aabb = info.Item2;
|
||||
var entity = info.Item3;
|
||||
var screenCoordinatesCenter = info.Item4;
|
||||
@@ -222,7 +209,7 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
switch (_overlaySymbolStyle)
|
||||
{
|
||||
case AdminOverlayAntagSymbolStyle.Specific:
|
||||
symbol = roleSymbol;
|
||||
symbol = playerInfo.RoleProto.Symbol;
|
||||
break;
|
||||
case AdminOverlayAntagSymbolStyle.Basic:
|
||||
symbol = Loc.GetString("player-tab-antag-prefix");
|
||||
@@ -238,17 +225,17 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
switch (_overlayFormat)
|
||||
{
|
||||
case AdminOverlayAntagFormat.Roletype:
|
||||
color = roleColor;
|
||||
symbol = IsFiltered(playerInfo.RoleProto) ? symbol : string.Empty;
|
||||
text = IsFiltered(playerInfo.RoleProto)
|
||||
? roleName.ToUpper()
|
||||
color = playerInfo.RoleProto.Color;
|
||||
symbol = _filter.Contains(playerInfo.RoleProto) ? symbol : string.Empty;
|
||||
text = _filter.Contains(playerInfo.RoleProto)
|
||||
? Loc.GetString(playerInfo.RoleProto.Name).ToUpper()
|
||||
: string.Empty;
|
||||
break;
|
||||
case AdminOverlayAntagFormat.Subtype:
|
||||
color = roleColor;
|
||||
symbol = IsFiltered(playerInfo.RoleProto) ? symbol : string.Empty;
|
||||
text = IsFiltered(playerInfo.RoleProto)
|
||||
? _roles.GetRoleSubtypeLabel(roleName, playerInfo.Subtype).ToUpper()
|
||||
color = playerInfo.RoleProto.Color;
|
||||
symbol = _filter.Contains(playerInfo.RoleProto) ? symbol : string.Empty;
|
||||
text = _filter.Contains(playerInfo.RoleProto)
|
||||
? _roles.GetRoleSubtypeLabel(playerInfo.RoleProto.Name, playerInfo.Subtype).ToUpper()
|
||||
: string.Empty;
|
||||
break;
|
||||
default:
|
||||
@@ -271,12 +258,4 @@ internal sealed class AdminNameOverlay : Overlay
|
||||
drawnOverlays.Add((screenCoordinatesCenter, currentOffset));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsFiltered(ProtoId<RoleTypePrototype>? roleProtoId)
|
||||
{
|
||||
if (roleProtoId == null)
|
||||
return false;
|
||||
|
||||
return Filter.Contains(roleProtoId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Administration.Systems
|
||||
{
|
||||
@@ -18,7 +17,6 @@ namespace Content.Client.Administration.Systems
|
||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
private AdminNameOverlay _adminNameOverlay = default!;
|
||||
|
||||
@@ -35,8 +33,7 @@ namespace Content.Client.Administration.Systems
|
||||
_entityLookup,
|
||||
_userInterfaceManager,
|
||||
_configurationManager,
|
||||
_roles,
|
||||
_proto);
|
||||
_roles);
|
||||
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<DefaultWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
Title="{Loc ban-panel-title}" MinSize="410 500">
|
||||
Title="{Loc ban-panel-title}" MinSize="350 500">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<TabContainer Name="Tabs" VerticalExpand="True">
|
||||
<!-- Basic info -->
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Numerics;
|
||||
using Content.Client.Administration.UI.CustomControls;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
@@ -33,21 +31,14 @@ public sealed partial class BanPanel : DefaultWindow
|
||||
private uint Multiplier { get; set; }
|
||||
private bool HasBanFlag { get; set; }
|
||||
private TimeSpan? ButtonResetOn { get; set; }
|
||||
|
||||
// This is less efficient than just holding a reference to the root control and enumerating children, but you
|
||||
// have to know how the controls are nested, which makes the code more complicated.
|
||||
// Role group name -> the role buttons themselves.
|
||||
private readonly Dictionary<string, List<Button>> _roleCheckboxes = new();
|
||||
private readonly List<CheckBox> _roleCheckboxes = new();
|
||||
private readonly ISawmill _banpanelSawmill;
|
||||
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||
|
||||
private const string ExpandedArrow = "▼";
|
||||
private const string ContractedArrow = "▶";
|
||||
|
||||
private enum TabNumbers
|
||||
{
|
||||
@@ -153,90 +144,47 @@ public sealed partial class BanPanel : DefaultWindow
|
||||
|
||||
ReasonTextEdit.Placeholder = new Rope.Leaf(Loc.GetString("ban-panel-reason"));
|
||||
|
||||
var departmentJobs = _protoMan.EnumeratePrototypes<DepartmentPrototype>()
|
||||
.OrderBy(x => x.Weight);
|
||||
foreach (var proto in departmentJobs)
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
foreach (var proto in prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||
{
|
||||
var roles = proto.Roles.Select(x => _protoMan.Index(x))
|
||||
.OrderBy(x => x.ID);
|
||||
CreateRoleGroup(proto.ID, proto.Color, roles);
|
||||
CreateRoleGroup(proto.ID, proto.Roles.Select(p => p.Id), proto.Color);
|
||||
}
|
||||
|
||||
var antagRoles = _protoMan.EnumeratePrototypes<AntagPrototype>()
|
||||
.OrderBy(x => x.ID);
|
||||
CreateRoleGroup("Antagonist", Color.Red, antagRoles);
|
||||
CreateRoleGroup("Antagonist", prototypeManager.EnumeratePrototypes<AntagPrototype>().Select(p => p.ID), Color.Red);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a "Role group" which stores information and logic for one "group" of roll bans.
|
||||
/// For example, all antags are one group, logi is a group, medical is a group, etc...
|
||||
/// </summary>
|
||||
private void CreateRoleGroup<T>(string groupName, Color color, IEnumerable<T> roles) where T : class, IPrototype
|
||||
private void CreateRoleGroup(string roleName, IEnumerable<string> roleList, Color color)
|
||||
{
|
||||
var outerContainer = new BoxContainer
|
||||
{
|
||||
Name = $"{groupName}GroupOuterBox",
|
||||
Name = $"{roleName}GroupOuterBox",
|
||||
HorizontalExpand = true,
|
||||
VerticalExpand = true,
|
||||
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
||||
Margin = new Thickness(4),
|
||||
Margin = new Thickness(4)
|
||||
};
|
||||
|
||||
// Stores stuff like ban all and expand buttons.
|
||||
var roleGroupHeader = new BoxContainer
|
||||
var departmentCheckbox = new CheckBox
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||
Name = $"{roleName}GroupCheckbox",
|
||||
Text = roleName,
|
||||
Modulate = color,
|
||||
HorizontalAlignment = HAlignment.Left
|
||||
};
|
||||
|
||||
// Stores the role checkboxes themselves.
|
||||
var innerContainer = new GridContainer
|
||||
outerContainer.AddChild(departmentCheckbox);
|
||||
var innerContainer = new BoxContainer
|
||||
{
|
||||
Name = $"{groupName}GroupInnerBox",
|
||||
Name = $"{roleName}GroupInnerBox",
|
||||
HorizontalExpand = true,
|
||||
Columns = 2,
|
||||
Visible = false,
|
||||
Margin = new Thickness(15, 5, 0, 5),
|
||||
Orientation = BoxContainer.LayoutOrientation.Horizontal
|
||||
};
|
||||
|
||||
var roleGroupCheckbox = CreateRoleGroupHeader(groupName, roleGroupHeader, color, innerContainer);
|
||||
|
||||
outerContainer.AddChild(roleGroupHeader);
|
||||
|
||||
// Add the roles themselves
|
||||
foreach (var role in roles)
|
||||
departmentCheckbox.OnToggled += args =>
|
||||
{
|
||||
AddRoleCheckbox(groupName, role.ID, innerContainer, roleGroupCheckbox);
|
||||
}
|
||||
|
||||
outerContainer.AddChild(innerContainer);
|
||||
|
||||
RolesContainer.AddChild(new PanelContainer
|
||||
{
|
||||
PanelOverride = new StyleBoxFlat
|
||||
foreach (var child in innerContainer.Children)
|
||||
{
|
||||
BackgroundColor = color
|
||||
}
|
||||
});
|
||||
RolesContainer.AddChild(outerContainer);
|
||||
RolesContainer.AddChild(new HSeparator());
|
||||
}
|
||||
|
||||
private Button CreateRoleGroupHeader(string groupName, BoxContainer header, Color color, GridContainer innerContainer)
|
||||
{
|
||||
var roleGroupCheckbox = new Button
|
||||
{
|
||||
Name = $"{groupName}GroupCheckbox",
|
||||
Text = "Ban all",
|
||||
Margin = new Thickness(0, 0, 5, 0),
|
||||
ToggleMode = true,
|
||||
};
|
||||
|
||||
// When this is toggled, toggle all buttons in this group so they match.
|
||||
roleGroupCheckbox.OnToggled += args =>
|
||||
{
|
||||
foreach (var role in _roleCheckboxes[groupName])
|
||||
{
|
||||
role.Pressed = args.Pressed;
|
||||
if (child is CheckBox c)
|
||||
{
|
||||
c.Pressed = args.Pressed;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.Pressed)
|
||||
@@ -251,12 +199,15 @@ public sealed partial class BanPanel : DefaultWindow
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var roleButtons in _roleCheckboxes.Values)
|
||||
foreach (var childContainer in RolesContainer.Children)
|
||||
{
|
||||
foreach (var button in roleButtons)
|
||||
if (childContainer is Container)
|
||||
{
|
||||
if (button.Pressed)
|
||||
return;
|
||||
foreach (var child in childContainer.Children)
|
||||
{
|
||||
if (child is CheckBox { Pressed: true })
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,72 +220,38 @@ public sealed partial class BanPanel : DefaultWindow
|
||||
SeverityOption.SelectId((int) newSeverity);
|
||||
}
|
||||
};
|
||||
|
||||
var hideButton = new Button
|
||||
outerContainer.AddChild(innerContainer);
|
||||
foreach (var role in roleList)
|
||||
{
|
||||
Text = Loc.GetString("role-bans-expand-roles") + " " + ContractedArrow,
|
||||
ToggleMode = true,
|
||||
};
|
||||
hideButton.OnPressed += args =>
|
||||
AddRoleCheckbox(role, innerContainer, departmentCheckbox);
|
||||
}
|
||||
RolesContainer.AddChild(new PanelContainer
|
||||
{
|
||||
innerContainer.Visible = args.Button.Pressed;
|
||||
((Button)args.Button).Text = args.Button.Pressed
|
||||
? Loc.GetString("role-bans-contract-roles") + " " + ExpandedArrow
|
||||
: Loc.GetString("role-bans-expand-roles") + " " + ContractedArrow;
|
||||
};
|
||||
header.AddChild(new Label
|
||||
{
|
||||
Text = groupName,
|
||||
Modulate = color,
|
||||
Margin = new Thickness(0, 0, 5, 0),
|
||||
PanelOverride = new StyleBoxFlat
|
||||
{
|
||||
BackgroundColor = color
|
||||
}
|
||||
});
|
||||
header.AddChild(roleGroupCheckbox);
|
||||
header.AddChild(hideButton);
|
||||
return roleGroupCheckbox;
|
||||
RolesContainer.AddChild(outerContainer);
|
||||
RolesContainer.AddChild(new HSeparator());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a checkbutton specifically for one "role" in a "group"
|
||||
/// E.g. it would add the Chief Medical Officer "role" into the "Medical" group.
|
||||
/// </summary>
|
||||
private void AddRoleCheckbox(string group, string role, GridContainer roleGroupInnerContainer, Button roleGroupCheckbox)
|
||||
private void AddRoleCheckbox(string role, Control container, CheckBox header)
|
||||
{
|
||||
var roleCheckboxContainer = new BoxContainer();
|
||||
var roleCheckButton = new Button
|
||||
var roleCheckbox = new CheckBox
|
||||
{
|
||||
Name = $"{role}RoleCheckbox",
|
||||
Text = role,
|
||||
ToggleMode = true,
|
||||
Text = role
|
||||
};
|
||||
roleCheckButton.OnToggled += args =>
|
||||
roleCheckbox.OnToggled += args =>
|
||||
{
|
||||
// Checks the role group checkbox if all the children are pressed
|
||||
if (args.Pressed && _roleCheckboxes[group].All(e => e.Pressed))
|
||||
roleGroupCheckbox.Pressed = args.Pressed;
|
||||
if (args is { Pressed: true, Button.Parent: { } } && args.Button.Parent.Children.Where(e => e is CheckBox).All(e => ((CheckBox) e).Pressed))
|
||||
header.Pressed = args.Pressed;
|
||||
else
|
||||
roleGroupCheckbox.Pressed = false;
|
||||
header.Pressed = false;
|
||||
};
|
||||
|
||||
// This is adding the icon before the role name
|
||||
// Yeah, this is sus, but having to split the functions up and stuff is worse imo.
|
||||
if (_protoMan.TryIndex<JobPrototype>(role, out var jobPrototype) && _protoMan.TryIndex(jobPrototype.Icon, out var iconProto))
|
||||
{
|
||||
var jobIconTexture = new TextureRect
|
||||
{
|
||||
Texture = _entMan.System<SpriteSystem>().Frame0(iconProto.Icon),
|
||||
TextureScale = new Vector2(2.5f, 2.5f),
|
||||
Stretch = TextureRect.StretchMode.KeepCentered,
|
||||
Margin = new Thickness(5, 0, 0, 0),
|
||||
};
|
||||
roleCheckboxContainer.AddChild(jobIconTexture);
|
||||
}
|
||||
|
||||
roleCheckboxContainer.AddChild(roleCheckButton);
|
||||
|
||||
roleGroupInnerContainer.AddChild(roleCheckboxContainer);
|
||||
|
||||
_roleCheckboxes.TryAdd(group, []);
|
||||
_roleCheckboxes[group].Add(roleCheckButton);
|
||||
container.AddChild(roleCheckbox);
|
||||
_roleCheckboxes.Add(roleCheckbox);
|
||||
}
|
||||
|
||||
public void UpdateBanFlag(bool newFlag)
|
||||
@@ -552,13 +469,7 @@ public sealed partial class BanPanel : DefaultWindow
|
||||
if (_roleCheckboxes.Count == 0)
|
||||
throw new DebugAssertException("RoleCheckboxes was empty");
|
||||
|
||||
foreach (var button in _roleCheckboxes.Values.SelectMany(departmentButtons => departmentButtons))
|
||||
{
|
||||
if (button is { Pressed: true, Text: not null })
|
||||
{
|
||||
rolesList.Add(button.Text);
|
||||
}
|
||||
}
|
||||
rolesList.AddRange(_roleCheckboxes.Where(c => c is { Pressed: true, Text: { } }).Select(c => c.Text!));
|
||||
|
||||
if (rolesList.Count == 0)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
<Control HorizontalExpand="True"/>
|
||||
<Label Name="Count" Access="Public"/>
|
||||
<Control HorizontalExpand="True"/>
|
||||
<Button Name="ExportLogs" Access="Public" Text="{Loc admin-logs-export}"/>
|
||||
<Button Name="PopOutButton" Access="Public" Text="{Loc admin-logs-pop-out}"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Content.Client.Administration.UI.CustomControls;
|
||||
using System.Linq;
|
||||
using Content.Client.Eui;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Eui;
|
||||
@@ -17,16 +15,6 @@ public sealed class AdminLogsEui : BaseEui
|
||||
{
|
||||
[Dependency] private readonly IClyde _clyde = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||
[Dependency] private readonly IFileDialogManager _dialogManager = default!;
|
||||
[Dependency] private readonly ILogManager _log = default!;
|
||||
|
||||
private const char CsvSeparator = ',';
|
||||
private const string CsvQuote = "\"";
|
||||
private const string CsvHeader = "Date,ID,PlayerID,Severity,Type,Message";
|
||||
|
||||
private ISawmill _sawmill;
|
||||
|
||||
private bool _currentlyExportingLogs = false;
|
||||
|
||||
public AdminLogsEui()
|
||||
{
|
||||
@@ -38,9 +26,6 @@ public sealed class AdminLogsEui : BaseEui
|
||||
LogsControl.RefreshButton.OnPressed += _ => RequestLogs();
|
||||
LogsControl.NextButton.OnPressed += _ => NextLogs();
|
||||
LogsControl.PopOutButton.OnPressed += _ => PopOut();
|
||||
LogsControl.ExportLogs.OnPressed += _ => ExportLogs();
|
||||
|
||||
_sawmill = _log.GetSawmill("admin.logs.ui");
|
||||
}
|
||||
|
||||
private WindowRoot? Root { get; set; }
|
||||
@@ -89,71 +74,6 @@ public sealed class AdminLogsEui : BaseEui
|
||||
SendMessage(request);
|
||||
}
|
||||
|
||||
private async void ExportLogs()
|
||||
{
|
||||
if (_currentlyExportingLogs)
|
||||
return;
|
||||
|
||||
_currentlyExportingLogs = true;
|
||||
LogsControl.ExportLogs.Disabled = true;
|
||||
|
||||
var file = await _dialogManager.SaveFile(new FileDialogFilters(new FileDialogFilters.Group("csv")));
|
||||
|
||||
if (file == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// Buffer is set to 4KB for performance reasons. As the average export of 1000 logs is ~200KB
|
||||
await using var writer = new StreamWriter(file.Value.fileStream, bufferSize: 4096);
|
||||
await writer.WriteLineAsync(CsvHeader);
|
||||
foreach (var child in LogsControl.LogsContainer.Children)
|
||||
{
|
||||
if (child is not AdminLogLabel logLabel || !child.Visible)
|
||||
continue;
|
||||
|
||||
var log = logLabel.Log;
|
||||
|
||||
// Date
|
||||
// I swear to god if someone adds ,s or "s to the other fields...
|
||||
await writer.WriteAsync(log.Date.ToString("s", System.Globalization.CultureInfo.InvariantCulture));
|
||||
await writer.WriteAsync(CsvSeparator);
|
||||
// ID
|
||||
await writer.WriteAsync(log.Id.ToString());
|
||||
await writer.WriteAsync(CsvSeparator);
|
||||
// PlayerID
|
||||
var players = log.Players;
|
||||
for (var i = 0; i < players.Length; i++)
|
||||
{
|
||||
await writer.WriteAsync(players[i] + (i == players.Length - 1 ? "" : " "));
|
||||
}
|
||||
await writer.WriteAsync(CsvSeparator);
|
||||
// Severity
|
||||
await writer.WriteAsync(log.Impact.ToString());
|
||||
await writer.WriteAsync(CsvSeparator);
|
||||
// Type
|
||||
await writer.WriteAsync(log.Type.ToString());
|
||||
await writer.WriteAsync(CsvSeparator);
|
||||
// Message
|
||||
await writer.WriteAsync(CsvQuote);
|
||||
await writer.WriteAsync(log.Message.Replace(CsvQuote, CsvQuote + CsvQuote));
|
||||
await writer.WriteAsync(CsvQuote);
|
||||
|
||||
await writer.WriteLineAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
_sawmill.Error($"Error when exporting admin log:\n{exc.StackTrace}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await file.Value.fileStream.DisposeAsync();
|
||||
_currentlyExportingLogs = false;
|
||||
LogsControl.ExportLogs.Disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopOut()
|
||||
{
|
||||
if (LogsWindow == null)
|
||||
|
||||
@@ -132,8 +132,8 @@ public sealed partial class ObjectsTab : Control
|
||||
entry.OnTeleport += TeleportTo;
|
||||
entry.OnDelete += Delete;
|
||||
button.ToolTip = $"{info.Name}, {info.Entity}";
|
||||
|
||||
button.AddChild(entry);
|
||||
button.StyleClasses.Clear();
|
||||
}
|
||||
|
||||
private bool DataFilterCondition(string filter, ListData listData)
|
||||
|
||||
@@ -172,7 +172,6 @@ public sealed partial class PlayerTab : Control
|
||||
_playerTabSymbolSetting);
|
||||
button.AddChild(entry);
|
||||
button.ToolTip = $"{player.Username}, {player.CharacterName}, {player.IdentityName}, {player.StartingJob}";
|
||||
button.StyleClasses.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
||||
|
||||
@@ -13,7 +11,6 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
||||
public sealed partial class PlayerTabEntry : PanelContainer
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
public PlayerTabEntry(
|
||||
PlayerInfo player,
|
||||
@@ -26,8 +23,6 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
||||
RobustXamlLoader.Load(this);
|
||||
var roles = _entMan.System<SharedRoleSystem>();
|
||||
|
||||
var rolePrototype = player.RoleProto == null ? null : _prototype.Index(player.RoleProto.Value);
|
||||
|
||||
UsernameLabel.Text = player.Username;
|
||||
if (!player.Connected)
|
||||
UsernameLabel.StyleClasses.Add("Disabled");
|
||||
@@ -62,19 +57,19 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
||||
break;
|
||||
default:
|
||||
case AdminPlayerTabSymbolOption.Specific:
|
||||
symbol = player.Antag ? rolePrototype?.Symbol ?? RoleTypePrototype.FallbackSymbol : string.Empty;
|
||||
symbol = player.Antag ? player.RoleProto.Symbol : string.Empty;
|
||||
break;
|
||||
}
|
||||
|
||||
CharacterLabel.Text = Loc.GetString("player-tab-character-name-antag-symbol", ("symbol", symbol), ("name", player.CharacterName));
|
||||
|
||||
if (player.Antag && colorAntags)
|
||||
CharacterLabel.FontColorOverride = rolePrototype?.Color ?? RoleTypePrototype.FallbackColor;
|
||||
CharacterLabel.FontColorOverride = player.RoleProto.Color;
|
||||
if (player.IdentityName != player.CharacterName)
|
||||
CharacterLabel.Text += $" [{player.IdentityName}]";
|
||||
|
||||
var roletype = RoleTypeLabel.Text = Loc.GetString(rolePrototype?.Name ?? RoleTypePrototype.FallbackName);
|
||||
var subtype = roles.GetRoleSubtypeLabel(rolePrototype?.Name ?? RoleTypePrototype.FallbackName, player.Subtype);
|
||||
var roletype = RoleTypeLabel.Text = Loc.GetString(player.RoleProto.Name);
|
||||
var subtype = roles.GetRoleSubtypeLabel(player.RoleProto.Name, player.Subtype);
|
||||
switch (roleSetting)
|
||||
{
|
||||
case AdminPlayerTabRoleTypeOption.RoleTypeSubtype:
|
||||
@@ -97,7 +92,7 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
||||
}
|
||||
|
||||
if (colorRoles)
|
||||
RoleTypeLabel.FontColorOverride = rolePrototype?.Color ?? RoleTypePrototype.FallbackColor;
|
||||
RoleTypeLabel.FontColorOverride = player.RoleProto.Color;
|
||||
BackgroundColorPanel.PanelOverride = styleBoxFlat;
|
||||
OverallPlaytimeLabel.Text = player.PlaytimeString;
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Alert.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Content.Client.Alerts;
|
||||
|
||||
/// <summary>
|
||||
/// This handles <see cref="GenericCounterAlertComponent"/>
|
||||
/// </summary>
|
||||
public sealed class GenericCounterAlertSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<GenericCounterAlertComponent, UpdateAlertSpriteEvent>(OnUpdateAlertSprite);
|
||||
}
|
||||
|
||||
private void OnUpdateAlertSprite(Entity<GenericCounterAlertComponent> ent, ref UpdateAlertSpriteEvent args)
|
||||
{
|
||||
var sprite = args.SpriteViewEnt.Comp;
|
||||
|
||||
var ev = new GetGenericAlertCounterAmountEvent(args.Alert);
|
||||
RaiseLocalEvent(args.ViewerEnt, ref ev);
|
||||
|
||||
if (!ev.Handled)
|
||||
return;
|
||||
|
||||
// It cannot be null if its handled, but good to check to avoid ugly null ignores.
|
||||
if (ev.Amount == null)
|
||||
return;
|
||||
|
||||
// How many digits can we display
|
||||
var maxDigitCount = GetMaxDigitCount((ent, ent, sprite));
|
||||
|
||||
// Clamp it to a positive number that we can actually display in full (no rollover to 0)
|
||||
var amount = (int) Math.Clamp(ev.Amount.Value, 0, Math.Pow(10, maxDigitCount) - 1);
|
||||
|
||||
// This is super wack but ig it works?
|
||||
var digitCount = ent.Comp.HideLeadingZeroes
|
||||
? amount.ToString().Length
|
||||
: maxDigitCount;
|
||||
|
||||
if (ent.Comp.HideLeadingZeroes)
|
||||
{
|
||||
for (var i = 0; i < ent.Comp.DigitKeys.Count; i++)
|
||||
{
|
||||
if (!_sprite.LayerMapTryGet(ent.Owner, ent.Comp.DigitKeys[i], out var layer, false))
|
||||
continue;
|
||||
|
||||
_sprite.LayerSetVisible(ent.Owner, layer, i <= digitCount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once PossibleLossOfFraction
|
||||
var baseOffset = (ent.Comp.AlertSize.X - digitCount * ent.Comp.GlyphWidth) / 2 * (1f / EyeManager.PixelsPerMeter);
|
||||
|
||||
for (var i = 0; i < ent.Comp.DigitKeys.Count; i++)
|
||||
{
|
||||
if (!_sprite.LayerMapTryGet(ent.Owner, ent.Comp.DigitKeys[i], out var layer, false))
|
||||
continue;
|
||||
|
||||
var result = amount / (int) Math.Pow(10, i) % 10;
|
||||
_sprite.LayerSetRsiState(ent.Owner, layer, result.ToString());
|
||||
|
||||
if (ent.Comp.CenterGlyph)
|
||||
{
|
||||
var offset = baseOffset + (digitCount - 1 - i) * ent.Comp.GlyphWidth * (1f / EyeManager.PixelsPerMeter);
|
||||
_sprite.LayerSetOffset(ent.Owner, layer, new Vector2(offset, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of digits that we can display.
|
||||
/// </summary>
|
||||
/// <returns>The number of digits.</returns>
|
||||
private int GetMaxDigitCount(Entity<GenericCounterAlertComponent, SpriteComponent> ent)
|
||||
{
|
||||
for (var i = ent.Comp1.DigitKeys.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (_sprite.LayerExists((ent.Owner, ent.Comp2), ent.Comp1.DigitKeys[i]))
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,11 @@ public record struct UpdateAlertSpriteEvent
|
||||
{
|
||||
public Entity<SpriteComponent> SpriteViewEnt;
|
||||
|
||||
public EntityUid ViewerEnt;
|
||||
|
||||
public AlertPrototype Alert;
|
||||
|
||||
public UpdateAlertSpriteEvent(Entity<SpriteComponent> spriteViewEnt, EntityUid viewerEnt, AlertPrototype alert)
|
||||
public UpdateAlertSpriteEvent(Entity<SpriteComponent> spriteViewEnt, AlertPrototype alert)
|
||||
{
|
||||
SpriteViewEnt = spriteViewEnt;
|
||||
ViewerEnt = viewerEnt;
|
||||
Alert = alert;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using Content.Shared.Atmos.EntitySystems;
|
||||
using Content.Shared.Atmos.Piping.Binary.Components;
|
||||
|
||||
namespace Content.Client.Atmos.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the client system responsible for managing and updating the gas pressure regulator interface.
|
||||
/// Inherits from the shared system <see cref="SharedGasPressureRegulatorSystem"/>.
|
||||
/// </summary>
|
||||
public sealed partial class GasPressureRegulatorSystem : SharedGasPressureRegulatorSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GasPressureRegulatorComponent, AfterAutoHandleStateEvent>(OnValveUpdate);
|
||||
}
|
||||
|
||||
private void OnValveUpdate(Entity<GasPressureRegulatorComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateUi(ent);
|
||||
}
|
||||
|
||||
protected override void UpdateUi(Entity<GasPressureRegulatorComponent> ent)
|
||||
{
|
||||
if (UserInterfaceSystem.TryGetOpenUi(ent.Owner, GasPressureRegulatorUiKey.Key, out var bui))
|
||||
{
|
||||
bui.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
using Content.Shared.Atmos.Piping.Binary.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Localizations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.Atmos.UI;
|
||||
|
||||
public sealed class GasPressureRegulatorBoundUserInterface(EntityUid owner, Enum uiKey)
|
||||
: BoundUserInterface(owner, uiKey)
|
||||
{
|
||||
private GasPressureRegulatorWindow? _window;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<GasPressureRegulatorWindow>();
|
||||
|
||||
_window.SetEntity(Owner);
|
||||
|
||||
_window.ThresholdPressureChanged += OnThresholdChanged;
|
||||
|
||||
if (EntMan.TryGetComponent(Owner, out GasPressureRegulatorComponent? comp))
|
||||
_window.SetThresholdPressureInput(comp.Threshold);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_window.Title = Identity.Name(Owner, EntMan);
|
||||
|
||||
if (!EntMan.TryGetComponent(Owner, out GasPressureRegulatorComponent? comp))
|
||||
return;
|
||||
|
||||
_window.SetThresholdPressureLabel(comp.Threshold);
|
||||
_window.UpdateInfo(comp.InletPressure, comp.OutletPressure, comp.FlowRate);
|
||||
}
|
||||
|
||||
private void OnThresholdChanged(string newThreshold)
|
||||
{
|
||||
var sentThreshold = 0f;
|
||||
|
||||
if (UserInputParser.TryFloat(newThreshold, out var parsedNewThreshold) && parsedNewThreshold >= 0 &&
|
||||
!float.IsInfinity(parsedNewThreshold))
|
||||
{
|
||||
sentThreshold = parsedNewThreshold;
|
||||
}
|
||||
|
||||
// Autofill to zero if the user inputs an invalid value.
|
||||
_window?.SetThresholdPressureInput(sentThreshold);
|
||||
|
||||
SendPredictedMessage(new GasPressureRegulatorChangeThresholdMessage(sentThreshold));
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
SetSize="345 380"
|
||||
MinSize="345 380"
|
||||
Title="{Loc gas-pressure-regulator-ui-title}"
|
||||
Resizable="False">
|
||||
|
||||
<BoxContainer Orientation="Vertical">
|
||||
|
||||
<BoxContainer Orientation="Vertical" Margin="0 10 0 10">
|
||||
|
||||
<BoxContainer Orientation="Vertical" Align="Center">
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-outlet}" Align="Center" StyleClasses="LabelKeyText" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Label Name="OutletPressureLabel" Text="N/A" Margin="0 0 4 0" />
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-pressure-unit}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<BoxContainer Orientation="Horizontal" Align="Center">
|
||||
<BoxContainer Orientation="Vertical" Align="Center" HorizontalExpand="True">
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-target}" Align="Right" StyleClasses="LabelKeyText" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Label Name="TargetPressureLabel" Margin="0 0 4 0" />
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-pressure-unit}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<ProgressBar Name="ToTargetBar" MaxValue="1" SetSize="5 75" Margin="10" Vertical="True" />
|
||||
|
||||
<SpriteView Name="EntityView" SetSize="64 64" Scale="3 3" OverrideDirection="North" Margin="0" />
|
||||
|
||||
<ProgressBar Name="FlowRateBar" MaxValue="1" SetSize="5 75" Margin="10" Vertical="True" />
|
||||
|
||||
<BoxContainer Orientation="Vertical" Align="Center" HorizontalExpand="True">
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-flow}" StyleClasses="LabelKeyText" />
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Label Name="CurrentFlowLabel" Text="N/A" Margin="0 0 4 0" />
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-flow-rate-unit}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<BoxContainer Orientation="Vertical" Align="Center" Margin="1">
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-inlet}" Align="Center" StyleClasses="LabelKeyText" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Label Name="InletPressureLabel" Text="N/A" Margin="0 0 4 0" />
|
||||
<Label Text="{Loc gas-pressure-regulator-ui-pressure-unit}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
</BoxContainer>
|
||||
|
||||
<!-- Controls to Set Pressure -->
|
||||
<controls:StripeBack Name="SetPressureStripeBack" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="10 10 10 10">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<LineEdit Name="ThresholdInput" HorizontalExpand="True" MinSize="70 0" />
|
||||
<Button Name="SetThresholdButton" Text="{Loc gas-pressure-regulator-ui-set-threshold}"
|
||||
Disabled="True" Margin="5 0 0 0" />
|
||||
</BoxContainer>
|
||||
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 5 0 0">
|
||||
<Button Name="Subtract1000Button" Text="{Loc gas-pressure-regulator-ui-subtract-1000}"
|
||||
HorizontalExpand="True" Margin="0 2 2 0"
|
||||
StyleClasses="OpenBoth" />
|
||||
<Button Name="Subtract100Button" Text="{Loc gas-pressure-regulator-ui-subtract-100}"
|
||||
HorizontalExpand="True" Margin="0 2 2 0"
|
||||
StyleClasses="OpenBoth" />
|
||||
<Button Name="Subtract10Button" Text="{Loc gas-pressure-regulator-ui-subtract-10}"
|
||||
HorizontalExpand="True" Margin="0 2 2 0"
|
||||
StyleClasses="OpenBoth" />
|
||||
<Button Name="Add10Button" Text="{Loc gas-pressure-regulator-ui-add-10}" HorizontalExpand="True"
|
||||
Margin="0 2 2 0"
|
||||
StyleClasses="OpenBoth" />
|
||||
<Button Name="Add100Button" Text="{Loc gas-pressure-regulator-ui-add-100}"
|
||||
HorizontalExpand="True" Margin="0 2 2 0"
|
||||
StyleClasses="OpenBoth" />
|
||||
<Button Name="Add1000Button" Text="{Loc gas-pressure-regulator-ui-add-1000}"
|
||||
HorizontalExpand="True" Margin="0 2 2 0"
|
||||
StyleClasses="OpenBoth" />
|
||||
</BoxContainer>
|
||||
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 5 0 0">
|
||||
<Button Name="ZeroThresholdButton" Text="{Loc gas-pressure-regulator-ui-zero-threshold}"
|
||||
HorizontalExpand="True" Margin="0 0 5 0" />
|
||||
<Button Name="SetToCurrentPressureButton"
|
||||
Text="{Loc gas-pressure-regulator-ui-set-to-current-pressure}" HorizontalExpand="True" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:StripeBack>
|
||||
|
||||
</BoxContainer>
|
||||
|
||||
</controls:FancyWindow>
|
||||
@@ -1,129 +0,0 @@
|
||||
using System.Globalization;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Atmos.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Client-side UI for controlling a pressure regulator.
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class GasPressureRegulatorWindow : FancyWindow
|
||||
{
|
||||
private float _flowRate;
|
||||
|
||||
public GasPressureRegulatorWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
ThresholdInput.OnTextChanged += _ => SetThresholdButton.Disabled = false;
|
||||
SetThresholdButton.OnPressed += _ =>
|
||||
{
|
||||
ThresholdPressureChanged?.Invoke(ThresholdInput.Text ??= "");
|
||||
SetThresholdButton.Disabled = true;
|
||||
};
|
||||
|
||||
SetToCurrentPressureButton.OnPressed += _ =>
|
||||
{
|
||||
if (InletPressureLabel.Text != null)
|
||||
{
|
||||
ThresholdInput.Text = InletPressureLabel.Text;
|
||||
}
|
||||
|
||||
SetThresholdButton.Disabled = false;
|
||||
};
|
||||
|
||||
ZeroThresholdButton.OnPressed += _ =>
|
||||
{
|
||||
ThresholdInput.Text = "0";
|
||||
SetThresholdButton.Disabled = false;
|
||||
};
|
||||
|
||||
Add1000Button.OnPressed += _ => AdjustThreshold(1000);
|
||||
Add100Button.OnPressed += _ => AdjustThreshold(100);
|
||||
Add10Button.OnPressed += _ => AdjustThreshold(10);
|
||||
Subtract10Button.OnPressed += _ => AdjustThreshold(-10);
|
||||
Subtract100Button.OnPressed += _ => AdjustThreshold(-100);
|
||||
Subtract1000Button.OnPressed += _ => AdjustThreshold(-1000);
|
||||
return;
|
||||
|
||||
void AdjustThreshold(float adjustment)
|
||||
{
|
||||
if (float.TryParse(ThresholdInput.Text, out var currentValue))
|
||||
{
|
||||
ThresholdInput.Text = (currentValue + adjustment).ToString(CultureInfo.CurrentCulture);
|
||||
SetThresholdButton.Disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<string>? ThresholdPressureChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current threshold pressure label. This is not setting the threshold input box.
|
||||
/// </summary>
|
||||
/// <param name="threshold"> Threshold to set.</param>
|
||||
public void SetThresholdPressureLabel(float threshold)
|
||||
{
|
||||
TargetPressureLabel.Text = threshold.ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the threshold pressure input field with the given value.
|
||||
/// When the client opens the UI the field will be autofilled with the current threshold pressure.
|
||||
/// </summary>
|
||||
/// <param name="input">The threshold pressure value to autofill into the input field.</param>
|
||||
public void SetThresholdPressureInput(float input)
|
||||
{
|
||||
ThresholdInput.Text = input.ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the entity to be visible in the UI.
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public void SetEntity(EntityUid entity)
|
||||
{
|
||||
EntityView.SetEntity(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the UI for the labels.
|
||||
/// </summary>
|
||||
/// <param name="inletPressure">The current pressure at the valve's inlet.</param>
|
||||
/// <param name="outletPressure">The current pressure at the valve's outlet.</param>
|
||||
/// <param name="flowRate">The current flow rate through the valve.</param>
|
||||
public void UpdateInfo(float inletPressure, float outletPressure, float flowRate)
|
||||
{
|
||||
if (float.TryParse(TargetPressureLabel.Text, out var parsedfloat))
|
||||
ToTargetBar.Value = inletPressure / parsedfloat;
|
||||
|
||||
InletPressureLabel.Text = float.Round(inletPressure).ToString(CultureInfo.CurrentCulture);
|
||||
OutletPressureLabel.Text = float.Round(outletPressure).ToString(CultureInfo.CurrentCulture);
|
||||
CurrentFlowLabel.Text = float.IsNaN(flowRate) ? "0" : flowRate.ToString(CultureInfo.CurrentCulture);
|
||||
_flowRate = flowRate;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
// Defines the flow rate at which the progress bar fills in one second.
|
||||
// If the flow rate is >50 L/s, the bar will take <1 second to fill.
|
||||
// If the flow rate is <50 L/s, the bar will take >1 second to fill.
|
||||
const int barFillPerSecond = 50;
|
||||
|
||||
var maxValue = FlowRateBar.MaxValue;
|
||||
|
||||
// Increment the progress bar value based on elapsed time
|
||||
FlowRateBar.Value += (_flowRate / barFillPerSecond) * args.DeltaSeconds;
|
||||
|
||||
// Reset the progress bar when it is fully filled
|
||||
if (FlowRateBar.Value >= maxValue)
|
||||
{
|
||||
FlowRateBar.Value = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
|
||||
_targetTime = _gameTiming.CurTime + TimeSpan.FromSeconds(_cooldown);
|
||||
|
||||
var player = _playerManager.LocalEntity;
|
||||
if (!TryComp(player, out TransformComponent? xform))
|
||||
if (!EntityManager.TryGetComponent(player, out TransformComponent? xform))
|
||||
{
|
||||
ClearSounds();
|
||||
return;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
using Content.Shared.Body.Systems;
|
||||
|
||||
namespace Content.Client.Body.Systems;
|
||||
|
||||
public sealed class BloodstreamSystem : SharedBloodstreamSystem;
|
||||
@@ -5,27 +5,32 @@ using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Client.Commands;
|
||||
|
||||
public sealed class HideMechanismsCommand : LocalizedEntityCommands
|
||||
public sealed class HideMechanismsCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _spriteSystem = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
public override string Command => "hidemechanisms";
|
||||
|
||||
public override string Description => LocalizationManager.GetString($"cmd-{Command}-desc", ("showMechanismsCommand", ShowMechanismsCommand.CommandName));
|
||||
|
||||
public override string Help => LocalizationManager.GetString($"cmd-{Command}-help", ("command", Command));
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var query = EntityManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
var containerSys = _entityManager.System<SharedContainerSystem>();
|
||||
var spriteSys = _entityManager.System<SpriteSystem>();
|
||||
var query = _entityManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
_spriteSystem.SetContainerOccluded((uid, sprite), false);
|
||||
spriteSys.SetContainerOccluded((uid, sprite), false);
|
||||
|
||||
var tempParent = uid;
|
||||
while (_containerSystem.TryGetContainingContainer((tempParent, null, null), out var container))
|
||||
while (containerSys.TryGetContainingContainer((tempParent, null, null), out var container))
|
||||
{
|
||||
if (!container.ShowContents)
|
||||
{
|
||||
_spriteSystem.SetContainerOccluded((uid, sprite), true);
|
||||
spriteSys.SetContainerOccluded((uid, sprite), true);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +1,57 @@
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.Overlays;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Prototypes;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Client.Commands;
|
||||
|
||||
public sealed class ShowHealthBarsCommand : LocalizedEntityCommands
|
||||
public sealed class ShowHealthBarsCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
public override string Command => "showhealthbars";
|
||||
|
||||
public override string Help => LocalizationManager.GetString($"cmd-{Command}-help", ("command", Command));
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var player = shell.Player;
|
||||
var player = _playerManager.LocalSession;
|
||||
if (player == null)
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command"));
|
||||
shell.WriteError(LocalizationManager.GetString($"cmd-{Command}-error-not-player"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.AttachedEntity is not { } playerEntity)
|
||||
var playerEntity = player?.AttachedEntity;
|
||||
if (!playerEntity.HasValue)
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-must-be-attached-to-entity"));
|
||||
shell.WriteError(LocalizationManager.GetString($"cmd-{Command}-error-no-entity"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EntityManager.HasComponent<ShowHealthBarsComponent>(playerEntity))
|
||||
if (!_entityManager.HasComponent<ShowHealthBarsComponent>(playerEntity))
|
||||
{
|
||||
var showHealthBarsComponent = new ShowHealthBarsComponent
|
||||
{
|
||||
DamageContainers = args.Select(arg => new ProtoId<DamageContainerPrototype>(arg)).ToList(),
|
||||
HealthStatusIcon = null,
|
||||
NetSyncEnabled = false,
|
||||
NetSyncEnabled = false
|
||||
};
|
||||
|
||||
EntityManager.AddComponent(playerEntity, showHealthBarsComponent, true);
|
||||
_entityManager.AddComponent(playerEntity.Value, showHealthBarsComponent, true);
|
||||
|
||||
shell.WriteLine(Loc.GetString("cmd-showhealthbars-notify-enabled", ("args", string.Join(", ", args))));
|
||||
shell.WriteLine(LocalizationManager.GetString($"cmd-{Command}-notify-enabled", ("args", string.Join(", ", args))));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_entityManager.RemoveComponentDeferred<ShowHealthBarsComponent>(playerEntity.Value);
|
||||
shell.WriteLine(LocalizationManager.GetString($"cmd-{Command}-notify-disabled"));
|
||||
}
|
||||
|
||||
EntityManager.RemoveComponentDeferred<ShowHealthBarsComponent>(playerEntity);
|
||||
shell.WriteLine(Loc.GetString("cmd-showhealthbars-notify-disabled"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,19 +4,24 @@ using Robust.Shared.Console;
|
||||
|
||||
namespace Content.Client.Commands;
|
||||
|
||||
public sealed class ShowMechanismsCommand : LocalizedEntityCommands
|
||||
public sealed class ShowMechanismsCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _spriteSystem = default!;
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
public override string Command => "showmechanisms";
|
||||
public const string CommandName = "showmechanisms";
|
||||
|
||||
public override string Command => CommandName;
|
||||
|
||||
public override string Help => LocalizationManager.GetString($"cmd-{Command}-help", ("command", Command));
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var query = EntityManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
var spriteSys = _entManager.System<SpriteSystem>();
|
||||
var query = _entManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
_spriteSystem.SetContainerOccluded((uid, sprite), false);
|
||||
spriteSys.SetContainerOccluded((uid, sprite), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,14 +286,14 @@ namespace Content.Client.Construction
|
||||
if (!CheckConstructionConditions(prototype, loc, dir, user, showPopup: true))
|
||||
return false;
|
||||
|
||||
ghost = Spawn("constructionghost", loc);
|
||||
var comp = Comp<ConstructionGhostComponent>(ghost.Value);
|
||||
ghost = EntityManager.SpawnEntity("constructionghost", loc);
|
||||
var comp = EntityManager.GetComponent<ConstructionGhostComponent>(ghost.Value);
|
||||
comp.Prototype = prototype;
|
||||
comp.GhostId = ghost.GetHashCode();
|
||||
Comp<TransformComponent>(ghost.Value).LocalRotation = dir.ToAngle();
|
||||
EntityManager.GetComponent<TransformComponent>(ghost.Value).LocalRotation = dir.ToAngle();
|
||||
_ghosts.Add(comp.GhostId, ghost.Value);
|
||||
|
||||
var sprite = Comp<SpriteComponent>(ghost.Value);
|
||||
var sprite = EntityManager.GetComponent<SpriteComponent>(ghost.Value);
|
||||
_sprite.SetColor((ghost.Value, sprite), new Color(48, 255, 48, 128));
|
||||
|
||||
if (targetProto.TryGetComponent(out IconComponent? icon, EntityManager.ComponentFactory))
|
||||
@@ -306,7 +306,7 @@ namespace Content.Client.Construction
|
||||
else if (targetProto.Components.TryGetValue("Sprite", out _))
|
||||
{
|
||||
var dummy = EntityManager.SpawnEntity(targetProtoId, MapCoordinates.Nullspace);
|
||||
var targetSprite = EnsureComp<SpriteComponent>(dummy);
|
||||
var targetSprite = EntityManager.EnsureComponent<SpriteComponent>(dummy);
|
||||
EntityManager.System<AppearanceSystem>().OnChangeData(dummy, targetSprite);
|
||||
|
||||
for (var i = 0; i < targetSprite.AllLayers.Count(); i++)
|
||||
@@ -325,7 +325,7 @@ namespace Content.Client.Construction
|
||||
_sprite.LayerSetVisible((ghost.Value, sprite), i, true);
|
||||
}
|
||||
|
||||
Del(dummy);
|
||||
EntityManager.DeleteEntity(dummy);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
@@ -367,7 +367,7 @@ namespace Content.Client.Construction
|
||||
{
|
||||
foreach (var ghost in _ghosts)
|
||||
{
|
||||
if (Comp<TransformComponent>(ghost.Value).Coordinates.Equals(loc))
|
||||
if (EntityManager.GetComponent<TransformComponent>(ghost.Value).Coordinates.Equals(loc))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ namespace Content.Client.Construction
|
||||
throw new ArgumentException($"Can't start construction for a ghost with no prototype. Ghost id: {ghostId}");
|
||||
}
|
||||
|
||||
var transform = Comp<TransformComponent>(ghostId);
|
||||
var transform = EntityManager.GetComponent<TransformComponent>(ghostId);
|
||||
var msg = new TryStartStructureConstructionMessage(GetNetCoordinates(transform.Coordinates), ghostComp.Prototype.ID, transform.LocalRotation, ghostId.GetHashCode());
|
||||
RaiseNetworkEvent(msg);
|
||||
}
|
||||
@@ -405,7 +405,7 @@ namespace Content.Client.Construction
|
||||
if (!_ghosts.TryGetValue(ghostId, out var ghost))
|
||||
return;
|
||||
|
||||
QueueDel(ghost);
|
||||
EntityManager.QueueDeleteEntity(ghost);
|
||||
_ghosts.Remove(ghostId);
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ namespace Content.Client.Construction
|
||||
{
|
||||
foreach (var ghost in _ghosts.Values)
|
||||
{
|
||||
QueueDel(ghost);
|
||||
EntityManager.QueueDeleteEntity(ghost);
|
||||
}
|
||||
|
||||
_ghosts.Clear();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<OutputPath>..\bin\Content.Client\</OutputPath>
|
||||
<OutputType Condition="'$(FullRelease)' != 'True'">Exe</OutputType>
|
||||
<WarningsAsErrors>RA0032;nullable</WarningsAsErrors>
|
||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<Configurations>Debug;Release;Tools;DebugOpt</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Shared.Drowsiness;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Enums;
|
||||
@@ -15,7 +15,6 @@ public sealed class DrowsinessOverlay : Overlay
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
private readonly SharedStatusEffectsSystem _statusEffects = default!;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
public override bool RequestScreenTexture => true;
|
||||
@@ -30,9 +29,6 @@ public sealed class DrowsinessOverlay : Overlay
|
||||
public DrowsinessOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_statusEffects = _sysMan.GetEntitySystem<SharedStatusEffectsSystem>();
|
||||
|
||||
_drowsinessShader = _prototypeManager.Index<ShaderPrototype>("Drowsiness").InstanceUnique();
|
||||
}
|
||||
|
||||
@@ -43,11 +39,17 @@ public sealed class DrowsinessOverlay : Overlay
|
||||
if (playerEntity == null)
|
||||
return;
|
||||
|
||||
if (!_statusEffects.TryGetEffectsEndTimeWithComp<DrowsinessStatusEffectComponent>(playerEntity, out var endTime))
|
||||
if (!_entityManager.HasComponent<DrowsinessComponent>(playerEntity)
|
||||
|| !_entityManager.TryGetComponent<StatusEffectsComponent>(playerEntity, out var status))
|
||||
return;
|
||||
|
||||
endTime ??= TimeSpan.MaxValue;
|
||||
var timeLeft = (float)(endTime - _timing.CurTime).Value.TotalSeconds;
|
||||
var statusSys = _sysMan.GetEntitySystem<StatusEffectsSystem>();
|
||||
if (!statusSys.TryGetTime(playerEntity.Value, SharedDrowsinessSystem.DrowsinessKey, out var time, status))
|
||||
return;
|
||||
|
||||
var curTime = _timing.CurTime;
|
||||
var timeLeft = (float)(time.Value.Item2 - curTime).TotalSeconds;
|
||||
|
||||
CurrentPower += 8f * (0.5f * timeLeft - CurrentPower) * args.DeltaSeconds / (timeLeft + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Drowsiness;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
@@ -10,7 +9,6 @@ public sealed class DrowsinessSystem : SharedDrowsinessSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
[Dependency] private readonly SharedStatusEffectsSystem _statusEffects = default!;
|
||||
|
||||
private DrowsinessOverlay _overlay = default!;
|
||||
|
||||
@@ -18,44 +16,35 @@ public sealed class DrowsinessSystem : SharedDrowsinessSystem
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DrowsinessStatusEffectComponent, StatusEffectAppliedEvent>(OnDrowsinessApply);
|
||||
SubscribeLocalEvent<DrowsinessStatusEffectComponent, StatusEffectRemovedEvent>(OnDrowsinessShutdown);
|
||||
SubscribeLocalEvent<DrowsinessComponent, ComponentInit>(OnDrowsinessInit);
|
||||
SubscribeLocalEvent<DrowsinessComponent, ComponentShutdown>(OnDrowsinessShutdown);
|
||||
|
||||
SubscribeLocalEvent<DrowsinessStatusEffectComponent, StatusEffectRelayedEvent<LocalPlayerAttachedEvent>>(OnStatusEffectPlayerAttached);
|
||||
SubscribeLocalEvent<DrowsinessStatusEffectComponent, StatusEffectRelayedEvent<LocalPlayerDetachedEvent>>(OnStatusEffectPlayerDetached);
|
||||
SubscribeLocalEvent<DrowsinessComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<DrowsinessComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
|
||||
|
||||
_overlay = new();
|
||||
}
|
||||
|
||||
private void OnDrowsinessApply(Entity<DrowsinessStatusEffectComponent> ent, ref StatusEffectAppliedEvent args)
|
||||
{
|
||||
if (_player.LocalEntity == args.Target)
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnDrowsinessShutdown(Entity<DrowsinessStatusEffectComponent> ent, ref StatusEffectRemovedEvent args)
|
||||
{
|
||||
if (_player.LocalEntity != args.Target)
|
||||
return;
|
||||
|
||||
if (!_statusEffects.HasEffectComp<DrowsinessStatusEffectComponent>(_player.LocalEntity.Value))
|
||||
{
|
||||
_overlay.CurrentPower = 0;
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStatusEffectPlayerAttached(Entity<DrowsinessStatusEffectComponent> ent, ref StatusEffectRelayedEvent<LocalPlayerAttachedEvent> args)
|
||||
private void OnPlayerAttached(EntityUid uid, DrowsinessComponent component, LocalPlayerAttachedEvent args)
|
||||
{
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnStatusEffectPlayerDetached(Entity<DrowsinessStatusEffectComponent> ent, ref StatusEffectRelayedEvent<LocalPlayerDetachedEvent> args)
|
||||
private void OnPlayerDetached(EntityUid uid, DrowsinessComponent component, LocalPlayerDetachedEvent args)
|
||||
{
|
||||
if (_player.LocalEntity is null)
|
||||
return;
|
||||
_overlay.CurrentPower = 0;
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
|
||||
if (!_statusEffects.HasEffectComp<DrowsinessStatusEffectComponent>(_player.LocalEntity.Value))
|
||||
private void OnDrowsinessInit(EntityUid uid, DrowsinessComponent component, ComponentInit args)
|
||||
{
|
||||
if (_player.LocalEntity == uid)
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnDrowsinessShutdown(EntityUid uid, DrowsinessComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (_player.LocalEntity == uid)
|
||||
{
|
||||
_overlay.CurrentPower = 0;
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Drugs;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
@@ -18,47 +17,49 @@ public sealed class DrugOverlaySystem : EntitySystem
|
||||
|
||||
private RainbowOverlay _overlay = default!;
|
||||
|
||||
public static string RainbowKey = "SeeingRainbows";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SeeingRainbowsStatusEffectComponent, StatusEffectAppliedEvent>(OnApplied);
|
||||
SubscribeLocalEvent<SeeingRainbowsStatusEffectComponent, StatusEffectRemovedEvent>(OnRemoved);
|
||||
SubscribeLocalEvent<SeeingRainbowsComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<SeeingRainbowsComponent, ComponentShutdown>(OnShutdown);
|
||||
|
||||
SubscribeLocalEvent<SeeingRainbowsStatusEffectComponent, StatusEffectRelayedEvent<LocalPlayerAttachedEvent>>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<SeeingRainbowsStatusEffectComponent, StatusEffectRelayedEvent<LocalPlayerDetachedEvent>>(OnPlayerDetached);
|
||||
SubscribeLocalEvent<SeeingRainbowsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<SeeingRainbowsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
|
||||
|
||||
_overlay = new();
|
||||
}
|
||||
|
||||
private void OnRemoved(Entity<SeeingRainbowsStatusEffectComponent> ent, ref StatusEffectRemovedEvent args)
|
||||
private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerAttachedEvent args)
|
||||
{
|
||||
if (_player.LocalEntity != args.Target)
|
||||
return;
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerDetachedEvent args)
|
||||
{
|
||||
_overlay.Intoxication = 0;
|
||||
_overlay.TimeTicker = 0;
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnApplied(Entity<SeeingRainbowsStatusEffectComponent> ent, ref StatusEffectAppliedEvent args)
|
||||
private void OnInit(EntityUid uid, SeeingRainbowsComponent component, ComponentInit args)
|
||||
{
|
||||
if (_player.LocalEntity != args.Target)
|
||||
return;
|
||||
|
||||
_overlay.Phase = _random.NextFloat(MathF.Tau); // random starting phase for movement effect
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
if (_player.LocalEntity == uid)
|
||||
{
|
||||
_overlay.Phase = _random.NextFloat(MathF.Tau); // random starting phase for movement effect
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerAttached(Entity<SeeingRainbowsStatusEffectComponent> ent, ref StatusEffectRelayedEvent<LocalPlayerAttachedEvent> args)
|
||||
private void OnShutdown(EntityUid uid, SeeingRainbowsComponent component, ComponentShutdown args)
|
||||
{
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnPlayerDetached(Entity<SeeingRainbowsStatusEffectComponent> ent, ref StatusEffectRelayedEvent<LocalPlayerDetachedEvent> args)
|
||||
{
|
||||
_overlay.Intoxication = 0;
|
||||
_overlay.TimeTicker = 0;
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
if (_player.LocalEntity == uid)
|
||||
{
|
||||
_overlay.Intoxication = 0;
|
||||
_overlay.TimeTicker = 0;
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Drugs;
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
@@ -17,8 +17,6 @@ public sealed class RainbowOverlay : Overlay
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
private readonly SharedStatusEffectsSystem _statusEffects = default!;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
public override bool RequestScreenTexture => true;
|
||||
@@ -39,8 +37,6 @@ public sealed class RainbowOverlay : Overlay
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_statusEffects = _sysMan.GetEntitySystem<SharedStatusEffectsSystem>();
|
||||
|
||||
_rainbowShader = _prototypeManager.Index<ShaderPrototype>("Rainbow").InstanceUnique();
|
||||
_config.OnValueChanged(CCVars.ReducedMotion, OnReducedMotionChanged, invokeImmediately: true);
|
||||
}
|
||||
@@ -58,13 +54,18 @@ public sealed class RainbowOverlay : Overlay
|
||||
if (playerEntity == null)
|
||||
return;
|
||||
|
||||
if (!_statusEffects.TryGetEffectsEndTimeWithComp<SeeingRainbowsStatusEffectComponent>(playerEntity, out var endTime))
|
||||
if (!_entityManager.HasComponent<SeeingRainbowsComponent>(playerEntity)
|
||||
|| !_entityManager.TryGetComponent<StatusEffectsComponent>(playerEntity, out var status))
|
||||
return;
|
||||
|
||||
endTime ??= TimeSpan.MaxValue;
|
||||
var timeLeft = (float)(endTime - _timing.CurTime).Value.TotalSeconds;
|
||||
var statusSys = _sysMan.GetEntitySystem<StatusEffectsSystem>();
|
||||
if (!statusSys.TryGetTime(playerEntity.Value, DrugOverlaySystem.RainbowKey, out var time, status))
|
||||
return;
|
||||
|
||||
var timeLeft = (float)(time.Value.Item2 - time.Value.Item1).TotalSeconds;
|
||||
|
||||
TimeTicker += args.DeltaSeconds;
|
||||
|
||||
if (timeLeft - TimeTicker > timeLeft / 16f)
|
||||
{
|
||||
Intoxication += (timeLeft - Intoxication) * args.DeltaSeconds / 16f;
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace Content.Client.Examine
|
||||
{
|
||||
var entity = args.EntityUid;
|
||||
|
||||
if (!args.EntityUid.IsValid() || !Exists(entity))
|
||||
if (!args.EntityUid.IsValid() || !EntityManager.EntityExists(entity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -225,7 +225,7 @@ namespace Content.Client.Examine
|
||||
|
||||
vBox.AddChild(hBox);
|
||||
|
||||
if (HasComp<SpriteComponent>(target))
|
||||
if (EntityManager.HasComponent<SpriteComponent>(target))
|
||||
{
|
||||
var spriteView = new SpriteView
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ public sealed partial class TriggerSystem
|
||||
|
||||
private void OnProximityInit(EntityUid uid, TriggerOnProximityComponent component, ComponentInit args)
|
||||
{
|
||||
EnsureComp<AnimationPlayerComponent>(uid);
|
||||
EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
|
||||
}
|
||||
|
||||
private void OnProxAppChange(EntityUid uid, TriggerOnProximityComponent component, ref AppearanceChangeEvent args)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Flash;
|
||||
using Content.Shared.Flash.Components;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
@@ -6,7 +6,7 @@ using Robust.Shared.Utility;
|
||||
namespace Content.Client.Guidebook.Richtext;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class KeyBindTag : IMarkupTagHandler
|
||||
public sealed class KeyBindTag : IMarkupTag
|
||||
{
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Content.Client.Guidebook.RichText;
|
||||
/// In order to be accessed by this tag, the desired field/property must
|
||||
/// be tagged with <see cref="Shared.Guidebook.GuidebookDataAttribute"/>.
|
||||
/// </summary>
|
||||
public sealed class ProtodataTag : IMarkupTagHandler
|
||||
public sealed class ProtodataTag : IMarkupTag
|
||||
{
|
||||
[Dependency] private readonly ILogManager _logMan = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
|
||||
@@ -10,14 +10,16 @@ using Content.Client.UserInterface.ControlExtensions;
|
||||
namespace Content.Client.Guidebook.RichText;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class TextLinkTag : IMarkupTagHandler
|
||||
public sealed class TextLinkTag : IMarkupTag
|
||||
{
|
||||
public static Color LinkColor => Color.CornflowerBlue;
|
||||
|
||||
public string Name => "textlink";
|
||||
|
||||
public Control? Control;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool TryCreateControl(MarkupNode node, [NotNullWhen(true)] out Control? control)
|
||||
public bool TryGetControl(MarkupNode node, [NotNullWhen(true)] out Control? control)
|
||||
{
|
||||
if (!node.Value.TryGetString(out var text)
|
||||
|| !node.Attributes.TryGetValue("link", out var linkParameter)
|
||||
@@ -36,21 +38,22 @@ public sealed class TextLinkTag : IMarkupTagHandler
|
||||
|
||||
label.OnMouseEntered += _ => label.FontColorOverride = Color.LightSkyBlue;
|
||||
label.OnMouseExited += _ => label.FontColorOverride = Color.CornflowerBlue;
|
||||
label.OnKeyBindDown += args => OnKeybindDown(args, link, label);
|
||||
label.OnKeyBindDown += args => OnKeybindDown(args, link);
|
||||
|
||||
control = label;
|
||||
Control = label;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnKeybindDown(GUIBoundKeyEventArgs args, string link, Control? control)
|
||||
private void OnKeybindDown(GUIBoundKeyEventArgs args, string link)
|
||||
{
|
||||
if (args.Function != EngineKeyFunctions.UIClick)
|
||||
return;
|
||||
|
||||
if (control == null)
|
||||
if (Control == null)
|
||||
return;
|
||||
|
||||
if (control.TryGetParentHandler<ILinkClickHandler>(out var handler))
|
||||
if (Control.TryGetParentHandler<ILinkClickHandler>(out var handler))
|
||||
handler.HandleClick(link);
|
||||
else
|
||||
Logger.Warning("Warning! No valid ILinkClickHandler found.");
|
||||
|
||||
@@ -16,6 +16,7 @@ using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Hands.Systems
|
||||
@@ -26,13 +27,16 @@ namespace Content.Client.Hands.Systems
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _ui = default!;
|
||||
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly StrippableSystem _stripSys = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly ExamineSystem _examine = default!;
|
||||
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
|
||||
|
||||
public event Action<string, HandLocation>? OnPlayerAddHand;
|
||||
public event Action<string>? OnPlayerRemoveHand;
|
||||
public event Action<string?>? OnPlayerSetActiveHand;
|
||||
public event Action<Entity<HandsComponent>>? OnPlayerHandsAdded;
|
||||
public event Action<HandsComponent>? OnPlayerHandsAdded;
|
||||
public event Action? OnPlayerHandsRemoved;
|
||||
public event Action<string, EntityUid>? OnPlayerItemAdded;
|
||||
public event Action<string, EntityUid>? OnPlayerItemRemoved;
|
||||
@@ -54,28 +58,67 @@ namespace Content.Client.Hands.Systems
|
||||
}
|
||||
|
||||
#region StateHandling
|
||||
private void HandleComponentState(Entity<HandsComponent> ent, ref ComponentHandleState args)
|
||||
private void HandleComponentState(EntityUid uid, HandsComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not HandsComponentState state)
|
||||
return;
|
||||
|
||||
var newHands = state.Hands.Keys.Except(ent.Comp.Hands.Keys); // hands that were added between states
|
||||
var oldHands = ent.Comp.Hands.Keys.Except(state.Hands.Keys); // hands that were removed between states
|
||||
|
||||
foreach (var handId in oldHands)
|
||||
var handsModified = component.Hands.Count != state.Hands.Count;
|
||||
// we need to check that, even if we have the same amount, that the individual hands didn't change.
|
||||
if (!handsModified)
|
||||
{
|
||||
RemoveHand(ent.AsNullable(), handId);
|
||||
foreach (var hand in component.Hands.Values)
|
||||
{
|
||||
if (state.Hands.Contains(hand))
|
||||
continue;
|
||||
handsModified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var handId in state.SortedHands.Intersect(newHands))
|
||||
var manager = EnsureComp<ContainerManagerComponent>(uid);
|
||||
|
||||
if (handsModified)
|
||||
{
|
||||
AddHand(ent.AsNullable(), handId, state.Hands[handId]);
|
||||
List<Hand> addedHands = new();
|
||||
foreach (var hand in state.Hands)
|
||||
{
|
||||
if (component.Hands.ContainsKey(hand.Name))
|
||||
continue;
|
||||
|
||||
var container = _containerSystem.EnsureContainer<ContainerSlot>(uid, hand.Name, manager);
|
||||
var newHand = new Hand(hand.Name, hand.Location, container);
|
||||
component.Hands.Add(hand.Name, newHand);
|
||||
addedHands.Add(newHand);
|
||||
}
|
||||
|
||||
foreach (var name in component.Hands.Keys)
|
||||
{
|
||||
if (!state.HandNames.Contains(name))
|
||||
{
|
||||
RemoveHand(uid, name, component);
|
||||
}
|
||||
}
|
||||
|
||||
component.SortedHands.Clear();
|
||||
component.SortedHands.AddRange(state.HandNames);
|
||||
var sorted = addedHands.OrderBy(hand => component.SortedHands.IndexOf(hand.Name));
|
||||
|
||||
foreach (var hand in sorted)
|
||||
{
|
||||
AddHand(uid, hand, component);
|
||||
}
|
||||
}
|
||||
ent.Comp.SortedHands = new (state.SortedHands);
|
||||
|
||||
SetActiveHand(ent.AsNullable(), state.ActiveHandId);
|
||||
_stripSys.UpdateUi(uid);
|
||||
|
||||
_stripSys.UpdateUi(ent);
|
||||
if (component.ActiveHand == null && state.ActiveHand == null)
|
||||
return; //edge case
|
||||
|
||||
if (component.ActiveHand != null && state.ActiveHand != component.ActiveHand.Name)
|
||||
{
|
||||
SetActiveHand(uid, component.Hands[state.ActiveHand!], component);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -86,77 +129,72 @@ namespace Content.Client.Hands.Systems
|
||||
return;
|
||||
}
|
||||
|
||||
OnPlayerHandsAdded?.Invoke(hands.Value);
|
||||
OnPlayerHandsAdded?.Invoke(hands);
|
||||
}
|
||||
|
||||
public override void DoDrop(Entity<HandsComponent?> ent,
|
||||
string handId,
|
||||
bool doDropInteraction = true,
|
||||
bool log = true)
|
||||
public override void DoDrop(EntityUid uid, Hand hand, bool doDropInteraction = true, HandsComponent? hands = null, bool log = true)
|
||||
{
|
||||
base.DoDrop(ent, handId, doDropInteraction, log);
|
||||
base.DoDrop(uid, hand, doDropInteraction, hands, log);
|
||||
|
||||
if (TryGetHeldItem(ent, handId, out var held) && TryComp(held, out SpriteComponent? sprite))
|
||||
if (TryComp(hand.HeldEntity, out SpriteComponent? sprite))
|
||||
sprite.RenderOrder = EntityManager.CurrentTick.Value;
|
||||
}
|
||||
|
||||
public EntityUid? GetActiveHandEntity()
|
||||
{
|
||||
return TryGetPlayerHands(out var hands) ? GetActiveItem(hands.Value.AsNullable()) : null;
|
||||
return TryGetPlayerHands(out var hands) ? hands.ActiveHandEntity : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the hands component of the local player
|
||||
/// </summary>
|
||||
public bool TryGetPlayerHands([NotNullWhen(true)] out Entity<HandsComponent>? hands)
|
||||
public bool TryGetPlayerHands([NotNullWhen(true)] out HandsComponent? hands)
|
||||
{
|
||||
var player = _playerManager.LocalEntity;
|
||||
hands = null;
|
||||
if (player == null || !TryComp<HandsComponent>(player.Value, out var handsComp))
|
||||
return false;
|
||||
|
||||
hands = (player.Value, handsComp);
|
||||
return true;
|
||||
return player != null && TryComp(player.Value, out hands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a user clicked on their hands GUI
|
||||
/// </summary>
|
||||
public void UIHandClick(Entity<HandsComponent> ent, string handName)
|
||||
public void UIHandClick(HandsComponent hands, string handName)
|
||||
{
|
||||
var hands = ent.Comp;
|
||||
if (hands.ActiveHandId == null)
|
||||
if (!hands.Hands.TryGetValue(handName, out var pressedHand))
|
||||
return;
|
||||
|
||||
var pressedEntity = GetHeldItem(ent.AsNullable(), handName);
|
||||
var activeEntity = GetActiveItem(ent.AsNullable());
|
||||
if (hands.ActiveHand == null)
|
||||
return;
|
||||
|
||||
if (handName == hands.ActiveHandId && activeEntity != null)
|
||||
var pressedEntity = pressedHand.HeldEntity;
|
||||
var activeEntity = hands.ActiveHand.HeldEntity;
|
||||
|
||||
if (pressedHand == hands.ActiveHand && activeEntity != null)
|
||||
{
|
||||
// use item in hand
|
||||
// it will always be attack_self() in my heart.
|
||||
RaisePredictiveEvent(new RequestUseInHandEvent());
|
||||
EntityManager.RaisePredictiveEvent(new RequestUseInHandEvent());
|
||||
return;
|
||||
}
|
||||
|
||||
if (handName != hands.ActiveHandId && pressedEntity == null)
|
||||
if (pressedHand != hands.ActiveHand && pressedEntity == null)
|
||||
{
|
||||
// change active hand
|
||||
RaisePredictiveEvent(new RequestSetHandEvent(handName));
|
||||
EntityManager.RaisePredictiveEvent(new RequestSetHandEvent(handName));
|
||||
return;
|
||||
}
|
||||
|
||||
if (handName != hands.ActiveHandId && pressedEntity != null && activeEntity != null)
|
||||
if (pressedHand != hands.ActiveHand && pressedEntity != null && activeEntity != null)
|
||||
{
|
||||
// use active item on held item
|
||||
RaisePredictiveEvent(new RequestHandInteractUsingEvent(handName));
|
||||
EntityManager.RaisePredictiveEvent(new RequestHandInteractUsingEvent(pressedHand.Name));
|
||||
return;
|
||||
}
|
||||
|
||||
if (handName != hands.ActiveHandId && pressedEntity != null && activeEntity == null)
|
||||
if (pressedHand != hands.ActiveHand && pressedEntity != null && activeEntity == null)
|
||||
{
|
||||
// move the item to the active hand
|
||||
RaisePredictiveEvent(new RequestMoveHandItemEvent(handName));
|
||||
EntityManager.RaisePredictiveEvent(new RequestMoveHandItemEvent(pressedHand.Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,18 +204,19 @@ namespace Content.Client.Hands.Systems
|
||||
/// </summary>
|
||||
public void UIHandActivate(string handName)
|
||||
{
|
||||
RaisePredictiveEvent(new RequestActivateInHandEvent(handName));
|
||||
EntityManager.RaisePredictiveEvent(new RequestActivateInHandEvent(handName));
|
||||
}
|
||||
|
||||
public void UIInventoryExamine(string handName)
|
||||
{
|
||||
if (!TryGetPlayerHands(out var hands) ||
|
||||
!TryGetHeldItem(hands.Value.AsNullable(), handName, out var heldEntity))
|
||||
!hands.Hands.TryGetValue(handName, out var hand) ||
|
||||
hand.HeldEntity is not { Valid: true } entity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_examine.DoExamine(heldEntity.Value);
|
||||
_examine.DoExamine(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,12 +226,13 @@ namespace Content.Client.Hands.Systems
|
||||
public void UIHandOpenContextMenu(string handName)
|
||||
{
|
||||
if (!TryGetPlayerHands(out var hands) ||
|
||||
!TryGetHeldItem(hands.Value.AsNullable(), handName, out var heldEntity))
|
||||
!hands.Hands.TryGetValue(handName, out var hand) ||
|
||||
hand.HeldEntity is not { Valid: true } entity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ui.GetUIController<VerbMenuUIController>().OpenVerbMenu(heldEntity.Value);
|
||||
_ui.GetUIController<VerbMenuUIController>().OpenVerbMenu(entity);
|
||||
}
|
||||
|
||||
public void UIHandAltActivateItem(string handName)
|
||||
@@ -206,67 +246,60 @@ namespace Content.Client.Hands.Systems
|
||||
{
|
||||
base.HandleEntityInserted(uid, hands, args);
|
||||
|
||||
if (!hands.Hands.ContainsKey(args.Container.ID))
|
||||
if (!hands.Hands.TryGetValue(args.Container.ID, out var hand))
|
||||
return;
|
||||
|
||||
UpdateHandVisuals(uid, args.Entity, args.Container.ID);
|
||||
UpdateHandVisuals(uid, args.Entity, hand);
|
||||
_stripSys.UpdateUi(uid);
|
||||
|
||||
if (uid != _playerManager.LocalEntity)
|
||||
return;
|
||||
|
||||
OnPlayerItemAdded?.Invoke(args.Container.ID, args.Entity);
|
||||
OnPlayerItemAdded?.Invoke(hand.Name, args.Entity);
|
||||
|
||||
if (HasComp<VirtualItemComponent>(args.Entity))
|
||||
OnPlayerHandBlocked?.Invoke(args.Container.ID);
|
||||
OnPlayerHandBlocked?.Invoke(hand.Name);
|
||||
}
|
||||
|
||||
protected override void HandleEntityRemoved(EntityUid uid, HandsComponent hands, EntRemovedFromContainerMessage args)
|
||||
{
|
||||
base.HandleEntityRemoved(uid, hands, args);
|
||||
|
||||
if (!hands.Hands.ContainsKey(args.Container.ID))
|
||||
if (!hands.Hands.TryGetValue(args.Container.ID, out var hand))
|
||||
return;
|
||||
|
||||
UpdateHandVisuals(uid, args.Entity, args.Container.ID);
|
||||
UpdateHandVisuals(uid, args.Entity, hand);
|
||||
_stripSys.UpdateUi(uid);
|
||||
|
||||
if (uid != _playerManager.LocalEntity)
|
||||
return;
|
||||
|
||||
OnPlayerItemRemoved?.Invoke(args.Container.ID, args.Entity);
|
||||
OnPlayerItemRemoved?.Invoke(hand.Name, args.Entity);
|
||||
|
||||
if (HasComp<VirtualItemComponent>(args.Entity))
|
||||
OnPlayerHandUnblocked?.Invoke(args.Container.ID);
|
||||
OnPlayerHandUnblocked?.Invoke(hand.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the players sprite with new in-hand visuals.
|
||||
/// </summary>
|
||||
private void UpdateHandVisuals(Entity<HandsComponent?, SpriteComponent?> ent, EntityUid held, string handId)
|
||||
private void UpdateHandVisuals(EntityUid uid, EntityUid held, Hand hand, HandsComponent? handComp = null, SpriteComponent? sprite = null)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp1, ref ent.Comp2, false))
|
||||
return;
|
||||
var handComp = ent.Comp1;
|
||||
var sprite = ent.Comp2;
|
||||
|
||||
if (!TryGetHand((ent, handComp), handId, out var hand))
|
||||
if (!Resolve(uid, ref handComp, ref sprite, false))
|
||||
return;
|
||||
|
||||
// visual update might involve changes to the entity's effective sprite -> need to update hands GUI.
|
||||
if (ent == _playerManager.LocalEntity)
|
||||
OnPlayerItemAdded?.Invoke(handId, held);
|
||||
if (uid == _playerManager.LocalEntity)
|
||||
OnPlayerItemAdded?.Invoke(hand.Name, held);
|
||||
|
||||
if (!handComp.ShowInHands)
|
||||
return;
|
||||
|
||||
// Remove old layers. We could also just set them to invisible, but as items may add arbitrary layers, this
|
||||
// may eventually bloat the player with lots of layers.
|
||||
if (handComp.RevealedLayers.TryGetValue(hand.Value.Location, out var revealedLayers))
|
||||
if (handComp.RevealedLayers.TryGetValue(hand.Location, out var revealedLayers))
|
||||
{
|
||||
foreach (var key in revealedLayers)
|
||||
{
|
||||
_sprite.RemoveLayer((ent, sprite), key);
|
||||
_sprite.RemoveLayer((uid, sprite), key);
|
||||
}
|
||||
|
||||
revealedLayers.Clear();
|
||||
@@ -274,22 +307,22 @@ namespace Content.Client.Hands.Systems
|
||||
else
|
||||
{
|
||||
revealedLayers = new();
|
||||
handComp.RevealedLayers[hand.Value.Location] = revealedLayers;
|
||||
handComp.RevealedLayers[hand.Location] = revealedLayers;
|
||||
}
|
||||
|
||||
if (HandIsEmpty((ent, handComp), handId))
|
||||
if (hand.HeldEntity == null)
|
||||
{
|
||||
// the held item was removed.
|
||||
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(ent, revealedLayers), true);
|
||||
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(uid, revealedLayers), true);
|
||||
return;
|
||||
}
|
||||
|
||||
var ev = new GetInhandVisualsEvent(ent, hand.Value.Location);
|
||||
var ev = new GetInhandVisualsEvent(uid, hand.Location);
|
||||
RaiseLocalEvent(held, ev);
|
||||
|
||||
if (ev.Layers.Count == 0)
|
||||
{
|
||||
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(ent, revealedLayers), true);
|
||||
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(uid, revealedLayers), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -302,7 +335,7 @@ namespace Content.Client.Hands.Systems
|
||||
continue;
|
||||
}
|
||||
|
||||
var index = _sprite.LayerMapReserve((ent, sprite), key);
|
||||
var index = _sprite.LayerMapReserve((uid, sprite), key);
|
||||
|
||||
// In case no RSI is given, use the item's base RSI as a default. This cuts down on a lot of unnecessary yaml entries.
|
||||
if (layerData.RsiPath == null
|
||||
@@ -310,34 +343,35 @@ namespace Content.Client.Hands.Systems
|
||||
&& sprite[index].Rsi == null)
|
||||
{
|
||||
if (TryComp<ItemComponent>(held, out var itemComponent) && itemComponent.RsiPath != null)
|
||||
_sprite.LayerSetRsi((ent, sprite), index, new ResPath(itemComponent.RsiPath));
|
||||
_sprite.LayerSetRsi((uid, sprite), index, new ResPath(itemComponent.RsiPath));
|
||||
else if (TryComp(held, out SpriteComponent? clothingSprite))
|
||||
_sprite.LayerSetRsi((ent, sprite), index, clothingSprite.BaseRSI);
|
||||
_sprite.LayerSetRsi((uid, sprite), index, clothingSprite.BaseRSI);
|
||||
}
|
||||
|
||||
_sprite.LayerSetData((ent, sprite), index, layerData);
|
||||
_sprite.LayerSetData((uid, sprite), index, layerData);
|
||||
|
||||
// Add displacement maps
|
||||
var displacement = hand.Value.Location switch
|
||||
var displacement = hand.Location switch
|
||||
{
|
||||
HandLocation.Left => handComp.LeftHandDisplacement,
|
||||
HandLocation.Right => handComp.RightHandDisplacement,
|
||||
_ => handComp.HandDisplacement
|
||||
};
|
||||
|
||||
if (displacement is not null && _displacement.TryAddDisplacement(displacement, (ent, sprite), index, key, out var displacementKey))
|
||||
if (displacement is not null && _displacement.TryAddDisplacement(displacement, (uid, sprite), index, key, out var displacementKey))
|
||||
revealedLayers.Add(displacementKey);
|
||||
}
|
||||
|
||||
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(ent, revealedLayers), true);
|
||||
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(uid, revealedLayers), true);
|
||||
}
|
||||
|
||||
private void OnVisualsChanged(EntityUid uid, HandsComponent component, VisualsChangedEvent args)
|
||||
{
|
||||
// update hands visuals if this item is in a hand (rather then inventory or other container).
|
||||
if (!component.Hands.ContainsKey(args.ContainerId))
|
||||
return;
|
||||
UpdateHandVisuals((uid, component), GetEntity(args.Item), args.ContainerId);
|
||||
if (component.Hands.TryGetValue(args.ContainerId, out var hand))
|
||||
{
|
||||
UpdateHandVisuals(uid, GetEntity(args.Item), hand, component);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -345,7 +379,7 @@ namespace Content.Client.Hands.Systems
|
||||
|
||||
private void HandlePlayerAttached(EntityUid uid, HandsComponent component, LocalPlayerAttachedEvent args)
|
||||
{
|
||||
OnPlayerHandsAdded?.Invoke((uid, component));
|
||||
OnPlayerHandsAdded?.Invoke(component);
|
||||
}
|
||||
|
||||
private void HandlePlayerDetached(EntityUid uid, HandsComponent component, LocalPlayerDetachedEvent args)
|
||||
@@ -356,7 +390,7 @@ namespace Content.Client.Hands.Systems
|
||||
private void OnHandsStartup(EntityUid uid, HandsComponent component, ComponentStartup args)
|
||||
{
|
||||
if (_playerManager.LocalEntity == uid)
|
||||
OnPlayerHandsAdded?.Invoke((uid, component));
|
||||
OnPlayerHandsAdded?.Invoke(component);
|
||||
}
|
||||
|
||||
private void OnHandsShutdown(EntityUid uid, HandsComponent component, ComponentShutdown args)
|
||||
@@ -366,6 +400,36 @@ namespace Content.Client.Hands.Systems
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void AddHand(EntityUid uid, Hand newHand, HandsComponent? handsComp = null)
|
||||
{
|
||||
AddHand(uid, newHand.Name, newHand.Location, handsComp);
|
||||
}
|
||||
|
||||
public override void AddHand(EntityUid uid, string handName, HandLocation handLocation, HandsComponent? handsComp = null)
|
||||
{
|
||||
base.AddHand(uid, handName, handLocation, handsComp);
|
||||
|
||||
if (uid == _playerManager.LocalEntity)
|
||||
OnPlayerAddHand?.Invoke(handName, handLocation);
|
||||
|
||||
if (handsComp == null)
|
||||
return;
|
||||
|
||||
if (handsComp.ActiveHand == null)
|
||||
SetActiveHand(uid, handsComp.Hands[handName], handsComp);
|
||||
}
|
||||
public override void RemoveHand(EntityUid uid, string handName, HandsComponent? handsComp = null)
|
||||
{
|
||||
if (uid == _playerManager.LocalEntity && handsComp != null &&
|
||||
handsComp.Hands.ContainsKey(handName) && uid ==
|
||||
_playerManager.LocalEntity)
|
||||
{
|
||||
OnPlayerRemoveHand?.Invoke(handName);
|
||||
}
|
||||
|
||||
base.RemoveHand(uid, handName, handsComp);
|
||||
}
|
||||
|
||||
private void OnHandActivated(Entity<HandsComponent>? ent)
|
||||
{
|
||||
if (ent is not { } hand)
|
||||
@@ -374,7 +438,13 @@ namespace Content.Client.Hands.Systems
|
||||
if (_playerManager.LocalEntity != hand.Owner)
|
||||
return;
|
||||
|
||||
OnPlayerSetActiveHand?.Invoke(hand.Comp.ActiveHandId);
|
||||
if (hand.Comp.ActiveHand == null)
|
||||
{
|
||||
OnPlayerSetActiveHand?.Invoke(null);
|
||||
return;
|
||||
}
|
||||
|
||||
OnPlayerSetActiveHand?.Invoke(hand.Comp.ActiveHand.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public sealed class HolopadSystem : SharedHolopadSystem
|
||||
// Remove shading from all layers (except displacement maps)
|
||||
for (var i = 0; i < hologramSprite.AllLayers.Count(); i++)
|
||||
{
|
||||
if (_sprite.TryGetLayer((hologram, hologramSprite), i, out var layer, false) && layer.ShaderPrototype != "DisplacedDraw")
|
||||
if (_sprite.TryGetLayer((hologram, hologramSprite), i, out var layer, false) && layer.ShaderPrototype != "DisplacedStencilDraw")
|
||||
hologramSprite.LayerSetShader(i, "unshaded");
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ public sealed class EyeColorPicker : Control
|
||||
AddChild(vBox);
|
||||
|
||||
vBox.AddChild(_colorSelectors = new ColorSelectorSliders());
|
||||
_colorSelectors.SelectorType = ColorSelectorSliders.ColorSelectorType.Hsv; // defaults color selector to HSV
|
||||
|
||||
_colorSelectors.OnColorChanged += ColorValueChanged;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
|
||||
private void OnCvarChanged(bool value)
|
||||
{
|
||||
var humanoidQuery = AllEntityQuery<HumanoidAppearanceComponent, SpriteComponent>();
|
||||
var humanoidQuery = EntityManager.AllEntityQueryEnumerator<HumanoidAppearanceComponent, SpriteComponent>();
|
||||
while (humanoidQuery.MoveNext(out var uid, out var humanoidComp, out var spriteComp))
|
||||
{
|
||||
UpdateSprite((uid, humanoidComp, spriteComp));
|
||||
|
||||
@@ -416,7 +416,6 @@ public sealed partial class MarkingPicker : Control
|
||||
CMarkingColors.AddChild(colorContainer);
|
||||
|
||||
ColorSelectorSliders colorSelector = new ColorSelectorSliders();
|
||||
colorSelector.SelectorType = ColorSelectorSliders.ColorSelectorType.Hsv; // defaults color selector to HSV
|
||||
colorSliders.Add(colorSelector);
|
||||
|
||||
colorContainer.AddChild(new Label { Text = $"{stateNames[i]} color:" });
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed partial class SingleMarkingPicker : BoxContainer
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// What happens if a marking is selected.
|
||||
/// It will send the 'slot' (marking index)
|
||||
@@ -231,7 +231,6 @@ public sealed partial class SingleMarkingPicker : BoxContainer
|
||||
HorizontalExpand = true
|
||||
};
|
||||
selector.Color = marking.MarkingColors[i];
|
||||
selector.SelectorType = ColorSelectorSliders.ColorSelectorType.Hsv; // defaults color selector to HSV
|
||||
|
||||
var colorIndex = i;
|
||||
selector.OnColorChanged += color =>
|
||||
|
||||
@@ -102,8 +102,6 @@ public static class MidiParser
|
||||
// 0x03 is TrackName,
|
||||
// 0x04 is InstrumentName
|
||||
|
||||
// This string can potentially contain control characters, including 0x00 which can cause problems if it ends up in database entries via admin logs
|
||||
// we sanitize TrackName and InstrumentName after they have been send to the server
|
||||
var text = Encoding.ASCII.GetString(metaData, 0, (int)metaLength);
|
||||
switch (metaType)
|
||||
{
|
||||
|
||||
@@ -194,12 +194,12 @@ namespace Content.Client.Inventory
|
||||
|
||||
public void UIInventoryActivate(string slot)
|
||||
{
|
||||
RaisePredictiveEvent(new UseSlotNetworkMessage(slot));
|
||||
EntityManager.RaisePredictiveEvent(new UseSlotNetworkMessage(slot));
|
||||
}
|
||||
|
||||
public void UIInventoryStorageActivate(string slot)
|
||||
{
|
||||
RaisePredictiveEvent(new OpenSlotStorageNetworkMessage(slot));
|
||||
EntityManager.RaisePredictiveEvent(new OpenSlotStorageNetworkMessage(slot));
|
||||
}
|
||||
|
||||
public void UIInventoryExamine(string slot, EntityUid uid)
|
||||
@@ -223,7 +223,7 @@ namespace Content.Client.Inventory
|
||||
if (!TryGetSlotEntity(uid, slot, out var item))
|
||||
return;
|
||||
|
||||
RaisePredictiveEvent(
|
||||
EntityManager.RaisePredictiveEvent(
|
||||
new InteractInventorySlotEvent(GetNetEntity(item.Value), altInteract: false));
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace Content.Client.Inventory
|
||||
if (!TryGetSlotEntity(uid, slot, out var item))
|
||||
return;
|
||||
|
||||
RaisePredictiveEvent(new InteractInventorySlotEvent(GetNetEntity(item.Value), altInteract: true));
|
||||
EntityManager.RaisePredictiveEvent(new InteractInventorySlotEvent(GetNetEntity(item.Value), altInteract: true));
|
||||
}
|
||||
|
||||
protected override void UpdateInventoryTemplate(Entity<InventoryComponent> ent)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Examine;
|
||||
using Content.Client.Hands.Systems;
|
||||
using Content.Client.Strip;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
@@ -35,7 +34,6 @@ namespace Content.Client.Inventory
|
||||
[Dependency] private readonly IUserInterfaceManager _ui = default!;
|
||||
|
||||
private readonly ExamineSystem _examine;
|
||||
private readonly HandsSystem _hands;
|
||||
private readonly InventorySystem _inv;
|
||||
private readonly SharedCuffableSystem _cuffable;
|
||||
private readonly StrippableSystem _strippable;
|
||||
@@ -67,7 +65,6 @@ namespace Content.Client.Inventory
|
||||
public StrippableBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_examine = EntMan.System<ExamineSystem>();
|
||||
_hands = EntMan.System<HandsSystem>();
|
||||
_inv = EntMan.System<InventorySystem>();
|
||||
_cuffable = EntMan.System<SharedCuffableSystem>();
|
||||
_strippable = EntMan.System<StrippableSystem>();
|
||||
@@ -123,28 +120,28 @@ namespace Content.Client.Inventory
|
||||
{
|
||||
// good ol hands shit code. there is a GuiHands comparer that does the same thing... but these are hands
|
||||
// and not gui hands... which are different...
|
||||
foreach (var (id, hand) in handsComp.Hands)
|
||||
foreach (var hand in handsComp.Hands.Values)
|
||||
{
|
||||
if (hand.Location != HandLocation.Right)
|
||||
continue;
|
||||
|
||||
AddHandButton((Owner, handsComp), id, hand);
|
||||
AddHandButton(hand);
|
||||
}
|
||||
|
||||
foreach (var (id, hand) in handsComp.Hands)
|
||||
foreach (var hand in handsComp.Hands.Values)
|
||||
{
|
||||
if (hand.Location != HandLocation.Middle)
|
||||
continue;
|
||||
|
||||
AddHandButton((Owner, handsComp), id, hand);
|
||||
AddHandButton(hand);
|
||||
}
|
||||
|
||||
foreach (var (id, hand) in handsComp.Hands)
|
||||
foreach (var hand in handsComp.Hands.Values)
|
||||
{
|
||||
if (hand.Location != HandLocation.Left)
|
||||
continue;
|
||||
|
||||
AddHandButton((Owner, handsComp), id, hand);
|
||||
AddHandButton(hand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,21 +177,20 @@ namespace Content.Client.Inventory
|
||||
_strippingMenu.SetSize = new Vector2(horizontalMenuSize, verticalMenuSize);
|
||||
}
|
||||
|
||||
private void AddHandButton(Entity<HandsComponent> ent, string handId, Hand hand)
|
||||
private void AddHandButton(Hand hand)
|
||||
{
|
||||
var button = new HandButton(handId, hand.Location);
|
||||
var button = new HandButton(hand.Name, hand.Location);
|
||||
|
||||
button.Pressed += SlotPressed;
|
||||
|
||||
var heldEntity = _hands.GetHeldItem(ent.AsNullable(), handId);
|
||||
if (EntMan.TryGetComponent<VirtualItemComponent>(heldEntity, out var virt))
|
||||
if (EntMan.TryGetComponent<VirtualItemComponent>(hand.HeldEntity, out var virt))
|
||||
{
|
||||
button.Blocked = true;
|
||||
if (EntMan.TryGetComponent<CuffableComponent>(Owner, out var cuff) && _cuffable.GetAllCuffs(cuff).Contains(virt.BlockingEntity))
|
||||
button.BlockedRect.MouseFilter = MouseFilterMode.Ignore;
|
||||
}
|
||||
|
||||
UpdateEntityIcon(button, heldEntity);
|
||||
UpdateEntityIcon(button, hand.HeldEntity);
|
||||
_strippingMenu!.HandsContainer.AddChild(button);
|
||||
LayoutContainer.SetPosition(button, new Vector2i(_handCount, 0) * (SlotControl.DefaultButtonSize + ButtonSeparation));
|
||||
_handCount++;
|
||||
|
||||
@@ -223,14 +223,13 @@ public sealed partial class LatheMenu : DefaultWindow
|
||||
/// Populates the build queue list with all queued items
|
||||
/// </summary>
|
||||
/// <param name="queue"></param>
|
||||
public void PopulateQueueList(IReadOnlyCollection<ProtoId<LatheRecipePrototype>> queue)
|
||||
public void PopulateQueueList(List<LatheRecipePrototype> queue)
|
||||
{
|
||||
QueueList.DisposeAllChildren();
|
||||
|
||||
var idx = 1;
|
||||
foreach (var recipeProto in queue)
|
||||
foreach (var recipe in queue)
|
||||
{
|
||||
var recipe = _prototypeManager.Index(recipeProto);
|
||||
var queuedRecipeBox = new BoxContainer();
|
||||
queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
||||
|
||||
@@ -244,14 +243,12 @@ public sealed partial class LatheMenu : DefaultWindow
|
||||
}
|
||||
}
|
||||
|
||||
public void SetQueueInfo(ProtoId<LatheRecipePrototype>? recipeProto)
|
||||
public void SetQueueInfo(LatheRecipePrototype? recipe)
|
||||
{
|
||||
FabricatingContainer.Visible = recipeProto != null;
|
||||
if (recipeProto == null)
|
||||
FabricatingContainer.Visible = recipe != null;
|
||||
if (recipe == null)
|
||||
return;
|
||||
|
||||
var recipe = _prototypeManager.Index(recipeProto.Value);
|
||||
|
||||
FabricatingDisplayContainer.Children.Clear();
|
||||
FabricatingDisplayContainer.AddChild(GetRecipeDisplayControl(recipe));
|
||||
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Light;
|
||||
|
||||
/// <summary>
|
||||
/// Applies ambient-occlusion to the viewport.
|
||||
/// </summary>
|
||||
public sealed class AmbientOcclusionOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IClyde _clyde = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities;
|
||||
|
||||
private IRenderTexture? _aoTarget;
|
||||
private IRenderTexture? _aoBlurBuffer;
|
||||
|
||||
// Couldn't figure out a way to avoid this so if you can then please do.
|
||||
private IRenderTexture? _aoStencilTarget;
|
||||
|
||||
public AmbientOcclusionOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
ZIndex = AfterLightTargetOverlay.ContentZIndex + 1;
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
/*
|
||||
* tl;dr
|
||||
* - we draw a black square on each "ambient occlusion" entity.
|
||||
* - we blur this.
|
||||
* - We apply it to the viewport.
|
||||
*
|
||||
* We do this while ignoring lighting because it will wash out the actual effect.
|
||||
* In 3D ambient occlusion is more complicated due top having to calculate normals but in 2D
|
||||
* we don't have a concept of depth / corners necessarily.
|
||||
*/
|
||||
|
||||
var viewport = args.Viewport;
|
||||
var mapId = args.MapId;
|
||||
var worldBounds = args.WorldBounds;
|
||||
var worldHandle = args.WorldHandle;
|
||||
var color = Color.FromHex(_cfgManager.GetCVar(CCVars.AmbientOcclusionColor));
|
||||
var distance = _cfgManager.GetCVar(CCVars.AmbientOcclusionDistance);
|
||||
//var color = Color.Red;
|
||||
var target = viewport.RenderTarget;
|
||||
var lightScale = target.Size / (Vector2) viewport.Size;
|
||||
var scale = viewport.RenderScale / (Vector2.One / lightScale);
|
||||
var maps = _entManager.System<SharedMapSystem>();
|
||||
var lookups = _entManager.System<EntityLookupSystem>();
|
||||
var query = _entManager.System<OccluderSystem>();
|
||||
var xformSystem = _entManager.System<SharedTransformSystem>();
|
||||
var turfSystem = _entManager.System<TurfSystem>();
|
||||
var invMatrix = args.Viewport.GetWorldToLocalMatrix();
|
||||
|
||||
if (_aoTarget?.Texture.Size != target.Size)
|
||||
{
|
||||
_aoTarget?.Dispose();
|
||||
_aoTarget = _clyde.CreateRenderTarget(target.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "ambient-occlusion-target");
|
||||
}
|
||||
|
||||
if (_aoBlurBuffer?.Texture.Size != target.Size)
|
||||
{
|
||||
_aoBlurBuffer?.Dispose();
|
||||
_aoBlurBuffer = _clyde.CreateRenderTarget(target.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "ambient-occlusion-blur-target");
|
||||
}
|
||||
|
||||
if (_aoStencilTarget?.Texture.Size != target.Size)
|
||||
{
|
||||
_aoStencilTarget?.Dispose();
|
||||
_aoStencilTarget = _clyde.CreateRenderTarget(target.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "ambient-occlusion-stencil-target");
|
||||
}
|
||||
|
||||
// Draw the texture data to the texture.
|
||||
args.WorldHandle.RenderInRenderTarget(_aoTarget,
|
||||
() =>
|
||||
{
|
||||
worldHandle.UseShader(_proto.Index<ShaderPrototype>("unshaded").Instance());
|
||||
var invMatrix = _aoTarget.GetWorldToLocalMatrix(viewport.Eye!, scale);
|
||||
|
||||
foreach (var entry in query.QueryAabb(mapId, worldBounds))
|
||||
{
|
||||
DebugTools.Assert(entry.Component.Enabled);
|
||||
var matrix = xformSystem.GetWorldMatrix(entry.Transform);
|
||||
var localMatrix = Matrix3x2.Multiply(matrix, invMatrix);
|
||||
|
||||
worldHandle.SetTransform(localMatrix);
|
||||
// 4 pixels
|
||||
worldHandle.DrawRect(Box2.UnitCentered.Enlarged(distance / EyeManager.PixelsPerMeter), Color.White);
|
||||
}
|
||||
}, Color.Transparent);
|
||||
|
||||
_clyde.BlurRenderTarget(viewport, _aoTarget, _aoBlurBuffer, viewport.Eye!, 14f);
|
||||
|
||||
// Need to do stencilling after blur as it will nuke it.
|
||||
// Draw stencil for the grid so we don't draw in space.
|
||||
args.WorldHandle.RenderInRenderTarget(_aoStencilTarget,
|
||||
() =>
|
||||
{
|
||||
// Don't want lighting affecting it.
|
||||
worldHandle.UseShader(_proto.Index<ShaderPrototype>("unshaded").Instance());
|
||||
|
||||
foreach (var grid in _mapManager.FindGridsIntersecting(mapId, worldBounds))
|
||||
{
|
||||
var transform = xformSystem.GetWorldMatrix(grid.Owner);
|
||||
var worldToTextureMatrix = Matrix3x2.Multiply(transform, invMatrix);
|
||||
var tiles = maps.GetTilesEnumerator(grid.Owner, grid, worldBounds);
|
||||
worldHandle.SetTransform(worldToTextureMatrix);
|
||||
while (tiles.MoveNext(out var tileRef))
|
||||
{
|
||||
if (turfSystem.IsSpace(tileRef))
|
||||
continue;
|
||||
|
||||
var bounds = lookups.GetLocalBounds(tileRef, grid.TileSize);
|
||||
worldHandle.DrawRect(bounds, Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
}, Color.Transparent);
|
||||
|
||||
// Draw the stencil texture to depth buffer.
|
||||
worldHandle.UseShader(_proto.Index<ShaderPrototype>("StencilMask").Instance());
|
||||
worldHandle.DrawTextureRect(_aoStencilTarget!.Texture, worldBounds);
|
||||
|
||||
// Draw the Blurred AO texture finally.
|
||||
worldHandle.UseShader(_proto.Index<ShaderPrototype>("StencilEqualDraw").Instance());
|
||||
worldHandle.DrawTextureRect(_aoTarget!.Texture, worldBounds, color);
|
||||
|
||||
args.WorldHandle.SetTransform(Matrix3x2.Identity);
|
||||
args.WorldHandle.UseShader(null);
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
/// </summary>
|
||||
private void CopyLightSettings(Entity<LightBehaviourComponent> entity, string property)
|
||||
{
|
||||
if (TryComp(entity, out PointLightComponent? light))
|
||||
if (EntityManager.TryGetComponent(entity, out PointLightComponent? light))
|
||||
{
|
||||
var propertyValue = AnimationHelper.GetAnimatableProperty(light, property);
|
||||
if (propertyValue != null)
|
||||
@@ -73,7 +73,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"{Comp<MetaDataComponent>(entity).EntityName} has a {nameof(LightBehaviourComponent)} but it has no {nameof(PointLightComponent)}! Check the prototype!");
|
||||
Log.Warning($"{EntityManager.GetComponent<MetaDataComponent>(entity).EntityName} has a {nameof(LightBehaviourComponent)} but it has no {nameof(PointLightComponent)}! Check the prototype!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
/// </summary>
|
||||
public void StartLightBehaviour(Entity<LightBehaviourComponent> entity, string id = "")
|
||||
{
|
||||
if (!TryComp(entity, out AnimationPlayerComponent? animation))
|
||||
if (!EntityManager.TryGetComponent(entity, out AnimationPlayerComponent? animation))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
/// <param name="resetToOriginalSettings">Should the light have its original settings applied?</param>
|
||||
public void StopLightBehaviour(Entity<LightBehaviourComponent> entity, string id = "", bool removeBehaviour = false, bool resetToOriginalSettings = false)
|
||||
{
|
||||
if (!TryComp(entity, out AnimationPlayerComponent? animation))
|
||||
if (!EntityManager.TryGetComponent(entity, out AnimationPlayerComponent? animation))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
comp.Animations.Remove(container);
|
||||
}
|
||||
|
||||
if (resetToOriginalSettings && TryComp(entity, out PointLightComponent? light))
|
||||
if (resetToOriginalSettings && EntityManager.TryGetComponent(entity, out PointLightComponent? light))
|
||||
{
|
||||
foreach (var (property, value) in comp.OriginalPropertyValues)
|
||||
{
|
||||
@@ -161,7 +161,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
public bool HasRunningBehaviours(Entity<LightBehaviourComponent> entity)
|
||||
{
|
||||
//var uid = Owner;
|
||||
if (!TryComp(entity, out AnimationPlayerComponent? animation))
|
||||
if (!EntityManager.TryGetComponent(entity, out AnimationPlayerComponent? animation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,51 +1,17 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Client.Light.EntitySystems;
|
||||
|
||||
public sealed class PlanetLightSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Enables / disables the ambient occlusion overlay.
|
||||
/// </summary>
|
||||
public bool AmbientOcclusion
|
||||
{
|
||||
get => _ambientOcclusion;
|
||||
set
|
||||
{
|
||||
if (_ambientOcclusion == value)
|
||||
return;
|
||||
|
||||
_ambientOcclusion = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
_overlayMan.AddOverlay(new AmbientOcclusionOverlay());
|
||||
}
|
||||
else
|
||||
{
|
||||
_overlayMan.RemoveOverlay<AmbientOcclusionOverlay>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _ambientOcclusion;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GetClearColorEvent>(OnClearColor);
|
||||
|
||||
_cfgManager.OnValueChanged(CCVars.AmbientOcclusion, val =>
|
||||
{
|
||||
AmbientOcclusion = val;
|
||||
}, true);
|
||||
|
||||
_overlayMan.AddOverlay(new BeforeLightTargetOverlay());
|
||||
_overlayMan.AddOverlay(new RoofOverlay(EntityManager));
|
||||
_overlayMan.AddOverlay(new TileEmissionOverlay(EntityManager));
|
||||
|
||||
@@ -62,8 +62,6 @@ public sealed class RoofOverlay : Overlay
|
||||
worldHandle.RenderInRenderTarget(target,
|
||||
() =>
|
||||
{
|
||||
var invMatrix = target.GetWorldToLocalMatrix(eye, scale);
|
||||
|
||||
for (var i = 0; i < _grids.Count; i++)
|
||||
{
|
||||
var grid = _grids[i];
|
||||
@@ -71,6 +69,8 @@ public sealed class RoofOverlay : Overlay
|
||||
if (!_entManager.TryGetComponent(grid.Owner, out ImplicitRoofComponent? roof))
|
||||
continue;
|
||||
|
||||
var invMatrix = target.GetWorldToLocalMatrix(eye, scale);
|
||||
|
||||
var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner);
|
||||
var matty = Matrix3x2.Multiply(gridMatrix, invMatrix);
|
||||
|
||||
@@ -94,13 +94,13 @@ public sealed class RoofOverlay : Overlay
|
||||
worldHandle.RenderInRenderTarget(target,
|
||||
() =>
|
||||
{
|
||||
var invMatrix = target.GetWorldToLocalMatrix(eye, scale);
|
||||
|
||||
foreach (var grid in _grids)
|
||||
{
|
||||
if (!_entManager.TryGetComponent(grid.Owner, out RoofComponent? roof))
|
||||
continue;
|
||||
|
||||
var invMatrix = target.GetWorldToLocalMatrix(eye, scale);
|
||||
|
||||
var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner);
|
||||
var matty = Matrix3x2.Multiply(gridMatrix, invMatrix);
|
||||
|
||||
|
||||
@@ -241,7 +241,6 @@ namespace Content.Client.Lobby.UI
|
||||
};
|
||||
|
||||
RgbSkinColorContainer.AddChild(_rgbSkinColorSelector = new ColorSelectorSliders());
|
||||
_rgbSkinColorSelector.SelectorType = ColorSelectorSliders.ColorSelectorType.Hsv; // defaults color selector to HSV
|
||||
_rgbSkinColorSelector.OnColorChanged += _ =>
|
||||
{
|
||||
OnSkinColorOnValueChanged();
|
||||
|
||||
@@ -144,8 +144,8 @@ public sealed partial class LoadoutGroupContainer : BoxContainer
|
||||
{
|
||||
subList.AddChild(proto);
|
||||
}
|
||||
var itemName = firstElement.Text ?? "";
|
||||
UpdateSubGroupSelectedInfo(firstElement, itemName, subList);
|
||||
|
||||
UpdateToggleColor(toggle, subList);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -164,14 +164,12 @@ public sealed partial class LoadoutGroupContainer : BoxContainer
|
||||
};
|
||||
|
||||
toggle.Text = subContainer.Visible ? OpenedGroupMark : ClosedGroupMark;
|
||||
toggle.Pressed = subContainer.Visible;
|
||||
|
||||
toggle.OnPressed += _ =>
|
||||
{
|
||||
var willOpen = !subContainer.Visible;
|
||||
subContainer.Visible = willOpen;
|
||||
toggle.Text = willOpen ? OpenedGroupMark : ClosedGroupMark;
|
||||
toggle.Pressed = willOpen;
|
||||
_openedGroups[kvp.Key] = willOpen;
|
||||
};
|
||||
|
||||
@@ -180,16 +178,15 @@ public sealed partial class LoadoutGroupContainer : BoxContainer
|
||||
return toggle;
|
||||
}
|
||||
|
||||
private void UpdateSubGroupSelectedInfo(LoadoutContainer loadout, string itemName, BoxContainer subList)
|
||||
private void UpdateToggleColor(Button toggle, BoxContainer subList)
|
||||
{
|
||||
var countSubSelected = subList.Children
|
||||
var anyActive = subList.Children
|
||||
.OfType<LoadoutContainer>()
|
||||
.Count(c => c.Select.Pressed);
|
||||
.Any(c => c.Select.Pressed);
|
||||
|
||||
if (countSubSelected > 0)
|
||||
{
|
||||
loadout.Text = Loc.GetString("loadouts-count-items-in-group", ("item", itemName), ("count", countSubSelected));
|
||||
}
|
||||
toggle.Modulate = anyActive
|
||||
? Color.Green
|
||||
: Color.White;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -793,7 +793,7 @@ public sealed class MappingState : GameplayStateBase
|
||||
|
||||
if (_mapMan.TryFindGridAt(mapPos, out var gridUid, out var grid) &&
|
||||
_entityManager.System<SharedMapSystem>().TryGetTileRef(gridUid, grid, coords, out var tileRef) &&
|
||||
_allPrototypesDict.TryGetValue(_entityManager.System<TurfSystem>().GetContentTileDefinition(tileRef), out button))
|
||||
_allPrototypesDict.TryGetValue(tileRef.GetContentTileDefinition(), out button))
|
||||
{
|
||||
OnSelected(button);
|
||||
return true;
|
||||
|
||||
@@ -33,7 +33,7 @@ public sealed class MarkerSystem : EntitySystem
|
||||
|
||||
private void UpdateVisibility(EntityUid uid)
|
||||
{
|
||||
if (TryComp(uid, out SpriteComponent? sprite))
|
||||
if (EntityManager.TryGetComponent(uid, out SpriteComponent? sprite))
|
||||
{
|
||||
_sprite.SetVisible((uid, sprite), MarkersVisible);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Numerics;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
@@ -15,8 +14,6 @@ namespace Content.Client.NetworkConfigurator;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private const string PanelBgColor = "#202023";
|
||||
|
||||
private readonly LinksRender _links;
|
||||
@@ -36,7 +33,6 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
||||
public NetworkConfiguratorLinkMenu()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
var footerStyleBox = new StyleBoxFlat()
|
||||
{
|
||||
@@ -65,7 +61,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
||||
ButtonContainerRight.RemoveAllChildren();
|
||||
|
||||
_sources.Clear();
|
||||
_sources.AddRange(linkState.Sources.Select(s => _prototypeManager.Index(s)));
|
||||
_sources.AddRange(linkState.Sources);
|
||||
_links.SourceButtons.Clear();
|
||||
var i = 0;
|
||||
foreach (var source in _sources)
|
||||
@@ -77,7 +73,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
||||
}
|
||||
|
||||
_sinks.Clear();
|
||||
_sinks.AddRange(linkState.Sinks.Select(s => _prototypeManager.Index(s)));
|
||||
_sinks.AddRange(linkState.Sinks);
|
||||
_links.SinkButtons.Clear();
|
||||
i = 0;
|
||||
foreach (var sink in _sinks)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
<ui:OptionDropDown Name="DropDownLightingQuality" Title="{Loc 'ui-options-lighting-label'}" />
|
||||
<CheckBox Name="ViewportLowResCheckBox" Text="{Loc 'ui-options-vp-low-res'}" />
|
||||
<CheckBox Name="ParallaxLowQualityCheckBox" Text="{Loc 'ui-options-parallax-low-quality'}" />
|
||||
<CheckBox Name="AmbientOcclusionCheckBox" Text="{Loc 'ui-options-ambient-occlusion'}" />
|
||||
|
||||
<!-- Interface -->
|
||||
<Label Text="{Loc 'ui-options-interface-label'}" StyleClasses="LabelKeyText"/>
|
||||
|
||||
@@ -20,7 +20,6 @@ public sealed partial class GraphicsTab : Control
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
Control.AddOptionCheckBox(CVars.DisplayVSync, VSyncCheckBox);
|
||||
Control.AddOptionCheckBox(CCVars.AmbientOcclusion, AmbientOcclusionCheckBox);
|
||||
Control.AddOption(new OptionFullscreen(Control, _cfg, FullscreenCheckBox));
|
||||
Control.AddOption(new OptionLightingQuality(Control, _cfg, DropDownLightingQuality));
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public sealed class OrbitVisualsSystem : EntitySystem
|
||||
{
|
||||
base.FrameUpdate(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<OrbitVisualsComponent, SpriteComponent>();
|
||||
var query = EntityManager.EntityQueryEnumerator<OrbitVisualsComponent, SpriteComponent>();
|
||||
while (query.MoveNext(out var uid, out var orbit, out var sprite))
|
||||
{
|
||||
var progress = (float)(_timing.CurTime.TotalSeconds / orbit.OrbitLength) % 1;
|
||||
|
||||
@@ -48,14 +48,17 @@ public sealed class PowerCellSystem : SharedPowerCellSystem
|
||||
if (!_sprite.LayerExists((uid, args.Sprite), PowerCellVisualLayers.Unshaded))
|
||||
return;
|
||||
|
||||
if (!_appearance.TryGetData<byte>(uid, PowerCellVisuals.ChargeLevel, out var level, args.Component))
|
||||
level = 0;
|
||||
if (_appearance.TryGetData<byte>(uid, PowerCellVisuals.ChargeLevel, out var level, args.Component))
|
||||
{
|
||||
if (level == 0)
|
||||
{
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), PowerCellVisualLayers.Unshaded, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var positiveCharge = level > 0;
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), PowerCellVisualLayers.Unshaded, positiveCharge);
|
||||
|
||||
if (positiveCharge)
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), PowerCellVisualLayers.Unshaded, false);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), PowerCellVisualLayers.Unshaded, $"o{level}");
|
||||
}
|
||||
}
|
||||
|
||||
private enum PowerCellVisualLayers : byte
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Hands.Systems;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.RCD.Components;
|
||||
@@ -18,7 +17,6 @@ public sealed class AlignRCDConstruction : PlacementMode
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
private readonly SharedMapSystem _mapSystem;
|
||||
private readonly HandsSystem _handsSystem;
|
||||
private readonly RCDSystem _rcdSystem;
|
||||
private readonly SharedTransformSystem _transformSystem;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
@@ -36,7 +34,6 @@ public sealed class AlignRCDConstruction : PlacementMode
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_mapSystem = _entityManager.System<SharedMapSystem>();
|
||||
_handsSystem = _entityManager.System<HandsSystem>();
|
||||
_rcdSystem = _entityManager.System<RCDSystem>();
|
||||
_transformSystem = _entityManager.System<SharedTransformSystem>();
|
||||
|
||||
@@ -91,9 +88,11 @@ public sealed class AlignRCDConstruction : PlacementMode
|
||||
}
|
||||
|
||||
// Determine if player is carrying an RCD in their active hand
|
||||
if (!_handsSystem.TryGetActiveItem(player.Value, out var heldEntity))
|
||||
if (!_entityManager.TryGetComponent<HandsComponent>(player, out var hands))
|
||||
return false;
|
||||
|
||||
var heldEntity = hands.ActiveHand?.HeldEntity;
|
||||
|
||||
if (!_entityManager.TryGetComponent<RCDComponent>(heldEntity, out var rcd))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using Content.Client.Hands.Systems;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.RCD;
|
||||
using Content.Shared.RCD.Components;
|
||||
using Content.Shared.RCD.Systems;
|
||||
using Robust.Client.Placement;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Enums;
|
||||
@@ -9,18 +10,13 @@ using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.RCD;
|
||||
|
||||
/// <summary>
|
||||
/// System for handling structure ghost placement in places where RCD can create objects.
|
||||
/// </summary>
|
||||
public sealed class RCDConstructionGhostSystem : EntitySystem
|
||||
{
|
||||
private const string PlacementMode = nameof(AlignRCDConstruction);
|
||||
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPlacementManager _placementManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
[Dependency] private readonly HandsSystem _hands = default!;
|
||||
|
||||
|
||||
private string _placementMode = typeof(AlignRCDConstruction).Name;
|
||||
private Direction _placementDirection = default;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
@@ -37,10 +33,12 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
|
||||
return;
|
||||
|
||||
// Determine if player is carrying an RCD in their active hand
|
||||
if (_playerManager.LocalSession?.AttachedEntity is not { } player)
|
||||
var player = _playerManager.LocalSession?.AttachedEntity;
|
||||
|
||||
if (!TryComp<HandsComponent>(player, out var hands))
|
||||
return;
|
||||
|
||||
var heldEntity = _hands.GetActiveItem(player);
|
||||
var heldEntity = hands.ActiveHand?.HeldEntity;
|
||||
|
||||
if (!TryComp<RCDComponent>(heldEntity, out var rcd))
|
||||
{
|
||||
@@ -67,7 +65,7 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
|
||||
var newObjInfo = new PlacementInformation
|
||||
{
|
||||
MobUid = heldEntity.Value,
|
||||
PlacementOption = PlacementMode,
|
||||
PlacementOption = _placementMode,
|
||||
EntityType = prototype.Prototype,
|
||||
Range = (int) Math.Ceiling(SharedInteractionSystem.InteractionRange),
|
||||
IsTile = (prototype.Mode == RcdMode.ConstructTile),
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Content.Client.Alerts;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Alert.Components;
|
||||
using Content.Shared.Revenant;
|
||||
using Content.Shared.Revenant.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
@@ -17,7 +15,7 @@ public sealed class RevenantSystem : EntitySystem
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RevenantComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
SubscribeLocalEvent<RevenantComponent, GetGenericAlertCounterAmountEvent>(OnGetCounterAmount);
|
||||
SubscribeLocalEvent<RevenantComponent, UpdateAlertSpriteEvent>(OnUpdateAlert);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, RevenantComponent component, ref AppearanceChangeEvent args)
|
||||
@@ -42,14 +40,14 @@ public sealed class RevenantSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGetCounterAmount(Entity<RevenantComponent> ent, ref GetGenericAlertCounterAmountEvent args)
|
||||
private void OnUpdateAlert(Entity<RevenantComponent> ent, ref UpdateAlertSpriteEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
if (args.Alert.ID != ent.Comp.EssenceAlert)
|
||||
return;
|
||||
|
||||
if (ent.Comp.EssenceAlert != args.Alert)
|
||||
return;
|
||||
|
||||
args.Amount = ent.Comp.Essence.Int();
|
||||
var essence = Math.Clamp(ent.Comp.Essence.Int(), 0, 999);
|
||||
_sprite.LayerSetRsiState(args.SpriteViewEnt.AsNullable(), RevenantVisualLayers.Digit1, $"{(essence / 100) % 10}");
|
||||
_sprite.LayerSetRsiState(args.SpriteViewEnt.AsNullable(), RevenantVisualLayers.Digit2, $"{(essence / 10) % 10}");
|
||||
_sprite.LayerSetRsiState(args.SpriteViewEnt.AsNullable(), RevenantVisualLayers.Digit3, $"{essence % 10}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Content.Client.Sandbox
|
||||
|
||||
// Try copy entity.
|
||||
if (uid.IsValid()
|
||||
&& TryComp(uid, out MetaDataComponent? comp)
|
||||
&& EntityManager.TryGetComponent(uid, out MetaDataComponent? comp)
|
||||
&& !comp.EntityDeleted)
|
||||
{
|
||||
if (comp.EntityPrototype == null || comp.EntityPrototype.HideSpawnMenu || comp.EntityPrototype.Abstract)
|
||||
|
||||
@@ -25,29 +25,6 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
|
||||
private TimeSpan _retentionTime;
|
||||
private readonly Dictionary<int, SensorData> _sensorData = new();
|
||||
|
||||
/// <summary>
|
||||
/// <para>A shared array used to store vertices for drawing graphs in <see cref="GraphView"/>.
|
||||
/// Prevents excessive allocations by reusing the same array across multiple graph views.</para>
|
||||
/// <para>This effectively makes it so that each <see cref="SensorMonitoringWindow"/> has its own pooled array.</para>
|
||||
/// </summary>
|
||||
private Vector2[] _sharedVertices = [];
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a shared array of vertices, ensuring that it has at least the requested size.
|
||||
/// Assigns a new array of the requested size if the current shared array is smaller than the requested size.
|
||||
/// </summary>
|
||||
/// <param name="requestedSize">The minimum number of vertices required in the shared array.</param>
|
||||
/// <returns>An array of <see cref="System.Numerics.Vector2"/> representing the shared vertices.</returns>
|
||||
/// <remarks>This does not prevent other threads from accessing the same shared pool.</remarks>
|
||||
public Vector2[] GetSharedVertices(int requestedSize)
|
||||
{
|
||||
if (_sharedVertices.Length < requestedSize)
|
||||
{
|
||||
_sharedVertices = new Vector2[requestedSize];
|
||||
}
|
||||
return _sharedVertices;
|
||||
}
|
||||
|
||||
public SensorMonitoringWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -168,7 +145,7 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
|
||||
}
|
||||
});
|
||||
|
||||
Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f, this) { MinHeight = 150 });
|
||||
Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f) { MinHeight = 150 });
|
||||
Asdf.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } });
|
||||
}
|
||||
}
|
||||
@@ -220,37 +197,31 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
|
||||
private readonly TimeSpan _startTime;
|
||||
private readonly TimeSpan _curTime;
|
||||
private readonly float _maxY;
|
||||
private readonly SensorMonitoringWindow _parentWindow;
|
||||
|
||||
public GraphView(Queue<SensorSample> samples,
|
||||
TimeSpan startTime,
|
||||
TimeSpan curTime,
|
||||
float maxY,
|
||||
SensorMonitoringWindow parentWindow)
|
||||
public GraphView(Queue<SensorSample> samples, TimeSpan startTime, TimeSpan curTime, float maxY)
|
||||
{
|
||||
_samples = samples;
|
||||
_startTime = startTime;
|
||||
_curTime = curTime;
|
||||
_maxY = maxY;
|
||||
RectClipContent = true;
|
||||
_parentWindow = parentWindow;
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
base.Draw(handle);
|
||||
|
||||
var window = (float)(_curTime - _startTime).TotalSeconds;
|
||||
var window = (float) (_curTime - _startTime).TotalSeconds;
|
||||
|
||||
// TODO: omg this is terrible don't fucking hardcode this size to something uncached huge omfg.
|
||||
var vertices = new Vector2[25000];
|
||||
var countVtx = 0;
|
||||
|
||||
var lastPoint = new Vector2(float.NaN, float.NaN);
|
||||
var requiredVertices = 6 * (_samples.Count - 1);
|
||||
|
||||
var vertices = _parentWindow.GetSharedVertices(requiredVertices);
|
||||
|
||||
foreach (var (time, sample) in _samples)
|
||||
{
|
||||
var relTime = (float)(time - _startTime).TotalSeconds;
|
||||
var relTime = (float) (time - _startTime).TotalSeconds;
|
||||
|
||||
var posY = PixelHeight - (sample / _maxY) * PixelHeight;
|
||||
var posX = (relTime / window) * PixelWidth;
|
||||
@@ -271,9 +242,8 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
|
||||
|
||||
lastPoint = newPoint;
|
||||
}
|
||||
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList,
|
||||
vertices.AsSpan(0, countVtx),
|
||||
Color.White.WithAlpha(0.1f));
|
||||
|
||||
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList, vertices.AsSpan(0, countVtx), Color.White.WithAlpha(0.1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
using Content.Shared.StatusEffectNew;
|
||||
using Content.Shared.StatusEffectNew.Components;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Client.StatusEffectNew;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public sealed partial class ClientStatusEffectsSystem : SharedStatusEffectsSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<StatusEffectContainerComponent, ComponentHandleState>(OnHandleState);
|
||||
}
|
||||
|
||||
private void OnHandleState(Entity<StatusEffectContainerComponent> ent, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not StatusEffectContainerComponentState state)
|
||||
return;
|
||||
|
||||
var toRemove = new ValueList<EntityUid>();
|
||||
foreach (var effect in ent.Comp.ActiveStatusEffects)
|
||||
{
|
||||
if (state.ActiveStatusEffects.Contains(GetNetEntity(effect)))
|
||||
continue;
|
||||
|
||||
toRemove.Add(effect);
|
||||
}
|
||||
|
||||
foreach (var effect in toRemove)
|
||||
{
|
||||
ent.Comp.ActiveStatusEffects.Remove(effect);
|
||||
var ev = new StatusEffectRemovedEvent(ent);
|
||||
RaiseLocalEvent(effect, ref ev);
|
||||
}
|
||||
|
||||
foreach (var effect in state.ActiveStatusEffects)
|
||||
{
|
||||
var effectUid = GetEntity(effect);
|
||||
if (ent.Comp.ActiveStatusEffects.Contains(effectUid))
|
||||
continue;
|
||||
|
||||
ent.Comp.ActiveStatusEffects.Add(effectUid);
|
||||
var ev = new StatusEffectAppliedEvent(ent);
|
||||
RaiseLocalEvent(effectUid, ref ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,15 +68,11 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem
|
||||
|
||||
foreach (var hand in _hands.EnumerateHands(player.Value))
|
||||
{
|
||||
if (!_hands.TryGetHeldItem(player.Value, hand, out var heldEntity))
|
||||
continue;
|
||||
|
||||
if (!scannerQuery.TryGetComponent(heldEntity, out var heldScanner) || !heldScanner.Enabled)
|
||||
if (!scannerQuery.TryGetComponent(hand.HeldEntity, out var heldScanner) || !heldScanner.Enabled)
|
||||
continue;
|
||||
|
||||
range = MathF.Max(heldScanner.Range, range);
|
||||
canSee = true;
|
||||
break;
|
||||
}
|
||||
|
||||
inRange = new HashSet<Entity<SubFloorHideComponent>>();
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Content.Client.Tabletop
|
||||
// Get the camera entity that the server has created for us
|
||||
var camera = GetEntity(msg.CameraUid);
|
||||
|
||||
if (!TryComp<EyeComponent>(camera, out var eyeComponent))
|
||||
if (!EntityManager.TryGetComponent<EyeComponent>(camera, out var eyeComponent))
|
||||
{
|
||||
// If there is no eye, print error and do not open any window
|
||||
Log.Error("Camera entity does not have eye component!");
|
||||
@@ -258,7 +258,7 @@ namespace Content.Client.Tabletop
|
||||
private void StopDragging(bool broadcast = true)
|
||||
{
|
||||
// Set the dragging player on the component to noone
|
||||
if (broadcast && _draggedEntity != null && HasComp<TabletopDraggableComponent>(_draggedEntity.Value))
|
||||
if (broadcast && _draggedEntity != null && EntityManager.HasComponent<TabletopDraggableComponent>(_draggedEntity.Value))
|
||||
{
|
||||
RaisePredictiveEvent(new TabletopMoveEvent(GetNetEntity(_draggedEntity.Value), Transforms.GetMapCoordinates(_draggedEntity.Value), GetNetEntity(_table!.Value)));
|
||||
RaisePredictiveEvent(new TabletopDraggingPlayerChangedEvent(GetNetEntity(_draggedEntity.Value), false));
|
||||
|
||||
@@ -98,8 +98,7 @@ public sealed class AlertsUIController : UIController, IOnStateEntered<GameplayS
|
||||
if (!EntityManager.TryGetComponent<SpriteComponent>(spriteViewEnt, out var sprite))
|
||||
return;
|
||||
|
||||
var ev = new UpdateAlertSpriteEvent((spriteViewEnt, sprite), player, alert);
|
||||
var ev = new UpdateAlertSpriteEvent((spriteViewEnt, sprite), alert);
|
||||
EntityManager.EventBus.RaiseLocalEvent(player, ref ev);
|
||||
EntityManager.EventBus.RaiseLocalEvent(spriteViewEnt, ref ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,15 +57,10 @@ namespace Content.Client.UserInterface.Systems.Alerts.Controls
|
||||
_sprite = _entityManager.System<SpriteSystem>();
|
||||
TooltipSupplier = SupplyTooltip;
|
||||
Alert = alert;
|
||||
|
||||
HorizontalAlignment = HAlignment.Left;
|
||||
_severity = severity;
|
||||
_icon = new SpriteView
|
||||
{
|
||||
Scale = new Vector2(2, 2),
|
||||
MaxSize = new Vector2(64, 64),
|
||||
Stretch = SpriteView.StretchMode.None,
|
||||
HorizontalAlignment = HAlignment.Left
|
||||
Scale = new Vector2(2, 2)
|
||||
};
|
||||
|
||||
SetupIcon();
|
||||
|
||||
@@ -207,9 +207,7 @@ public sealed class GasTankWindow
|
||||
_btnInternals.Disabled = !canConnectInternals;
|
||||
_lblInternals.SetMarkup(Loc.GetString("gas-tank-window-internal-text",
|
||||
("status", Loc.GetString(internalsConnected ? "gas-tank-window-internal-connected" : "gas-tank-window-internal-disconnected"))));
|
||||
if (!_spbPressure.HasKeyboardFocus())
|
||||
// Don't update release pressure if we're currently editing it
|
||||
_spbPressure.Value = outputPressure;
|
||||
_spbPressure.Value = outputPressure;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
|
||||
@@ -7,7 +7,6 @@ using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Inventory.VirtualItem;
|
||||
using Content.Shared.Timing;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
@@ -29,7 +28,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
private readonly Dictionary<string, int> _handContainerIndices = new();
|
||||
private readonly Dictionary<string, HandButton> _handLookup = new();
|
||||
private HandsComponent? _playerHandsComponent;
|
||||
private HandButton? _activeHand;
|
||||
private HandButton? _activeHand = null;
|
||||
|
||||
// We only have two item status controls (left and right hand),
|
||||
// but we may have more than two hands.
|
||||
@@ -39,7 +38,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
private HandButton? _statusHandLeft;
|
||||
private HandButton? _statusHandRight;
|
||||
|
||||
private int _backupSuffix; //this is used when autogenerating container names if they don't have names
|
||||
private int _backupSuffix = 0; //this is used when autogenerating container names if they don't have names
|
||||
|
||||
private HotbarGui? HandsGui => UIManager.GetActiveUIWidgetOrNull<HotbarGui>();
|
||||
|
||||
@@ -49,7 +48,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
_handsSystem.OnPlayerItemAdded += OnItemAdded;
|
||||
_handsSystem.OnPlayerItemRemoved += OnItemRemoved;
|
||||
_handsSystem.OnPlayerSetActiveHand += SetActiveHand;
|
||||
_handsSystem.OnPlayerRemoveHand += OnRemoveHand;
|
||||
_handsSystem.OnPlayerRemoveHand += RemoveHand;
|
||||
_handsSystem.OnPlayerHandsAdded += LoadPlayerHands;
|
||||
_handsSystem.OnPlayerHandsRemoved += UnloadPlayerHands;
|
||||
_handsSystem.OnPlayerHandBlocked += HandBlocked;
|
||||
@@ -62,35 +61,28 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
_handsSystem.OnPlayerItemAdded -= OnItemAdded;
|
||||
_handsSystem.OnPlayerItemRemoved -= OnItemRemoved;
|
||||
_handsSystem.OnPlayerSetActiveHand -= SetActiveHand;
|
||||
_handsSystem.OnPlayerRemoveHand -= OnRemoveHand;
|
||||
_handsSystem.OnPlayerRemoveHand -= RemoveHand;
|
||||
_handsSystem.OnPlayerHandsAdded -= LoadPlayerHands;
|
||||
_handsSystem.OnPlayerHandsRemoved -= UnloadPlayerHands;
|
||||
_handsSystem.OnPlayerHandBlocked -= HandBlocked;
|
||||
_handsSystem.OnPlayerHandUnblocked -= HandUnblocked;
|
||||
}
|
||||
|
||||
private void OnAddHand(Entity<HandsComponent> entity, string name, HandLocation location)
|
||||
private void OnAddHand(string name, HandLocation location)
|
||||
{
|
||||
if (entity.Owner != _player.LocalEntity)
|
||||
return;
|
||||
AddHand(name, location);
|
||||
}
|
||||
|
||||
private void OnRemoveHand(Entity<HandsComponent> entity, string name)
|
||||
{
|
||||
if (entity.Owner != _player.LocalEntity)
|
||||
return;
|
||||
RemoveHand(name);
|
||||
}
|
||||
|
||||
private void HandPressed(GUIBoundKeyEventArgs args, SlotControl hand)
|
||||
{
|
||||
if (!_handsSystem.TryGetPlayerHands(out var hands))
|
||||
if (_playerHandsComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Function == EngineKeyFunctions.UIClick)
|
||||
{
|
||||
_handsSystem.UIHandClick(hands.Value, hand.SlotName);
|
||||
_handsSystem.UIHandClick(_playerHandsComponent, hand.SlotName);
|
||||
args.Handle();
|
||||
}
|
||||
else if (args.Function == EngineKeyFunctions.UseSecondary)
|
||||
@@ -130,33 +122,33 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPlayerHands(Entity<HandsComponent> handsComp)
|
||||
private void LoadPlayerHands(HandsComponent handsComp)
|
||||
{
|
||||
DebugTools.Assert(_playerHandsComponent == null);
|
||||
if (HandsGui != null)
|
||||
HandsGui.Visible = true;
|
||||
|
||||
_playerHandsComponent = handsComp;
|
||||
foreach (var (name, hand) in handsComp.Comp.Hands)
|
||||
foreach (var (name, hand) in handsComp.Hands)
|
||||
{
|
||||
var handButton = AddHand(name, hand.Location);
|
||||
|
||||
if (_handsSystem.TryGetHeldItem(handsComp.AsNullable(), name, out var held) &&
|
||||
_entities.TryGetComponent(held, out VirtualItemComponent? virt))
|
||||
if (_entities.TryGetComponent(hand.HeldEntity, out VirtualItemComponent? virt))
|
||||
{
|
||||
handButton.SetEntity(virt.BlockingEntity);
|
||||
handButton.Blocked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
handButton.SetEntity(held);
|
||||
handButton.SetEntity(hand.HeldEntity);
|
||||
handButton.Blocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (handsComp.Comp.ActiveHandId == null)
|
||||
var activeHand = handsComp.ActiveHand;
|
||||
if (activeHand == null)
|
||||
return;
|
||||
SetActiveHand(handsComp.Comp.ActiveHandId);
|
||||
SetActiveHand(activeHand.Name);
|
||||
}
|
||||
|
||||
private void HandBlocked(string handName)
|
||||
@@ -268,21 +260,19 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
if (HandsGui != null &&
|
||||
_playerHandsComponent != null &&
|
||||
_player.LocalSession?.AttachedEntity is { } playerEntity &&
|
||||
_handsSystem.TryGetHand((playerEntity, _playerHandsComponent), handName, out var hand))
|
||||
_handsSystem.TryGetHand(playerEntity, handName, out var hand, _playerHandsComponent))
|
||||
{
|
||||
var heldEnt = _handsSystem.GetHeldItem((playerEntity, _playerHandsComponent), handName);
|
||||
|
||||
var foldedLocation = hand.Value.Location.GetUILocation();
|
||||
var foldedLocation = hand.Location.GetUILocation();
|
||||
if (foldedLocation == HandUILocation.Left)
|
||||
{
|
||||
_statusHandLeft = handControl;
|
||||
HandsGui.UpdatePanelEntityLeft(heldEnt);
|
||||
HandsGui.UpdatePanelEntityLeft(hand.HeldEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Middle or right
|
||||
_statusHandRight = handControl;
|
||||
HandsGui.UpdatePanelEntityRight(heldEnt);
|
||||
HandsGui.UpdatePanelEntityRight(hand.HeldEntity);
|
||||
}
|
||||
|
||||
HandsGui.SetHighlightHand(foldedLocation);
|
||||
@@ -302,7 +292,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
button.Pressed += HandPressed;
|
||||
|
||||
if (!_handLookup.TryAdd(handName, button))
|
||||
return _handLookup[handName];
|
||||
throw new Exception("Tried to add hand with duplicate name to UI. Name:" + handName);
|
||||
|
||||
if (HandsGui != null)
|
||||
{
|
||||
@@ -372,7 +362,6 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
RemoveHand(handName, out _);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
private bool RemoveHand(string handName, out HandButton? handButton)
|
||||
{
|
||||
if (!_handLookup.TryGetValue(handName, out handButton))
|
||||
@@ -388,7 +377,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
_statusHandRight = null;
|
||||
|
||||
_handLookup.Remove(handName);
|
||||
handButton.Orphan();
|
||||
handButton.Dispose();
|
||||
UpdateVisibleStatusPanels();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -329,8 +329,9 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
|
||||
var player = _playerUid;
|
||||
|
||||
if (!control.MouseIsHovering ||
|
||||
player == null ||
|
||||
!_handsSystem.TryGetActiveItem(player.Value, out var held) ||
|
||||
_playerInventory == null ||
|
||||
!_entities.TryGetComponent<HandsComponent>(player, out var hands) ||
|
||||
hands.ActiveHandEntity is not { } held ||
|
||||
!_entities.TryGetComponent(held, out SpriteComponent? sprite) ||
|
||||
!_inventorySystem.TryGetSlotContainer(player.Value, control.SlotName, out var container, out var slotDef))
|
||||
{
|
||||
@@ -341,12 +342,12 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
|
||||
// Set green / red overlay at 50% transparency
|
||||
var hoverEntity = _entities.SpawnEntity("hoverentity", MapCoordinates.Nullspace);
|
||||
var hoverSprite = _entities.GetComponent<SpriteComponent>(hoverEntity);
|
||||
var fits = _inventorySystem.CanEquip(player.Value, held.Value, control.SlotName, out _, slotDef) &&
|
||||
_container.CanInsert(held.Value, container);
|
||||
var fits = _inventorySystem.CanEquip(player.Value, held, control.SlotName, out _, slotDef) &&
|
||||
_container.CanInsert(held, container);
|
||||
|
||||
if (!fits && _entities.TryGetComponent<StorageComponent>(container.ContainedEntity, out var storage))
|
||||
{
|
||||
fits = _entities.System<StorageSystem>().CanInsert(container.ContainedEntity.Value, held.Value, out _, storage);
|
||||
fits = _entities.System<StorageSystem>().CanInsert(container.ContainedEntity.Value, held, out _, storage);
|
||||
}
|
||||
else if (!fits && _entities.TryGetComponent<ItemSlotsComponent>(container.ContainedEntity, out var itemSlots))
|
||||
{
|
||||
@@ -356,14 +357,14 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
|
||||
if (!slot.InsertOnInteract)
|
||||
continue;
|
||||
|
||||
if (!itemSlotsSys.CanInsert(container.ContainedEntity.Value, held.Value, null, slot))
|
||||
if (!itemSlotsSys.CanInsert(container.ContainedEntity.Value, held, null, slot))
|
||||
continue;
|
||||
fits = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_sprite.CopySprite((held.Value, sprite), (hoverEntity, hoverSprite));
|
||||
_sprite.CopySprite((held, sprite), (hoverEntity, hoverSprite));
|
||||
_sprite.SetColor((hoverEntity, hoverSprite), fits ? new Color(0, 255, 0, 127) : new Color(255, 0, 0, 127));
|
||||
|
||||
control.HoverSpriteView.SetEntity(hoverEntity);
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace Content.Client.Verbs
|
||||
// is this a client exclusive (gui) verb?
|
||||
ExecuteVerb(verb, user, GetEntity(target));
|
||||
else
|
||||
RaisePredictiveEvent(new ExecuteVerbEvent(target, verb));
|
||||
EntityManager.RaisePredictiveEvent(new ExecuteVerbEvent(target, verb));
|
||||
}
|
||||
|
||||
private void HandleVerbResponse(VerbsResponseEvent msg)
|
||||
|
||||
@@ -178,7 +178,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down && !gun.BurstActivated)
|
||||
{
|
||||
if (gun.ShotCounter != 0)
|
||||
RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
|
||||
EntityManager.RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
if (mousePos.MapId == MapId.Nullspace)
|
||||
{
|
||||
if (gun.ShotCounter != 0)
|
||||
RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
|
||||
EntityManager.RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
|
||||
Log.Debug($"Sending shoot request tick {Timing.CurTick} / {Timing.CurTime}");
|
||||
|
||||
RaisePredictiveEvent(new RequestShootEvent
|
||||
EntityManager.RaisePredictiveEvent(new RequestShootEvent
|
||||
{
|
||||
Target = target,
|
||||
Coordinates = GetNetCoordinates(coordinates),
|
||||
|
||||
Reference in New Issue
Block a user