mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 18:31:17 +03:00
* Make masks pullable by others * Small fix * Sort Dependencies * gasjfsakhfaskjfsahjsafjhkfsa forgot to push * Move the methods * Target mask, not wearer --------- Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com>
202 lines
7.3 KiB
C#
202 lines
7.3 KiB
C#
using Content.Shared.Actions;
|
|
using Content.Shared.Clothing.Components;
|
|
using Content.Shared.Clothing.Events;
|
|
using Content.Shared.DoAfter;
|
|
using Content.Shared.Foldable;
|
|
using Content.Shared.IdentityManagement;
|
|
using Content.Shared.Inventory;
|
|
using Content.Shared.Inventory.Events;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.Verbs;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Shared.Clothing.EntitySystems;
|
|
|
|
public sealed partial class MaskSystem : EntitySystem
|
|
{
|
|
[Dependency] private IGameTiming _timingSystem = default!;
|
|
[Dependency] private SharedActionsSystem _actionSystem = default!;
|
|
[Dependency] private ClothingSystem _clothingSystem = default!;
|
|
[Dependency] private SharedDoAfterSystem _doAfterSystem = default!;
|
|
[Dependency] private InventorySystem _inventorySystem = default!;
|
|
[Dependency] private SharedPopupSystem _popupSystem = default!;
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnGotUnequipped(Entity<MaskComponent> mask, ref GotUnequippedEvent args)
|
|
{
|
|
ToggleMask(mask, false);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnGetActions(Entity<MaskComponent> mask, ref GetItemActionsEvent args)
|
|
{
|
|
if (!_inventorySystem.InSlotWithFlags(mask.Owner, SlotFlags.MASK)
|
|
|| !mask.Comp.IsToggleable)
|
|
return;
|
|
|
|
args.AddAction(ref mask.Comp.ToggleActionEntity, mask.Comp.ToggleAction);
|
|
Dirty(mask);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnToggleMaskAction(Entity<MaskComponent> mask, ref ToggleMaskEvent args)
|
|
{
|
|
if (args.Handled
|
|
|| mask.Comp.ToggleActionEntity == null
|
|
|| !mask.Comp.IsToggleable
|
|
|| !_inventorySystem.InSlotWithFlags(mask.Owner, SlotFlags.MASK))
|
|
return;
|
|
|
|
TryToggleMask(mask, args.Performer);
|
|
|
|
args.Handled = true;
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnGetInteractionVerbs(Entity<MaskComponent> mask, ref GetVerbsEvent<EquipmentVerb> args)
|
|
{
|
|
var evArgs = args;
|
|
|
|
if (!evArgs.CanAccess
|
|
|| !evArgs.CanInteract
|
|
|| evArgs.Hands is null
|
|
|| !mask.Comp.IsToggleable)
|
|
return;
|
|
|
|
var dir = mask.Comp.IsToggled ? "up" : "down";
|
|
|
|
EquipmentVerb verb = new()
|
|
{
|
|
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/dot.svg.192dpi.png")),
|
|
Act = () => TryToggleMask(mask, evArgs.User),
|
|
Text = Loc.GetString($"verb-name-mask-pull-{dir}"),
|
|
Message = Loc.GetString($"verb-description-mask-pull-{dir}"),
|
|
TextStyleClass = "InteractionVerb",
|
|
};
|
|
|
|
evArgs.Verbs.Add(verb);
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnToggleMaskDoAfterEvent(Entity<MaskComponent> mask, ref ToggleMaskDoAfterEvent args)
|
|
{
|
|
if (_timingSystem.ApplyingState || args.Handled || args.Cancelled)
|
|
return;
|
|
|
|
ToggleMask(mask, args.State, args.Force);
|
|
|
|
if (args.ByOther && args.Target.HasValue)
|
|
{
|
|
var dir = mask.Comp.IsToggled ? "down" : "up";
|
|
|
|
var messageWearer =
|
|
Loc.GetString($"verb-mask-other-pulled-{dir}-popup-message", ("puller", Identity.Entity(args.User, EntityManager)), ("mask", mask));
|
|
_popupSystem.PopupEntity(messageWearer, args.Target.Value, args.Target.Value);
|
|
|
|
var messagePuller =
|
|
Loc.GetString($"verb-mask-pulled-{dir}-popup-message", ("wearer", Identity.Entity(args.Target.Value, EntityManager)), ("mask", mask));
|
|
_popupSystem.PopupEntity(messagePuller, args.User, args.User);
|
|
}
|
|
|
|
args.Handled = true;
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnFolded(Entity<MaskComponent> mask, ref FoldedEvent args)
|
|
{
|
|
// See FoldableClothingComponent
|
|
if (!mask.Comp.DisableOnFolded)
|
|
return;
|
|
|
|
// While folded, we force the mask to be toggled / pulled down, so that its functionality as a mask is disabled,
|
|
// and we also prevent it from being un-toggled. We also automatically untoggle it when it gets unfolded, so it
|
|
// fully returns to its previous state when folded & unfolded.
|
|
|
|
ToggleMask(mask, args.IsFolded, force: true);
|
|
SetToggleable(mask, !args.IsFolded);
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is called when someone attempts to pull a mask down via a verb.
|
|
/// </summary>
|
|
/// <param name="mask"> The Mask Entity that is being pulled up/down.</param>
|
|
/// <param name="puller"> The person attempting to pull down the mask.</param>
|
|
/// <param name="wearer"> The person wearing the mask.</param>
|
|
/// <param name="state"> The wanted state of the mask. If undefined/null, it simply toggles the mask.</param>
|
|
/// <param name="force"> If true, it forces the mask to be toggled even if it cannot be toggled.</param>
|
|
private void TryToggleMask(Entity<MaskComponent> mask, EntityUid puller, bool? state = null, bool force = false)
|
|
{
|
|
TimeSpan delay;
|
|
var wearer = Transform(mask).ParentUid;
|
|
var dir = mask.Comp.IsToggled ? "up" : "down";
|
|
|
|
if (puller == wearer)
|
|
{
|
|
delay = TimeSpan.Zero;
|
|
|
|
var message = Loc.GetString($"action-mask-pull-{dir}-popup-message", ("mask", mask));
|
|
_popupSystem.PopupEntity(message, wearer, wearer);
|
|
}
|
|
else
|
|
{
|
|
delay = mask.Comp.Delay;
|
|
|
|
var message = Loc.GetString($"verb-mask-pull-{dir}-popup-message", ("puller", Identity.Entity(puller, EntityManager)), ("mask", mask));
|
|
_popupSystem.PopupEntity(message, wearer, wearer, PopupType.Medium);
|
|
}
|
|
|
|
var doAfterEv = new ToggleMaskDoAfterEvent(state, force, puller != wearer);
|
|
_doAfterSystem.TryStartDoAfter(
|
|
new DoAfterArgs(EntityManager, puller, delay, doAfterEv, mask, target: wearer)
|
|
{
|
|
BreakOnDamage = true,
|
|
BreakOnMove = true,
|
|
MovementThreshold = 0.1f,
|
|
});
|
|
}
|
|
|
|
private void ToggleMask(Entity<MaskComponent> mask, bool? state = null, bool force = false)
|
|
{
|
|
if (_timingSystem.ApplyingState
|
|
|| !force && !mask.Comp.IsToggleable)
|
|
return;
|
|
|
|
mask.Comp.IsToggled = state ?? !mask.Comp.IsToggled;
|
|
|
|
if (mask.Comp.ToggleActionEntity is { } action)
|
|
_actionSystem.SetToggled(action, mask.Comp.IsToggled);
|
|
|
|
// TODO Generalize toggling & clothing prefixes. See also FoldableClothingComponent
|
|
var prefix = mask.Comp.IsToggled ? mask.Comp.EquippedPrefix : null;
|
|
_clothingSystem.SetEquippedPrefix(mask, prefix);
|
|
|
|
EntityUid? wearer = null;
|
|
if (_inventorySystem.InSlotWithFlags(mask.Owner, SlotFlags.MASK))
|
|
wearer = Transform(mask).ParentUid;
|
|
|
|
var maskEv = new ItemMaskToggledEvent(mask, wearer);
|
|
RaiseLocalEvent(mask, ref maskEv);
|
|
|
|
if (wearer != null)
|
|
{
|
|
var wearerEv = new WearerMaskToggledEvent(mask);
|
|
RaiseLocalEvent(wearer.Value, ref wearerEv);
|
|
}
|
|
|
|
Dirty(mask);
|
|
}
|
|
|
|
public void SetToggleable(Entity<MaskComponent> mask, bool toggleable)
|
|
{
|
|
if (_timingSystem.ApplyingState || mask.Comp.IsToggleable == toggleable)
|
|
return;
|
|
|
|
mask.Comp.IsToggleable = toggleable;
|
|
|
|
if (mask.Comp.ToggleActionEntity is { } action)
|
|
_actionSystem.SetEnabled(action, toggleable);
|
|
|
|
Dirty(mask);
|
|
}
|
|
}
|