Predict BarSignBoundUserinterface (#42364)

fix bar sign prediction
This commit is contained in:
slarticodefast
2026-01-11 23:48:01 +01:00
committed by GitHub
parent a92702e780
commit 4fafb55477
5 changed files with 88 additions and 65 deletions

View File

@@ -1,53 +0,0 @@
using Content.Client.BarSign.Ui;
using Content.Shared.BarSign;
using Content.Shared.Power;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client.BarSign;
public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BarSignComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
}
private void OnAfterAutoHandleState(EntityUid uid, BarSignComponent component, ref AfterAutoHandleStateEvent args)
{
if (_ui.TryGetOpenUi<BarSignBoundUserInterface>(uid, BarSignUiKey.Key, out var bui))
bui.Update(component.Current);
UpdateAppearance(uid, component);
}
protected override void OnAppearanceChange(EntityUid uid, BarSignComponent component, ref AppearanceChangeEvent args)
{
UpdateAppearance(uid, component, args.Component, args.Sprite);
}
private void UpdateAppearance(EntityUid id, BarSignComponent sign, AppearanceComponent? appearance = null, SpriteComponent? sprite = null)
{
if (!Resolve(id, ref appearance, ref sprite))
return;
AppearanceSystem.TryGetData<bool>(id, PowerDeviceVisuals.Powered, out var powered, appearance);
if (powered
&& sign.Current != null
&& _prototypeManager.Resolve(sign.Current, out var proto))
{
SpriteSystem.LayerSetSprite((id, sprite), 0, proto.Icon);
sprite.LayerSetShader(0, "unshaded");
}
else
{
SpriteSystem.LayerSetRsiState((id, sprite), 0, "empty");
sprite.LayerSetShader(0, null, null);
}
}
}

View File

@@ -0,0 +1,30 @@
using Content.Shared.BarSign;
using Content.Shared.Power;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client.BarSign;
public sealed class BarSignVisualizerSystem : VisualizerSystem<BarSignComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
protected override void OnAppearanceChange(EntityUid uid, BarSignComponent component, ref AppearanceChangeEvent args)
{
AppearanceSystem.TryGetData<bool>(uid, PowerDeviceVisuals.Powered, out var powered, args.Component);
AppearanceSystem.TryGetData<string>(uid, BarSignVisuals.BarSignPrototype, out var currentSign, args.Component);
if (powered
&& currentSign != null
&& _prototypeManager.Resolve<BarSignPrototype>(currentSign, out var proto))
{
SpriteSystem.LayerSetSprite((uid, args.Sprite), 0, proto.Icon);
args.Sprite?.LayerSetShader(0, "unshaded");
}
else
{
SpriteSystem.LayerSetRsiState((uid, args.Sprite), 0, "empty");
args.Sprite?.LayerSetShader(0, null, null);
}
}
}

View File

@@ -19,32 +19,27 @@ public sealed class BarSignBoundUserInterface(EntityUid owner, Enum uiKey) : Bou
var sign = EntMan.GetComponentOrNull<BarSignComponent>(Owner)?.Current is { } current
? _prototype.Index(current)
: null;
var allSigns = Shared.BarSign.BarSignSystem.GetAllBarSigns(_prototype)
var allSigns = BarSignSystem.GetAllBarSigns(_prototype)
.OrderBy(p => Loc.GetString(p.Name))
.ToList();
_menu = new(sign, allSigns);
_menu.OnSignSelected += id =>
{
SendMessage(new SetBarSignMessage(id));
SendPredictedMessage(new SetBarSignMessage(id));
};
_menu.OnClose += Close;
_menu.OpenCentered();
}
public void Update(ProtoId<BarSignPrototype>? sign)
public override void Update()
{
if (_prototype.Resolve(sign, out var signPrototype))
_menu?.UpdateState(signPrototype);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
if (!EntMan.TryGetComponent<BarSignComponent>(Owner, out var signComp))
return;
_menu?.Dispose();
if (_prototype.Resolve(signComp.Current, out var signPrototype))
_menu?.UpdateState(signPrototype);
}
}

View File

@@ -4,6 +4,10 @@ using Robust.Shared.Serialization;
namespace Content.Shared.BarSign;
/// <summary>
/// Makes it possible to switch this entity's sprite and name using a BUI.
/// <seealso cref="BarSignPrototype"/>
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class BarSignComponent : Component
{
@@ -14,14 +18,32 @@ public sealed partial class BarSignComponent : Component
public ProtoId<BarSignPrototype>? Current;
}
/// <summary>
/// The key for the BoundUserInterface.
/// </summary>
[Serializable, NetSerializable]
public enum BarSignUiKey : byte
{
Key
}
/// <summary>
/// The enum to be used for appearance data of the bar sign.
/// </summary>
[Serializable, NetSerializable]
public enum BarSignVisuals : byte
{
BarSignPrototype,
}
/// <summary>
/// Send from the client when setting the bar sign.
/// </summary>
[Serializable, NetSerializable]
public sealed class SetBarSignMessage(ProtoId<BarSignPrototype> sign) : BoundUserInterfaceMessage
{
/// <summary>
/// The new prototype to use.
/// </summary>
public ProtoId<BarSignPrototype> Sign = sign;
}

View File

@@ -1,4 +1,5 @@
using System.Linq;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
@@ -9,10 +10,14 @@ public sealed class BarSignSystem : EntitySystem
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
public override void Initialize()
{
SubscribeLocalEvent<BarSignComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<BarSignComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
Subs.BuiEvents<BarSignComponent>(BarSignUiKey.Key,
subs =>
{
@@ -29,25 +34,49 @@ public sealed class BarSignSystem : EntitySystem
SetBarSign(ent, newPrototype);
}
private void OnAfterAutoHandleState(Entity<BarSignComponent> ent, ref AfterAutoHandleStateEvent args)
{
// Update the UI if the component was changed.
if (_ui.TryGetOpenUi(ent.Owner, BarSignUiKey.Key, out var bui))
bui.Update();
}
private void OnSetBarSignMessage(Entity<BarSignComponent> ent, ref SetBarSignMessage args)
{
if (!_prototypeManager.Resolve(args.Sign, out var signPrototype))
return;
if (signPrototype.Hidden)
return; // Hidden signs cannot be selected from the BUI.
SetBarSign(ent, signPrototype);
}
/// <summary>
/// Set the sprite, name and description of the bar sign to a given <see cref="BarSignPrototype"/>.
/// </summary>
public void SetBarSign(Entity<BarSignComponent> ent, BarSignPrototype newPrototype)
{
if (ent.Comp.Current == newPrototype.ID)
return;
var meta = MetaData(ent);
var name = Loc.GetString(newPrototype.Name);
_metaData.SetEntityName(ent, name, meta);
_metaData.SetEntityDescription(ent, Loc.GetString(newPrototype.Description), meta);
_appearance.SetData(ent.Owner, BarSignVisuals.BarSignPrototype, newPrototype.ID);
ent.Comp.Current = newPrototype.ID;
Dirty(ent);
// Predict updating the BUI if it's open.
if (_ui.TryGetOpenUi(ent.Owner, BarSignUiKey.Key, out var bui))
bui.Update();
}
/// <summary>
/// Returns a list of all <see cref="BarSignPrototype"/>s that are not hidden.
/// </summary>
public static List<BarSignPrototype> GetAllBarSigns(IPrototypeManager prototypeManager)
{
return prototypeManager