Add face bandanas (#24597)

* add face bandanas

* oops

* make face bandanas butcherable, also one bite

* oops

* Add mouth IdentityBlocker to bandanas

* refactor to use foldablecomponent

* remove some leftover bits

* remove HamsterWearable until face sprite updated

* oops

* review changes

* remove a few unneeded bits
This commit is contained in:
themias
2024-02-03 19:52:44 -05:00
committed by GitHub
parent 494af9ac68
commit b503fe5864
31 changed files with 309 additions and 126 deletions

View File

@@ -64,7 +64,7 @@ public sealed partial class ToggleMaskEvent : InstantActionEvent { }
/// Event raised on the mask entity when it is toggled. /// Event raised on the mask entity when it is toggled.
/// </summary> /// </summary>
[ByRefEvent] [ByRefEvent]
public readonly record struct ItemMaskToggledEvent(EntityUid Wearer, bool IsToggled, bool IsEquip); public readonly record struct ItemMaskToggledEvent(EntityUid Wearer, string? equippedPrefix, bool IsToggled, bool IsEquip);
/// <summary> /// <summary>
/// Event raised on the entity wearing the mask when it is toggled. /// Event raised on the entity wearing the mask when it is toggled.

View File

@@ -0,0 +1,20 @@
using Content.Shared.Inventory;
using Robust.Shared.GameStates;
namespace Content.Shared.Clothing.Components;
[RegisterComponent, NetworkedComponent]
public sealed partial class FoldableClothingComponent : Component
{
/// <summary>
/// Which slots does this fit into when folded?
/// </summary>
[DataField]
public SlotFlags? FoldedSlots;
/// <summary>
/// Which slots does this fit into when unfolded?
/// </summary>
[DataField]
public SlotFlags? UnfoldedSlots;
}

View File

@@ -1,4 +1,4 @@
using Content.Shared.Clothing.EntitySystems; using Content.Shared.Clothing.EntitySystems;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -19,4 +19,7 @@ public sealed partial class MaskComponent : Component
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
public bool IsToggled; public bool IsToggled;
[DataField, AutoNetworkedField]
public string EquippedPrefix = "toggled";
} }

View File

@@ -113,7 +113,8 @@ public abstract class ClothingSystem : EntitySystem
private void OnMaskToggled(Entity<ClothingComponent> ent, ref ItemMaskToggledEvent args) private void OnMaskToggled(Entity<ClothingComponent> ent, ref ItemMaskToggledEvent args)
{ {
//TODO: sprites for 'pulled down' state. defaults to invisible due to no sprite with this prefix //TODO: sprites for 'pulled down' state. defaults to invisible due to no sprite with this prefix
SetEquippedPrefix(ent, args.IsToggled ? "toggled" : null, ent); if(args.equippedPrefix != null)
SetEquippedPrefix(ent, args.IsToggled ? args.equippedPrefix : null, ent);
} }
private void OnEquipDoAfter(Entity<ClothingComponent> ent, ref ClothingEquipDoAfterEvent args) private void OnEquipDoAfter(Entity<ClothingComponent> ent, ref ClothingEquipDoAfterEvent args)

View File

@@ -0,0 +1,42 @@
using Content.Shared.Clothing.Components;
using Content.Shared.Foldable;
using Content.Shared.Inventory;
namespace Content.Shared.Clothing.EntitySystems;
public sealed class FoldableClothingSystem : EntitySystem
{
[Dependency] private readonly ClothingSystem _clothingSystem = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FoldableClothingComponent, FoldAttemptEvent>(OnFoldAttempt);
SubscribeLocalEvent<FoldableClothingComponent, FoldedEvent>(OnFolded);
}
private void OnFoldAttempt(Entity<FoldableClothingComponent> ent, ref FoldAttemptEvent args)
{
if (args.Cancelled)
return;
// allow folding while equipped if allowed slots are the same:
// e.g. flip a hat backwards while on your head
if (_inventorySystem.TryGetContainingSlot(ent.Owner, out var slot) &&
!ent.Comp.FoldedSlots.Equals(ent.Comp.UnfoldedSlots))
args.Cancelled = true;
}
private void OnFolded(Entity<FoldableClothingComponent> ent, ref FoldedEvent args)
{
if (TryComp<ClothingComponent>(ent.Owner, out var clothingComp))
{
if (args.IsFolded && ent.Comp.FoldedSlots.HasValue)
_clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp);
else if (!args.IsFolded && ent.Comp.UnfoldedSlots.HasValue)
_clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
}
}
}

View File

@@ -1,7 +1,9 @@
using Content.Shared.Actions; using Content.Shared.Actions;
using Content.Shared.Clothing.Components; using Content.Shared.Clothing.Components;
using Content.Shared.Foldable;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Item;
using Content.Shared.Popups; using Content.Shared.Popups;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -21,11 +23,12 @@ public sealed class MaskSystem : EntitySystem
SubscribeLocalEvent<MaskComponent, ToggleMaskEvent>(OnToggleMask); SubscribeLocalEvent<MaskComponent, ToggleMaskEvent>(OnToggleMask);
SubscribeLocalEvent<MaskComponent, GetItemActionsEvent>(OnGetActions); SubscribeLocalEvent<MaskComponent, GetItemActionsEvent>(OnGetActions);
SubscribeLocalEvent<MaskComponent, GotUnequippedEvent>(OnGotUnequipped); SubscribeLocalEvent<MaskComponent, GotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<MaskComponent, FoldedEvent>(OnFolded);
} }
private void OnGetActions(EntityUid uid, MaskComponent component, GetItemActionsEvent args) private void OnGetActions(EntityUid uid, MaskComponent component, GetItemActionsEvent args)
{ {
if (!args.InHands) if (_inventorySystem.InSlotWithFlags(uid, SlotFlags.MASK))
args.AddAction(ref component.ToggleActionEntity, component.ToggleAction); args.AddAction(ref component.ToggleActionEntity, component.ToggleAction);
} }
@@ -46,7 +49,7 @@ public sealed class MaskSystem : EntitySystem
else else
_popupSystem.PopupEntity(Loc.GetString("action-mask-pull-up-popup-message", ("mask", uid)), args.Performer, args.Performer); _popupSystem.PopupEntity(Loc.GetString("action-mask-pull-up-popup-message", ("mask", uid)), args.Performer, args.Performer);
ToggleMaskComponents(uid, mask, args.Performer); ToggleMaskComponents(uid, mask, args.Performer, mask.EquippedPrefix);
} }
// set to untoggled when unequipped, so it isn't left in a 'pulled down' state // set to untoggled when unequipped, so it isn't left in a 'pulled down' state
@@ -59,15 +62,22 @@ public sealed class MaskSystem : EntitySystem
Dirty(uid, mask); Dirty(uid, mask);
_actionSystem.SetToggled(mask.ToggleActionEntity, mask.IsToggled); _actionSystem.SetToggled(mask.ToggleActionEntity, mask.IsToggled);
ToggleMaskComponents(uid, mask, args.Equipee, true); ToggleMaskComponents(uid, mask, args.Equipee, mask.EquippedPrefix, true);
} }
private void ToggleMaskComponents(EntityUid uid, MaskComponent mask, EntityUid wearer, bool isEquip = false) private void ToggleMaskComponents(EntityUid uid, MaskComponent mask, EntityUid wearer, string? equippedPrefix = null, bool isEquip = false)
{ {
var maskEv = new ItemMaskToggledEvent(wearer, mask.IsToggled, isEquip); var maskEv = new ItemMaskToggledEvent(wearer, equippedPrefix, mask.IsToggled, isEquip);
RaiseLocalEvent(uid, ref maskEv); RaiseLocalEvent(uid, ref maskEv);
var wearerEv = new WearerMaskToggledEvent(mask.IsToggled); var wearerEv = new WearerMaskToggledEvent(mask.IsToggled);
RaiseLocalEvent(wearer, ref wearerEv); RaiseLocalEvent(wearer, ref wearerEv);
} }
private void OnFolded(Entity<MaskComponent> ent, ref FoldedEvent args)
{
ent.Comp.IsToggled = args.IsFolded;
ToggleMaskComponents(ent.Owner, ent.Comp, ent.Owner);
}
} }

View File

@@ -1,5 +1,4 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Foldable; namespace Content.Shared.Foldable;
@@ -9,23 +8,13 @@ namespace Content.Shared.Foldable;
/// <remarks> /// <remarks>
/// Will prevent any insertions into containers while this item is unfolded. /// Will prevent any insertions into containers while this item is unfolded.
/// </remarks> /// </remarks>
[RegisterComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[NetworkedComponent]
[Access(typeof(FoldableSystem))] [Access(typeof(FoldableSystem))]
public sealed partial class FoldableComponent : Component public sealed partial class FoldableComponent : Component
{ {
[DataField("folded")] [DataField("folded"), AutoNetworkedField]
public bool IsFolded = false; public bool IsFolded = false;
}
// ahhh, the ol' "state thats just a copy of the component". [DataField]
[Serializable, NetSerializable] public bool CanFoldInsideContainer = false;
public sealed class FoldableComponentState : ComponentState
{
public readonly bool IsFolded;
public FoldableComponentState(bool isFolded)
{
IsFolded = isFolded;
}
} }

View File

@@ -3,7 +3,6 @@ using Content.Shared.Buckle.Components;
using Content.Shared.Storage.Components; using Content.Shared.Storage.Components;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -20,8 +19,7 @@ public sealed class FoldableSystem : EntitySystem
base.Initialize(); base.Initialize();
SubscribeLocalEvent<FoldableComponent, GetVerbsEvent<AlternativeVerb>>(AddFoldVerb); SubscribeLocalEvent<FoldableComponent, GetVerbsEvent<AlternativeVerb>>(AddFoldVerb);
SubscribeLocalEvent<FoldableComponent, ComponentGetState>(OnGetState); SubscribeLocalEvent<FoldableComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<FoldableComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<FoldableComponent, ComponentInit>(OnFoldableInit); SubscribeLocalEvent<FoldableComponent, ComponentInit>(OnFoldableInit);
SubscribeLocalEvent<FoldableComponent, ContainerGettingInsertedAttemptEvent>(OnInsertEvent); SubscribeLocalEvent<FoldableComponent, ContainerGettingInsertedAttemptEvent>(OnInsertEvent);
@@ -31,18 +29,9 @@ public sealed class FoldableSystem : EntitySystem
SubscribeLocalEvent<FoldableComponent, BuckleAttemptEvent>(OnBuckleAttempt); SubscribeLocalEvent<FoldableComponent, BuckleAttemptEvent>(OnBuckleAttempt);
} }
private void OnGetState(EntityUid uid, FoldableComponent component, ref ComponentGetState args) private void OnHandleState(EntityUid uid, FoldableComponent component, ref AfterAutoHandleStateEvent args)
{ {
args.State = new FoldableComponentState(component.IsFolded); SetFolded(uid, component, component.IsFolded);
}
private void OnHandleState(EntityUid uid, FoldableComponent component, ref ComponentHandleState args)
{
if (args.Current is not FoldableComponentState state)
return;
if (state.IsFolded != component.IsFolded)
SetFolded(uid, component, state.IsFolded);
} }
private void OnFoldableInit(EntityUid uid, FoldableComponent component, ComponentInit args) private void OnFoldableInit(EntityUid uid, FoldableComponent component, ComponentInit args)
@@ -90,11 +79,14 @@ public sealed class FoldableSystem : EntitySystem
Dirty(uid, component); Dirty(uid, component);
_appearance.SetData(uid, FoldedVisuals.State, folded); _appearance.SetData(uid, FoldedVisuals.State, folded);
_buckle.StrapSetEnabled(uid, !component.IsFolded); _buckle.StrapSetEnabled(uid, !component.IsFolded);
var ev = new FoldedEvent(folded);
RaiseLocalEvent(uid, ref ev);
} }
private void OnInsertEvent(EntityUid uid, FoldableComponent component, ContainerGettingInsertedAttemptEvent args) private void OnInsertEvent(EntityUid uid, FoldableComponent component, ContainerGettingInsertedAttemptEvent args)
{ {
if (!component.IsFolded) if (!component.IsFolded && !component.CanFoldInsideContainer)
args.Cancel(); args.Cancel();
} }
@@ -108,8 +100,8 @@ public sealed class FoldableSystem : EntitySystem
if (!Resolve(uid, ref fold)) if (!Resolve(uid, ref fold))
return false; return false;
// Can't un-fold in any container (locker, hands, inventory, whatever). // Can't un-fold in any container unless enabled (locker, hands, inventory, whatever).
if (_container.IsEntityInContainer(uid)) if (_container.IsEntityInContainer(uid) && !fold.CanFoldInsideContainer)
return false; return false;
var ev = new FoldAttemptEvent(); var ev = new FoldAttemptEvent();
@@ -167,3 +159,10 @@ public sealed class FoldableSystem : EntitySystem
/// <param name="Cancelled"></param> /// <param name="Cancelled"></param>
[ByRefEvent] [ByRefEvent]
public record struct FoldAttemptEvent(bool Cancelled = false); public record struct FoldAttemptEvent(bool Cancelled = false);
/// <summary>
/// Event raised on an entity after it has been folded.
/// </summary>
/// <param name="IsFolded"></param>
[ByRefEvent]
public readonly record struct FoldedEvent(bool IsFolded);

View File

@@ -1,114 +1,72 @@
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBaseButcherable, BaseFoldable]
id: ClothingHeadBandBase
abstract: true
components:
- type: Foldable
folded: true
- type: Mask
isToggled: true
- type: IngestionBlocker
enabled: false
- type: IdentityBlocker
enabled: false
coverage: MOUTH
- type: Sprite # needed for vendor inventory icons
layers:
- state: icon
map: ["foldedLayer"]
visible: true
- state: icon_mask
map: [ "unfoldedLayer" ]
visible: false
- type: entity
parent: [ClothingHeadBandBase, ClothingMaskBandBlack]
id: ClothingHeadBandBlack id: ClothingHeadBandBlack
name: black bandana name: black bandana
description: A black bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/black.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/black.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandBlue]
id: ClothingHeadBandBlue id: ClothingHeadBandBlue
name: blue bandana name: blue bandana
description: A blue bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/blue.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/blue.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandBotany]
id: ClothingHeadBandBotany id: ClothingHeadBandBotany
name: botany bandana name: botany bandana
description: A botany bandana to make you look cool, made from natural fibers.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/botany.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/botany.rsi
- type: Tag
tags:
- ClothMade
- HamsterWearable
- WhitelistChameleon
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandGold]
id: ClothingHeadBandGold id: ClothingHeadBandGold
name: gold bandana name: gold bandana
description: A gold bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/gold.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/gold.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandGreen]
id: ClothingHeadBandGreen id: ClothingHeadBandGreen
name: green bandana name: green bandana
description: A green bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/green.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/green.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandGrey]
id: ClothingHeadBandGrey id: ClothingHeadBandGrey
name: grey bandana name: grey bandana
description: A grey bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/grey.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/grey.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandRed]
id: ClothingHeadBandRed id: ClothingHeadBandRed
name: red bandana name: red bandana
description: A red bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/red.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/red.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandSkull]
id: ClothingHeadBandSkull id: ClothingHeadBandSkull
name: skull bandana name: skull bandana
description: A bandana with a skull to make you look even cooler.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/skull.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/skull.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandMerc]
id: ClothingHeadBandMerc id: ClothingHeadBandMerc
name: mercenary bandana name: mercenary bandana
description: To protect the head from the sun, insects and other dangers of the higher path.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/merc.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/merc.rsi
- type: entity - type: entity
parent: ClothingHeadBaseButcherable parent: [ClothingHeadBandBase, ClothingMaskBandBrown]
id: ClothingHeadBandBrown id: ClothingHeadBandBrown
name: brown bandana name: brown bandana
description: A brown bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/brown.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/brown.rsi

View File

@@ -0,0 +1,138 @@
- type: entity
parent: [ClothingMaskBaseButcherable, BaseFoldable]
id: ClothingMaskBandanaBase
abstract: true
components:
- type: Appearance
- type: Foldable
canFoldInsideContainer: true
- type: FoldableClothing
foldedSlots:
- HEAD
unfoldedSlots:
- MASK
- type: Mask
- type: IngestionBlocker
- type: IdentityBlocker
coverage: MOUTH
- type: Sprite
layers:
- state: icon_mask
map: [ "unfoldedLayer" ]
- state: icon
map: ["foldedLayer"]
visible: false
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandBlack
name: black bandana
description: A black bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/black.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/black.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandBlue
name: blue bandana
description: A blue bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/blue.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/blue.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandBotany
name: botany bandana
description: A botany bandana to make you look cool, made from natural fibers.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/botany.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/botany.rsi
- type: Tag
tags:
- ClothMade
- WhitelistChameleon
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandGold
name: gold bandana
description: A gold bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/gold.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/gold.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandGreen
name: green bandana
description: A green bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/green.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/green.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandGrey
name: grey bandana
description: A grey bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/grey.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/grey.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandRed
name: red bandana
description: A red bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/red.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/red.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandSkull
name: skull bandana
description: A bandana with a skull to make you look even cooler.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/skull.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/skull.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandMerc
name: mercenary bandana
description: To protect the head from the sun, insects and other dangers of the higher path.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/merc.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/merc.rsi
- type: entity
parent: ClothingMaskBandanaBase
id: ClothingMaskBandBrown
name: brown bandana
description: A brown bandana to make you look cool.
components:
- type: Sprite
sprite: Clothing/Head/Bandanas/brown.rsi
- type: Clothing
sprite: Clothing/Head/Bandanas/brown.rsi

View File

@@ -27,3 +27,26 @@
icon: { sprite: Clothing/Mask/gas.rsi, state: icon } icon: { sprite: Clothing/Mask/gas.rsi, state: icon }
iconOn: Interface/Default/blocked.png iconOn: Interface/Default/blocked.png
event: !type:ToggleMaskEvent event: !type:ToggleMaskEvent
- type: entity
id: ClothingMaskBaseButcherable
parent: ClothingMaskBase
abstract: true
components:
- type: Butcherable
butcheringType: Knife
spawned:
- id: MaterialCloth1
amount: 1
- type: Food
requiresSpecialDigestion: true
- type: SolutionContainerManager
solutions:
food:
maxVol: 10
reagents:
- ReagentId: Fiber
Quantity: 10
- type: Tag
tags:
- ClothMade

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -22,7 +22,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {

View File

@@ -18,7 +18,7 @@
"directions": 4 "directions": 4
}, },
{ {
"name": "mask-equipped-HELMET", "name": "equipped-MASK",
"directions": 4 "directions": 4
}, },
{ {