Stop network serializing prototypes (#38602)
* Stop network serializing prototypes Send the damn proto ID instead. * Fix sandbox violation
This commit is contained in:
committed by
GitHub
parent
bb7e7c3e5f
commit
73df3b1593
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Client.Administration.Systems;
|
using Content.Client.Administration.Systems;
|
||||||
@@ -24,6 +25,7 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
private readonly EntityLookupSystem _entityLookup;
|
private readonly EntityLookupSystem _entityLookup;
|
||||||
private readonly IUserInterfaceManager _userInterfaceManager;
|
private readonly IUserInterfaceManager _userInterfaceManager;
|
||||||
private readonly SharedRoleSystem _roles;
|
private readonly SharedRoleSystem _roles;
|
||||||
|
private readonly IPrototypeManager _prototypeManager;
|
||||||
private readonly Font _font;
|
private readonly Font _font;
|
||||||
private readonly Font _fontBold;
|
private readonly Font _fontBold;
|
||||||
private AdminOverlayAntagFormat _overlayFormat;
|
private AdminOverlayAntagFormat _overlayFormat;
|
||||||
@@ -36,8 +38,9 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
private float _overlayMergeDistance;
|
private float _overlayMergeDistance;
|
||||||
|
|
||||||
//TODO make this adjustable via GUI?
|
//TODO make this adjustable via GUI?
|
||||||
private readonly ProtoId<RoleTypePrototype>[] _filter =
|
private static readonly FrozenSet<ProtoId<RoleTypePrototype>> Filter =
|
||||||
["SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"];
|
new ProtoId<RoleTypePrototype>[] {"SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"}
|
||||||
|
.ToFrozenSet();
|
||||||
|
|
||||||
private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic");
|
private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic");
|
||||||
|
|
||||||
@@ -49,7 +52,8 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
EntityLookupSystem entityLookup,
|
EntityLookupSystem entityLookup,
|
||||||
IUserInterfaceManager userInterfaceManager,
|
IUserInterfaceManager userInterfaceManager,
|
||||||
IConfigurationManager config,
|
IConfigurationManager config,
|
||||||
SharedRoleSystem roles)
|
SharedRoleSystem roles,
|
||||||
|
IPrototypeManager prototypeManager)
|
||||||
{
|
{
|
||||||
_system = system;
|
_system = system;
|
||||||
_entityManager = entityManager;
|
_entityManager = entityManager;
|
||||||
@@ -57,6 +61,7 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
_entityLookup = entityLookup;
|
_entityLookup = entityLookup;
|
||||||
_userInterfaceManager = userInterfaceManager;
|
_userInterfaceManager = userInterfaceManager;
|
||||||
_roles = roles;
|
_roles = roles;
|
||||||
|
_prototypeManager = prototypeManager;
|
||||||
ZIndex = 200;
|
ZIndex = 200;
|
||||||
// Setting these to a specific ttf would break the antag symbols
|
// Setting these to a specific ttf would break the antag symbols
|
||||||
_font = resourceCache.NotoStack();
|
_font = resourceCache.NotoStack();
|
||||||
@@ -125,6 +130,14 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
foreach (var info in sortable.OrderBy(s => s.Item4.Y).ToList())
|
foreach (var info in sortable.OrderBy(s => s.Item4.Y).ToList())
|
||||||
{
|
{
|
||||||
var playerInfo = info.Item1;
|
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 aabb = info.Item2;
|
||||||
var entity = info.Item3;
|
var entity = info.Item3;
|
||||||
var screenCoordinatesCenter = info.Item4;
|
var screenCoordinatesCenter = info.Item4;
|
||||||
@@ -209,7 +222,7 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
switch (_overlaySymbolStyle)
|
switch (_overlaySymbolStyle)
|
||||||
{
|
{
|
||||||
case AdminOverlayAntagSymbolStyle.Specific:
|
case AdminOverlayAntagSymbolStyle.Specific:
|
||||||
symbol = playerInfo.RoleProto.Symbol;
|
symbol = roleSymbol;
|
||||||
break;
|
break;
|
||||||
case AdminOverlayAntagSymbolStyle.Basic:
|
case AdminOverlayAntagSymbolStyle.Basic:
|
||||||
symbol = Loc.GetString("player-tab-antag-prefix");
|
symbol = Loc.GetString("player-tab-antag-prefix");
|
||||||
@@ -225,17 +238,17 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
switch (_overlayFormat)
|
switch (_overlayFormat)
|
||||||
{
|
{
|
||||||
case AdminOverlayAntagFormat.Roletype:
|
case AdminOverlayAntagFormat.Roletype:
|
||||||
color = playerInfo.RoleProto.Color;
|
color = roleColor;
|
||||||
symbol = _filter.Contains(playerInfo.RoleProto) ? symbol : string.Empty;
|
symbol = IsFiltered(playerInfo.RoleProto) ? symbol : string.Empty;
|
||||||
text = _filter.Contains(playerInfo.RoleProto)
|
text = IsFiltered(playerInfo.RoleProto)
|
||||||
? Loc.GetString(playerInfo.RoleProto.Name).ToUpper()
|
? roleName.ToUpper()
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
break;
|
break;
|
||||||
case AdminOverlayAntagFormat.Subtype:
|
case AdminOverlayAntagFormat.Subtype:
|
||||||
color = playerInfo.RoleProto.Color;
|
color = roleColor;
|
||||||
symbol = _filter.Contains(playerInfo.RoleProto) ? symbol : string.Empty;
|
symbol = IsFiltered(playerInfo.RoleProto) ? symbol : string.Empty;
|
||||||
text = _filter.Contains(playerInfo.RoleProto)
|
text = IsFiltered(playerInfo.RoleProto)
|
||||||
? _roles.GetRoleSubtypeLabel(playerInfo.RoleProto.Name, playerInfo.Subtype).ToUpper()
|
? _roles.GetRoleSubtypeLabel(roleName, playerInfo.Subtype).ToUpper()
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -258,4 +271,12 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
drawnOverlays.Add((screenCoordinatesCenter, currentOffset));
|
drawnOverlays.Add((screenCoordinatesCenter, currentOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsFiltered(ProtoId<RoleTypePrototype>? roleProtoId)
|
||||||
|
{
|
||||||
|
if (roleProtoId == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return Filter.Contains(roleProtoId.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Robust.Client.Graphics;
|
|||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client.Administration.Systems
|
namespace Content.Client.Administration.Systems
|
||||||
{
|
{
|
||||||
@@ -17,6 +18,7 @@ namespace Content.Client.Administration.Systems
|
|||||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||||
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
|
|
||||||
private AdminNameOverlay _adminNameOverlay = default!;
|
private AdminNameOverlay _adminNameOverlay = default!;
|
||||||
|
|
||||||
@@ -33,7 +35,8 @@ namespace Content.Client.Administration.Systems
|
|||||||
_entityLookup,
|
_entityLookup,
|
||||||
_userInterfaceManager,
|
_userInterfaceManager,
|
||||||
_configurationManager,
|
_configurationManager,
|
||||||
_roles);
|
_roles,
|
||||||
|
_proto);
|
||||||
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
|
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.Mind;
|
||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
||||||
|
|
||||||
@@ -11,6 +13,7 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
|||||||
public sealed partial class PlayerTabEntry : PanelContainer
|
public sealed partial class PlayerTabEntry : PanelContainer
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
|
||||||
public PlayerTabEntry(
|
public PlayerTabEntry(
|
||||||
PlayerInfo player,
|
PlayerInfo player,
|
||||||
@@ -23,6 +26,8 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
|||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
var roles = _entMan.System<SharedRoleSystem>();
|
var roles = _entMan.System<SharedRoleSystem>();
|
||||||
|
|
||||||
|
var rolePrototype = player.RoleProto == null ? null : _prototype.Index(player.RoleProto.Value);
|
||||||
|
|
||||||
UsernameLabel.Text = player.Username;
|
UsernameLabel.Text = player.Username;
|
||||||
if (!player.Connected)
|
if (!player.Connected)
|
||||||
UsernameLabel.StyleClasses.Add("Disabled");
|
UsernameLabel.StyleClasses.Add("Disabled");
|
||||||
@@ -57,19 +62,19 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case AdminPlayerTabSymbolOption.Specific:
|
case AdminPlayerTabSymbolOption.Specific:
|
||||||
symbol = player.Antag ? player.RoleProto.Symbol : string.Empty;
|
symbol = player.Antag ? rolePrototype?.Symbol ?? RoleTypePrototype.FallbackSymbol : string.Empty;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterLabel.Text = Loc.GetString("player-tab-character-name-antag-symbol", ("symbol", symbol), ("name", player.CharacterName));
|
CharacterLabel.Text = Loc.GetString("player-tab-character-name-antag-symbol", ("symbol", symbol), ("name", player.CharacterName));
|
||||||
|
|
||||||
if (player.Antag && colorAntags)
|
if (player.Antag && colorAntags)
|
||||||
CharacterLabel.FontColorOverride = player.RoleProto.Color;
|
CharacterLabel.FontColorOverride = rolePrototype?.Color ?? RoleTypePrototype.FallbackColor;
|
||||||
if (player.IdentityName != player.CharacterName)
|
if (player.IdentityName != player.CharacterName)
|
||||||
CharacterLabel.Text += $" [{player.IdentityName}]";
|
CharacterLabel.Text += $" [{player.IdentityName}]";
|
||||||
|
|
||||||
var roletype = RoleTypeLabel.Text = Loc.GetString(player.RoleProto.Name);
|
var roletype = RoleTypeLabel.Text = Loc.GetString(rolePrototype?.Name ?? RoleTypePrototype.FallbackName);
|
||||||
var subtype = roles.GetRoleSubtypeLabel(player.RoleProto.Name, player.Subtype);
|
var subtype = roles.GetRoleSubtypeLabel(rolePrototype?.Name ?? RoleTypePrototype.FallbackName, player.Subtype);
|
||||||
switch (roleSetting)
|
switch (roleSetting)
|
||||||
{
|
{
|
||||||
case AdminPlayerTabRoleTypeOption.RoleTypeSubtype:
|
case AdminPlayerTabRoleTypeOption.RoleTypeSubtype:
|
||||||
@@ -92,7 +97,7 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (colorRoles)
|
if (colorRoles)
|
||||||
RoleTypeLabel.FontColorOverride = player.RoleProto.Color;
|
RoleTypeLabel.FontColorOverride = rolePrototype?.Color ?? RoleTypePrototype.FallbackColor;
|
||||||
BackgroundColorPanel.PanelOverride = styleBoxFlat;
|
BackgroundColorPanel.PanelOverride = styleBoxFlat;
|
||||||
OverallPlaytimeLabel.Text = player.PlaytimeString;
|
OverallPlaytimeLabel.Text = player.PlaytimeString;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Numerics;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using Content.Client.UserInterface.Controls;
|
using Content.Client.UserInterface.Controls;
|
||||||
using Content.Shared.DeviceLinking;
|
using Content.Shared.DeviceLinking;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
@@ -14,6 +15,8 @@ namespace Content.Client.NetworkConfigurator;
|
|||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
||||||
{
|
{
|
||||||
|
private readonly IPrototypeManager _prototypeManager = null!;
|
||||||
|
|
||||||
private const string PanelBgColor = "#202023";
|
private const string PanelBgColor = "#202023";
|
||||||
|
|
||||||
private readonly LinksRender _links;
|
private readonly LinksRender _links;
|
||||||
@@ -33,6 +36,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
|||||||
public NetworkConfiguratorLinkMenu()
|
public NetworkConfiguratorLinkMenu()
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
var footerStyleBox = new StyleBoxFlat()
|
var footerStyleBox = new StyleBoxFlat()
|
||||||
{
|
{
|
||||||
@@ -61,7 +65,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
|||||||
ButtonContainerRight.RemoveAllChildren();
|
ButtonContainerRight.RemoveAllChildren();
|
||||||
|
|
||||||
_sources.Clear();
|
_sources.Clear();
|
||||||
_sources.AddRange(linkState.Sources);
|
_sources.AddRange(linkState.Sources.Select(s => _prototypeManager.Index(s)));
|
||||||
_links.SourceButtons.Clear();
|
_links.SourceButtons.Clear();
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var source in _sources)
|
foreach (var source in _sources)
|
||||||
@@ -73,7 +77,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
_sinks.Clear();
|
_sinks.Clear();
|
||||||
_sinks.AddRange(linkState.Sinks);
|
_sinks.AddRange(linkState.Sinks.Select(s => _prototypeManager.Index(s)));
|
||||||
_links.SinkButtons.Clear();
|
_links.SinkButtons.Clear();
|
||||||
i = 0;
|
i = 0;
|
||||||
foreach (var sink in _sinks)
|
foreach (var sink in _sinks)
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ using Content.Shared.Administration.Logs;
|
|||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
|
using Content.Shared.Mind;
|
||||||
using Content.Shared.Players.PlayTimeTracking;
|
using Content.Shared.Players.PlayTimeTracking;
|
||||||
using Prometheus;
|
using Prometheus;
|
||||||
using Robust.Shared;
|
using Robust.Shared;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Reflection;
|
using Robust.Shared.Reflection;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -33,6 +35,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
[Dependency] private readonly ISharedPlayerManager _player = default!;
|
[Dependency] private readonly ISharedPlayerManager _player = default!;
|
||||||
[Dependency] private readonly ISharedPlaytimeManager _playtime = default!;
|
[Dependency] private readonly ISharedPlaytimeManager _playtime = default!;
|
||||||
[Dependency] private readonly ISharedChatManager _chat = default!;
|
[Dependency] private readonly ISharedChatManager _chat = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
|
|
||||||
public const string SawmillId = "admin.logs";
|
public const string SawmillId = "admin.logs";
|
||||||
|
|
||||||
@@ -330,7 +333,8 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
var cachedInfo = adminSys.GetCachedPlayerInfo(new NetUserId(id));
|
var cachedInfo = adminSys.GetCachedPlayerInfo(new NetUserId(id));
|
||||||
if (cachedInfo != null && cachedInfo.Antag)
|
if (cachedInfo != null && cachedInfo.Antag)
|
||||||
{
|
{
|
||||||
var subtype = Loc.GetString(cachedInfo.Subtype ?? cachedInfo.RoleProto.Name);
|
var proto = cachedInfo.RoleProto == null ? null : _proto.Index(cachedInfo.RoleProto.Value);
|
||||||
|
var subtype = Loc.GetString(cachedInfo.Subtype ?? proto?.Name ?? RoleTypePrototype.FallbackName);
|
||||||
logMessage = Loc.GetString(
|
logMessage = Loc.GetString(
|
||||||
"admin-alert-antag-label",
|
"admin-alert-antag-label",
|
||||||
("message", logMessage),
|
("message", logMessage),
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ public sealed class AdminSystem : EntitySystem
|
|||||||
var antag = false;
|
var antag = false;
|
||||||
|
|
||||||
// Starting role, antagonist status and role type
|
// Starting role, antagonist status and role type
|
||||||
RoleTypePrototype roleType = new();
|
RoleTypePrototype? roleType = null;
|
||||||
var startingRole = string.Empty;
|
var startingRole = string.Empty;
|
||||||
LocId? subtype = null;
|
LocId? subtype = null;
|
||||||
if (_minds.TryGetMind(session, out var mindId, out var mindComp) && mindComp is not null)
|
if (_minds.TryGetMind(session, out var mindId, out var mindComp) && mindComp is not null)
|
||||||
@@ -244,7 +244,7 @@ public sealed class AdminSystem : EntitySystem
|
|||||||
subtype = mindComp.Subtype;
|
subtype = mindComp.Subtype;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Log.Error($"{ToPrettyString(mindId)} has invalid Role Type '{mindComp.RoleType}'. Displaying '{Loc.GetString(roleType.Name)}' instead");
|
Log.Error($"{ToPrettyString(mindId)} has invalid Role Type '{mindComp.RoleType}'. Displaying '{Loc.GetString(RoleTypePrototype.FallbackName)}' instead");
|
||||||
|
|
||||||
antag = _role.MindIsAntagonist(mindId);
|
antag = _role.MindIsAntagonist(mindId);
|
||||||
startingRole = _jobs.MindTryGetJobName(mindId);
|
startingRole = _jobs.MindTryGetJobName(mindId);
|
||||||
@@ -270,7 +270,7 @@ public sealed class AdminSystem : EntitySystem
|
|||||||
identityName,
|
identityName,
|
||||||
startingRole,
|
startingRole,
|
||||||
antag,
|
antag,
|
||||||
roleType,
|
roleType?.ID,
|
||||||
subtype,
|
subtype,
|
||||||
sortWeight,
|
sortWeight,
|
||||||
GetNetEntity(session?.AttachedEntity),
|
GetNetEntity(session?.AttachedEntity),
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Robust.Server.Audio;
|
|||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Map.Events;
|
using Robust.Shared.Map.Events;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
@@ -496,14 +497,15 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var sources = _deviceLinkSystem.GetSourcePorts(sourceUid, sourceComponent);
|
var sources = _deviceLinkSystem.GetSourcePorts(sourceUid, sourceComponent);
|
||||||
var sinks = _deviceLinkSystem.GetSinkPorts(sinkUid, sinkComponent);
|
var sinks = _deviceLinkSystem.GetSinkPortIds((sinkUid, sinkComponent));
|
||||||
var links = _deviceLinkSystem.GetLinks(sourceUid, sinkUid, sourceComponent);
|
var links = _deviceLinkSystem.GetLinks(sourceUid, sinkUid, sourceComponent);
|
||||||
var defaults = _deviceLinkSystem.GetDefaults(sources);
|
var defaults = _deviceLinkSystem.GetDefaults(sources);
|
||||||
|
var sourceIds = sources.Select(s => (ProtoId<SourcePortPrototype>)s.ID).ToArray();
|
||||||
|
|
||||||
var sourceAddress = Resolve(sourceUid, ref sourceNetworkComponent, false) ? sourceNetworkComponent.Address : "";
|
var sourceAddress = Resolve(sourceUid, ref sourceNetworkComponent, false) ? sourceNetworkComponent.Address : "";
|
||||||
var sinkAddress = Resolve(sinkUid, ref sinkNetworkComponent, false) ? sinkNetworkComponent.Address : "";
|
var sinkAddress = Resolve(sinkUid, ref sinkNetworkComponent, false) ? sinkNetworkComponent.Address : "";
|
||||||
|
|
||||||
var state = new DeviceLinkUserInterfaceState(sources, sinks, links, sourceAddress, sinkAddress, defaults);
|
var state = new DeviceLinkUserInterfaceState(sourceIds, sinks, links, sourceAddress, sinkAddress, defaults);
|
||||||
_uiSystem.SetUiState(configuratorUid, NetworkConfiguratorUiKey.Link, state);
|
_uiSystem.SetUiState(configuratorUid, NetworkConfiguratorUiKey.Link, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Content.Server.Chat.Systems;
|
|||||||
using Content.Server.Speech.Components;
|
using Content.Server.Speech.Components;
|
||||||
using Content.Shared.Chat.Prototypes;
|
using Content.Shared.Chat.Prototypes;
|
||||||
using Content.Shared.Speech.Components;
|
using Content.Shared.Speech.Components;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Speech.EntitySystems;
|
namespace Content.Server.Speech.EntitySystems;
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ public sealed class MumbleAccentSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly ChatSystem _chat = default!;
|
[Dependency] private readonly ChatSystem _chat = default!;
|
||||||
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
|
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -23,10 +25,14 @@ public sealed class MumbleAccentSystem : EntitySystem
|
|||||||
if (args.Handled || !args.Emote.Category.HasFlag(EmoteCategory.Vocal))
|
if (args.Handled || !args.Emote.Category.HasFlag(EmoteCategory.Vocal))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryComp<VocalComponent>(ent.Owner, out var vocalComp))
|
if (TryComp<VocalComponent>(ent.Owner, out var vocalComp) && vocalComp.EmoteSounds is { } sounds)
|
||||||
{
|
{
|
||||||
// play a muffled version of the vocal emote
|
// play a muffled version of the vocal emote
|
||||||
args.Handled = _chat.TryPlayEmoteSound(ent.Owner, vocalComp.EmoteSounds, args.Emote, ent.Comp.EmoteAudioParams);
|
args.Handled = _chat.TryPlayEmoteSound(
|
||||||
|
ent.Owner,
|
||||||
|
_prototype.Index(sounds),
|
||||||
|
args.Emote,
|
||||||
|
ent.Comp.EmoteAudioParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,11 @@ public sealed class VocalSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (component.EmoteSounds is not { } sounds)
|
||||||
|
return;
|
||||||
|
|
||||||
// just play regular sound based on emote proto
|
// just play regular sound based on emote proto
|
||||||
args.Handled = _chat.TryPlayEmoteSound(uid, component.EmoteSounds, args.Emote);
|
args.Handled = _chat.TryPlayEmoteSound(uid, _proto.Index(sounds), args.Emote);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScreamAction(EntityUid uid, VocalComponent component, ScreamActionEvent args)
|
private void OnScreamAction(EntityUid uid, VocalComponent component, ScreamActionEvent args)
|
||||||
@@ -85,7 +88,10 @@ public sealed class VocalSystem : EntitySystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _chat.TryPlayEmoteSound(uid, component.EmoteSounds, component.ScreamId);
|
if (component.EmoteSounds is not { } sounds)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _chat.TryPlayEmoteSound(uid, _proto.Index(sounds), component.ScreamId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadSounds(EntityUid uid, VocalComponent component, Sex? sex = null)
|
private void LoadSounds(EntityUid uid, VocalComponent component, Sex? sex = null)
|
||||||
@@ -97,6 +103,10 @@ public sealed class VocalSystem : EntitySystem
|
|||||||
|
|
||||||
if (!component.Sounds.TryGetValue(sex.Value, out var protoId))
|
if (!component.Sounds.TryGetValue(sex.Value, out var protoId))
|
||||||
return;
|
return;
|
||||||
_proto.TryIndex(protoId, out component.EmoteSounds);
|
|
||||||
|
if (!_proto.HasIndex(protoId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
component.EmoteSounds = protoId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Shared.Mind;
|
using Content.Shared.Mind;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Administration;
|
namespace Content.Shared.Administration;
|
||||||
@@ -11,7 +12,7 @@ public sealed record PlayerInfo(
|
|||||||
string IdentityName,
|
string IdentityName,
|
||||||
string StartingJob,
|
string StartingJob,
|
||||||
bool Antag,
|
bool Antag,
|
||||||
RoleTypePrototype RoleProto,
|
ProtoId<RoleTypePrototype>? RoleProto,
|
||||||
LocId? Subtype,
|
LocId? Subtype,
|
||||||
int SortWeight,
|
int SortWeight,
|
||||||
NetEntity? NetEntity,
|
NetEntity? NetEntity,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Content.Shared.Cargo.Prototypes;
|
|||||||
/// that must be sold together in a labeled container in order
|
/// that must be sold together in a labeled container in order
|
||||||
/// to receive a monetary reward.
|
/// to receive a monetary reward.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype, Serializable, NetSerializable]
|
[Prototype]
|
||||||
public sealed partial class CargoBountyPrototype : IPrototype
|
public sealed partial class CargoBountyPrototype : IPrototype
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Content.Shared.Chat.Prototypes;
|
|||||||
/// Sounds collection for each <see cref="EmotePrototype"/>.
|
/// Sounds collection for each <see cref="EmotePrototype"/>.
|
||||||
/// Different entities may use different sounds collections.
|
/// Different entities may use different sounds collections.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype, Serializable, NetSerializable]
|
[Prototype]
|
||||||
public sealed partial class EmoteSoundsPrototype : IPrototype
|
public sealed partial class EmoteSoundsPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[IdDataField]
|
[IdDataField]
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace Content.Shared.Damage.Prototypes
|
|||||||
/// cref="DamageableComponent"/> should support.
|
/// cref="DamageableComponent"/> should support.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class DamageContainerPrototype : IPrototype
|
public sealed partial class DamageContainerPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace Content.Shared.Damage.Prototypes
|
|||||||
/// to change/get/set damage in a <see cref="DamageableComponent"/>.
|
/// to change/get/set damage in a <see cref="DamageableComponent"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[Prototype(2)]
|
[Prototype(2)]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class DamageGroupPrototype : IPrototype
|
public sealed partial class DamageGroupPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[IdDataField] public string ID { get; private set; } = default!;
|
[IdDataField] public string ID { get; private set; } = default!;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Content.Shared.DeviceLinking;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A prototype for a device port, for use with device linking.
|
/// A prototype for a device port, for use with device linking.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public abstract class DevicePortPrototype
|
public abstract class DevicePortPrototype
|
||||||
{
|
{
|
||||||
[IdDataField]
|
[IdDataField]
|
||||||
@@ -28,13 +27,11 @@ public abstract class DevicePortPrototype
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class SinkPortPrototype : DevicePortPrototype, IPrototype
|
public sealed partial class SinkPortPrototype : DevicePortPrototype, IPrototype
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class SourcePortPrototype : DevicePortPrototype, IPrototype
|
public sealed partial class SourcePortPrototype : DevicePortPrototype, IPrototype
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Linq;
|
||||||
using Content.Shared.Administration.Logs;
|
using Content.Shared.Administration.Logs;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.DeviceLinking.Events;
|
using Content.Shared.DeviceLinking.Events;
|
||||||
@@ -142,6 +143,11 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProtoId<SourcePortPrototype>[] GetSourcePortIds(Entity<DeviceLinkSourceComponent> source)
|
||||||
|
{
|
||||||
|
return source.Comp.Ports.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the available ports from a source
|
/// Retrieves the available ports from a source
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -160,6 +166,11 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
|
|||||||
return sourcePorts;
|
return sourcePorts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProtoId<SinkPortPrototype>[] GetSinkPortIds(Entity<DeviceLinkSinkComponent> source)
|
||||||
|
{
|
||||||
|
return source.Comp.Ports.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the available ports from a sink
|
/// Retrieves the available ports from a sink
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Content.Shared.DeviceNetwork;
|
|||||||
/// A named device network frequency. Useful for ensuring entity prototypes can communicate with each other.
|
/// A named device network frequency. Useful for ensuring entity prototypes can communicate with each other.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class DeviceFrequencyPrototype : IPrototype
|
public sealed partial class DeviceFrequencyPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[IdDataField]
|
[IdDataField]
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ public sealed class DeviceListUserInterfaceState : BoundUserInterfaceState
|
|||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class DeviceLinkUserInterfaceState : BoundUserInterfaceState
|
public sealed class DeviceLinkUserInterfaceState : BoundUserInterfaceState
|
||||||
{
|
{
|
||||||
public readonly List<SourcePortPrototype> Sources;
|
public readonly ProtoId<SourcePortPrototype>[] Sources;
|
||||||
public readonly List<SinkPortPrototype> Sinks;
|
public readonly ProtoId<SinkPortPrototype>[] Sinks;
|
||||||
public readonly HashSet<(ProtoId<SourcePortPrototype> source, ProtoId<SinkPortPrototype> sink)> Links;
|
public readonly HashSet<(ProtoId<SourcePortPrototype> source, ProtoId<SinkPortPrototype> sink)> Links;
|
||||||
public readonly List<(string source, string sink)>? Defaults;
|
public readonly List<(string source, string sink)>? Defaults;
|
||||||
public readonly string SourceAddress;
|
public readonly string SourceAddress;
|
||||||
public readonly string SinkAddress;
|
public readonly string SinkAddress;
|
||||||
|
|
||||||
public DeviceLinkUserInterfaceState(
|
public DeviceLinkUserInterfaceState(
|
||||||
List<SourcePortPrototype> sources,
|
ProtoId<SourcePortPrototype>[] sources,
|
||||||
List<SinkPortPrototype> sinks,
|
ProtoId<SinkPortPrototype>[] sinks,
|
||||||
HashSet<(ProtoId<SourcePortPrototype> source, ProtoId<SinkPortPrototype> sink)> links,
|
HashSet<(ProtoId<SourcePortPrototype> source, ProtoId<SinkPortPrototype> sink)> links,
|
||||||
string sourceAddress,
|
string sourceAddress,
|
||||||
string sinkAddress,
|
string sinkAddress,
|
||||||
|
|||||||
@@ -5,27 +5,31 @@ namespace Content.Shared.Mind;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The core properties of Role Types
|
/// The core properties of Role Types
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype, Serializable]
|
[Prototype]
|
||||||
public sealed partial class RoleTypePrototype : IPrototype
|
public sealed partial class RoleTypePrototype : IPrototype
|
||||||
{
|
{
|
||||||
[IdDataField]
|
[IdDataField]
|
||||||
public string ID { get; private set; } = default!;
|
public string ID { get; private set; } = default!;
|
||||||
|
|
||||||
|
public static readonly LocId FallbackName = "role-type-crew-aligned-name";
|
||||||
|
public const string FallbackSymbol = "";
|
||||||
|
public static readonly Color FallbackColor = Color.FromHex("#eeeeee");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The role's name as displayed on the UI.
|
/// The role's name as displayed on the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public LocId Name = "role-type-crew-aligned-name";
|
public LocId Name = FallbackName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The role's displayed color.
|
/// The role's displayed color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public Color Color = Color.FromHex("#eeeeee");
|
public Color Color = FallbackColor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A symbol used to represent the role type.
|
/// A symbol used to represent the role type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public string Symbol = string.Empty;
|
public string Symbol = FallbackSymbol;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ namespace Content.Shared.Roles;
|
|||||||
/// Describes information for a single antag.
|
/// Describes information for a single antag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class AntagPrototype : IPrototype
|
public sealed partial class AntagPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ public partial class SiliconLaw : IComparable<SiliconLaw>, IEquatable<SiliconLaw
|
|||||||
/// This is a prototype for a law governing the behavior of silicons.
|
/// This is a prototype for a law governing the behavior of silicons.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class SiliconLawPrototype : SiliconLaw, IPrototype
|
public sealed partial class SiliconLawPrototype : SiliconLaw, IPrototype
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public sealed partial class SiliconLawset
|
|||||||
/// This is a prototype for a <see cref="SiliconLawPrototype"/> list.
|
/// This is a prototype for a <see cref="SiliconLawPrototype"/> list.
|
||||||
/// Cannot be used directly since it is a list of prototype ids rather than List<Siliconlaw>.
|
/// Cannot be used directly since it is a list of prototype ids rather than List<Siliconlaw>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype, Serializable, NetSerializable]
|
[Prototype]
|
||||||
public sealed partial class SiliconLawsetPrototype : IPrototype
|
public sealed partial class SiliconLawsetPrototype : IPrototype
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -49,5 +49,5 @@ public sealed partial class VocalComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
[AutoNetworkedField]
|
[AutoNetworkedField]
|
||||||
public EmoteSoundsPrototype? EmoteSounds = null;
|
public ProtoId<EmoteSoundsPrototype>? EmoteSounds = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Content.Shared.Store;
|
|||||||
/// This is separate to the cargo ordering system.
|
/// This is separate to the cargo ordering system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[DataDefinition, Serializable, NetSerializable]
|
[DataDefinition]
|
||||||
public sealed partial class CurrencyPrototype : IPrototype
|
public sealed partial class CurrencyPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
|
|||||||
@@ -242,7 +242,6 @@ public partial class ListingData : IEquatable<ListingData>
|
|||||||
/// Defines a set item listing that is available in a store
|
/// Defines a set item listing that is available in a store
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable]
|
|
||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
public sealed partial class ListingPrototype : ListingData, IPrototype
|
public sealed partial class ListingPrototype : ListingData, IPrototype
|
||||||
{
|
{
|
||||||
@@ -423,7 +422,7 @@ public sealed partial class ListingDataWithCostModifiers : ListingData
|
|||||||
/// how <see cref="StoreDiscountComponent"/> will be filled by respective system.
|
/// how <see cref="StoreDiscountComponent"/> will be filled by respective system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[DataDefinition, Serializable, NetSerializable]
|
[DataDefinition]
|
||||||
public sealed partial class DiscountCategoryPrototype : IPrototype
|
public sealed partial class DiscountCategoryPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Content.Shared.Store;
|
|||||||
/// Used to define different categories for a store.
|
/// Used to define different categories for a store.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype]
|
[Prototype]
|
||||||
[Serializable, NetSerializable, DataDefinition]
|
|
||||||
public sealed partial class StoreCategoryPrototype : IPrototype
|
public sealed partial class StoreCategoryPrototype : IPrototype
|
||||||
{
|
{
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Content.Shared.StoryGen;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prototype for a story template that can be filled in with words chosen from <see cref="DatasetPrototype"/>s.
|
/// Prototype for a story template that can be filled in with words chosen from <see cref="DatasetPrototype"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, Prototype]
|
[Prototype]
|
||||||
public sealed partial class StoryTemplatePrototype : IPrototype
|
public sealed partial class StoryTemplatePrototype : IPrototype
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
|
|||||||
|
|
||||||
namespace Content.Shared.VendingMachines
|
namespace Content.Shared.VendingMachines
|
||||||
{
|
{
|
||||||
[Serializable, NetSerializable, Prototype]
|
[Prototype]
|
||||||
public sealed partial class VendingMachineInventoryPrototype : IPrototype
|
public sealed partial class VendingMachineInventoryPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
|
|||||||
Reference in New Issue
Block a user