Files
tbd-station-14/Content.Server/Clothing/Systems/ChameleonClothingSystem.cs
2023-07-16 01:04:51 -06:00

117 lines
4.3 KiB
C#

using Content.Server.IdentityManagement;
using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems;
using Content.Shared.IdentityManagement.Components;
using Content.Shared.Prototypes;
using Content.Shared.Verbs;
using Robust.Server.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Clothing.Systems;
public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IdentitySystem _identity = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ChameleonClothingComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<ChameleonClothingComponent, ComponentGetState>(GetState);
SubscribeLocalEvent<ChameleonClothingComponent, GetVerbsEvent<InteractionVerb>>(OnVerb);
SubscribeLocalEvent<ChameleonClothingComponent, ChameleonPrototypeSelectedMessage>(OnSelected);
}
private void OnMapInit(EntityUid uid, ChameleonClothingComponent component, MapInitEvent args)
{
SetSelectedPrototype(uid, component.SelectedId, true, component);
}
private void GetState(EntityUid uid, ChameleonClothingComponent component, ref ComponentGetState args)
{
args.State = new ChameleonClothingComponentState
{
SelectedId = component.SelectedId
};
}
private void OnVerb(EntityUid uid, ChameleonClothingComponent component, GetVerbsEvent<InteractionVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
args.Verbs.Add(new InteractionVerb()
{
Text = Loc.GetString("chameleon-component-verb-text"),
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/settings.svg.192dpi.png")),
Act = () => TryOpenUi(uid, args.User, component)
});
}
private void OnSelected(EntityUid uid, ChameleonClothingComponent component, ChameleonPrototypeSelectedMessage args)
{
SetSelectedPrototype(uid, args.SelectedId, component: component);
}
private void TryOpenUi(EntityUid uid, EntityUid user, ChameleonClothingComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
if (!TryComp(user, out ActorComponent? actor))
return;
_uiSystem.TryToggleUi(uid, ChameleonUiKey.Key, actor.PlayerSession);
}
private void UpdateUi(EntityUid uid, ChameleonClothingComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
var state = new ChameleonBoundUserInterfaceState(component.Slot, component.SelectedId);
_uiSystem.TrySetUiState(uid, ChameleonUiKey.Key, state);
}
/// <summary>
/// Change chameleon items name, description and sprite to mimic other entity prototype.
/// </summary>
public void SetSelectedPrototype(EntityUid uid, string? protoId, bool forceUpdate = false,
ChameleonClothingComponent? component = null)
{
if (!Resolve(uid, ref component, false))
return;
// check that wasn't already selected
// forceUpdate on component init ignores this check
if (component.SelectedId == protoId && !forceUpdate)
return;
// make sure that it is valid change
if (string.IsNullOrEmpty(protoId) || !_proto.TryIndex(protoId, out EntityPrototype? proto))
return;
if (!IsValidTarget(proto, component.Slot))
return;
component.SelectedId = protoId;
UpdateIdentityBlocker(uid, component, proto);
UpdateVisuals(uid, component);
UpdateUi(uid, component);
Dirty(component);
}
private void UpdateIdentityBlocker(EntityUid uid, ChameleonClothingComponent component, EntityPrototype proto)
{
if (proto.HasComponent<IdentityBlockerComponent>(_factory))
EnsureComp<IdentityBlockerComponent>(uid);
else
RemComp<IdentityBlockerComponent>(uid);
if (component.User != null)
_identity.QueueIdentityUpdate(component.User.Value);
}
}