committed by
GitHub
parent
32c14b0e51
commit
052ea49884
@@ -4,15 +4,13 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Client.GameObjects.Components.Clothing;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Content.Shared.Preferences.Appearance;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.SharedInventoryComponent.ClientInventoryMessage;
|
||||
@@ -81,6 +79,46 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
return item != null && _slots.Values.Any(e => e == item);
|
||||
}
|
||||
|
||||
public override float WalkSpeedModifier
|
||||
{
|
||||
get
|
||||
{
|
||||
var mod = 1f;
|
||||
foreach (var slot in _slots.Values)
|
||||
{
|
||||
if (slot != null)
|
||||
{
|
||||
foreach (var modifier in slot.GetAllComponents<IMoveSpeedModifier>())
|
||||
{
|
||||
mod *= modifier.WalkSpeedModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
public override float SprintSpeedModifier
|
||||
{
|
||||
get
|
||||
{
|
||||
var mod = 1f;
|
||||
foreach (var slot in _slots.Values)
|
||||
{
|
||||
if (slot != null)
|
||||
{
|
||||
foreach (var modifier in slot.GetAllComponents<IMoveSpeedModifier>())
|
||||
{
|
||||
mod *= modifier.SprintSpeedModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
@@ -120,6 +158,11 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
|
||||
_slots.Remove(slot);
|
||||
}
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? mod))
|
||||
{
|
||||
mod.RefreshMovementSpeedModifiers();
|
||||
}
|
||||
}
|
||||
|
||||
private void _setSlot(Slots slot, IEntity entity)
|
||||
|
||||
22
Content.Client/GameObjects/Components/MagbootsComponent.cs
Normal file
22
Content.Client/GameObjects/Components/MagbootsComponent.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Content.Client.GameObjects.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class MagbootsComponent : SharedMagbootsComponent
|
||||
{
|
||||
public override bool On { get; set; }
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
if (curState is not MagbootsComponentState compState)
|
||||
return;
|
||||
|
||||
On = compState.On;
|
||||
OnChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.EntitySystems.Click;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||
using Content.Shared.GameObjects.EntitySystems.EffectBlocker;
|
||||
@@ -105,6 +106,46 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
}
|
||||
}
|
||||
|
||||
public override float WalkSpeedModifier
|
||||
{
|
||||
get
|
||||
{
|
||||
var mod = 1f;
|
||||
foreach (var slot in _slotContainers.Values)
|
||||
{
|
||||
if (slot.ContainedEntity != null)
|
||||
{
|
||||
foreach (var modifier in slot.ContainedEntity.GetAllComponents<IMoveSpeedModifier>())
|
||||
{
|
||||
mod *= modifier.WalkSpeedModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
public override float SprintSpeedModifier
|
||||
{
|
||||
get
|
||||
{
|
||||
var mod = 1f;
|
||||
foreach (var slot in _slotContainers.Values)
|
||||
{
|
||||
if (slot.ContainedEntity != null)
|
||||
{
|
||||
foreach (var modifier in slot.ContainedEntity.GetAllComponents<IMoveSpeedModifier>())
|
||||
{
|
||||
mod *= modifier.SprintSpeedModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
bool IEffectBlocker.CanSlip()
|
||||
{
|
||||
if (Owner.TryGetComponent(out InventoryComponent inventoryComponent) &&
|
||||
@@ -165,7 +206,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
return GetSlotItem<ItemComponent>(slot);
|
||||
}
|
||||
|
||||
public IEnumerable<T> LookupItems<T>() where T: Component
|
||||
public IEnumerable<T> LookupItems<T>() where T : Component
|
||||
{
|
||||
return _slotContainers.Values.SelectMany(x => x.ContainedEntities.Select(e => e.GetComponentOrNull<T>()))
|
||||
.Where(x => x != null);
|
||||
@@ -185,6 +226,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
containedEntity = null;
|
||||
Dirty();
|
||||
}
|
||||
|
||||
return containedEntity?.GetComponent<T>();
|
||||
}
|
||||
|
||||
@@ -230,12 +272,16 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
Dirty();
|
||||
|
||||
UpdateMovementSpeed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Equip(Slots slot, ItemComponent item, bool mobCheck = true) => Equip(slot, item, mobCheck, out var _);
|
||||
public bool Equip(Slots slot, ItemComponent item, bool mobCheck = true) =>
|
||||
Equip(slot, item, mobCheck, out var _);
|
||||
|
||||
public bool Equip(Slots slot, IEntity entity, bool mobCheck = true) => Equip(slot, entity.GetComponent<ItemComponent>(), mobCheck);
|
||||
public bool Equip(Slots slot, IEntity entity, bool mobCheck = true) =>
|
||||
Equip(slot, entity.GetComponent<ItemComponent>(), mobCheck);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether an item can be put in the specified slot.
|
||||
@@ -314,9 +360,19 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
Dirty();
|
||||
|
||||
UpdateMovementSpeed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateMovementSpeed()
|
||||
{
|
||||
if (Owner.TryGetComponent(out MovementSpeedModifierComponent mod))
|
||||
{
|
||||
mod.RefreshMovementSpeedModifiers();
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceUnequip(Slots slot)
|
||||
{
|
||||
var inventorySlot = _slotContainers[slot];
|
||||
@@ -452,7 +508,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
var activeHand = hands.GetActiveHand;
|
||||
if (activeHand != null && activeHand.Owner.TryGetComponent(out ItemComponent clothing))
|
||||
{
|
||||
hands.Drop(hands.ActiveHand, doDropInteraction:false);
|
||||
hands.Drop(hands.ActiveHand, doDropInteraction: false);
|
||||
if (!Equip(msg.Inventoryslot, clothing, true, out var reason))
|
||||
{
|
||||
hands.PutInHand(clothing);
|
||||
@@ -461,6 +517,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
Owner.PopupMessageCursor(reason);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ClientInventoryUpdate.Use:
|
||||
@@ -491,7 +548,9 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
if (activeHand != null && GetSlotItem(msg.Inventoryslot) == null)
|
||||
{
|
||||
var canEquip = CanEquip(msg.Inventoryslot, activeHand, true, out var reason);
|
||||
_hoverEntity = new KeyValuePair<Slots, (EntityUid entity, bool fits)>(msg.Inventoryslot, (activeHand.Owner.Uid, canEquip));
|
||||
_hoverEntity =
|
||||
new KeyValuePair<Slots, (EntityUid entity, bool fits)>(msg.Inventoryslot,
|
||||
(activeHand.Owner.Uid, canEquip));
|
||||
|
||||
Dirty();
|
||||
}
|
||||
@@ -519,7 +578,8 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession session = null)
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel,
|
||||
ICommonSession session = null)
|
||||
{
|
||||
base.HandleNetworkMessage(message, netChannel, session);
|
||||
|
||||
|
||||
157
Content.Server/GameObjects/Components/MagbootsComponent.cs
Normal file
157
Content.Server/GameObjects/Components/MagbootsComponent.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
#nullable enable
|
||||
using Content.Server.GameObjects.Components.Atmos;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.ComponentDependencies;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||
|
||||
namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
public sealed class MagbootsComponent : SharedMagbootsComponent, IUnequipped, IEquipped, IUse, IActivate
|
||||
{
|
||||
[ComponentDependency] private ItemComponent? _item = null;
|
||||
[ComponentDependency] private ItemActionsComponent? _itemActions = null;
|
||||
[ComponentDependency] private SpriteComponent? _sprite = null;
|
||||
private bool _on;
|
||||
|
||||
[ViewVariables]
|
||||
public override bool On
|
||||
{
|
||||
get => _on;
|
||||
set
|
||||
{
|
||||
_on = value;
|
||||
|
||||
UpdateContainer();
|
||||
_itemActions?.Toggle(ItemActionType.ToggleMagboots, On);
|
||||
if (_item != null)
|
||||
_item.EquippedPrefix = On ? "on" : null;
|
||||
_sprite?.LayerSetState(0, On ? "icon-on" : "icon");
|
||||
OnChanged();
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void Toggle(IEntity user)
|
||||
{
|
||||
On = !On;
|
||||
}
|
||||
|
||||
void IUnequipped.Unequipped(UnequippedEventArgs eventArgs)
|
||||
{
|
||||
if (On && eventArgs.Slot == Slots.SHOES)
|
||||
{
|
||||
if (eventArgs.User.TryGetComponent(out MovedByPressureComponent? movedByPressure))
|
||||
{
|
||||
movedByPressure.Enabled = true;
|
||||
}
|
||||
|
||||
if (eventArgs.User.TryGetComponent(out ServerAlertsComponent? alerts))
|
||||
{
|
||||
alerts.ClearAlert(AlertType.Magboots);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IEquipped.Equipped(EquippedEventArgs eventArgs)
|
||||
{
|
||||
UpdateContainer();
|
||||
}
|
||||
|
||||
private void UpdateContainer()
|
||||
{
|
||||
if (!Owner.TryGetContainer(out var container))
|
||||
return;
|
||||
|
||||
if (container.Owner.TryGetComponent(out InventoryComponent? inventoryComponent)
|
||||
&& inventoryComponent.GetSlotItem(Slots.SHOES)?.Owner == Owner)
|
||||
{
|
||||
if (container.Owner.TryGetComponent(out MovedByPressureComponent? movedByPressure))
|
||||
{
|
||||
movedByPressure.Enabled = false;
|
||||
}
|
||||
|
||||
if (container.Owner.TryGetComponent(out ServerAlertsComponent? alerts))
|
||||
{
|
||||
if (On)
|
||||
{
|
||||
alerts.ShowAlert(AlertType.Magboots);
|
||||
}
|
||||
else
|
||||
{
|
||||
alerts.ClearAlert(AlertType.Magboots);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
|
||||
{
|
||||
Toggle(eventArgs.User);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
Toggle(eventArgs.User);
|
||||
}
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new MagbootsComponentState(On);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class ToggleMagbootsVerb : Verb<MagbootsComponent>
|
||||
{
|
||||
protected override void GetData(IEntity user, MagbootsComponent component, VerbData data)
|
||||
{
|
||||
if (!ActionBlockerSystem.CanInteract(user))
|
||||
{
|
||||
data.Visibility = VerbVisibility.Invisible;
|
||||
return;
|
||||
}
|
||||
|
||||
data.Text = Loc.GetString("Toggle Magboots");
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, MagbootsComponent component)
|
||||
{
|
||||
component.Toggle(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class ToggleMagbootsAction : IToggleItemAction
|
||||
{
|
||||
public void ExposeData(ObjectSerializer serializer) { }
|
||||
|
||||
public bool DoToggleAction(ToggleItemActionEventArgs args)
|
||||
{
|
||||
if (!args.Item.TryGetComponent<MagbootsComponent>(out var magboots))
|
||||
return false;
|
||||
|
||||
magboots.Toggle(args.Performer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
Error,
|
||||
ToggleInternals,
|
||||
ToggleLight,
|
||||
ToggleMagboots,
|
||||
DebugInstant,
|
||||
DebugToggle,
|
||||
DebugTargetPoint,
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
Parched,
|
||||
Pulled,
|
||||
Pulling,
|
||||
Magboots,
|
||||
Debug1,
|
||||
Debug2,
|
||||
Debug3,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
@@ -11,7 +12,7 @@ using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefine
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Inventory
|
||||
{
|
||||
public abstract class SharedInventoryComponent : Component
|
||||
public abstract class SharedInventoryComponent : Component, IMoveSpeedModifier
|
||||
{
|
||||
// ReSharper disable UnassignedReadonlyField
|
||||
[Dependency] protected readonly IReflectionManager ReflectionManager;
|
||||
@@ -100,5 +101,8 @@ namespace Content.Shared.GameObjects.Components.Inventory
|
||||
Slot = slot;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract float WalkSpeedModifier { get; }
|
||||
public abstract float SprintSpeedModifier { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -54,6 +56,15 @@ namespace Content.Shared.GameObjects.Components.Movement
|
||||
_movespeedModifiersNeedRefresh = true;
|
||||
}
|
||||
|
||||
public static void RefreshItemModifiers(IEntity item)
|
||||
{
|
||||
if (item.TryGetContainer(out var container) &&
|
||||
container.Owner.TryGetComponent(out MovementSpeedModifierComponent mod))
|
||||
{
|
||||
mod.RefreshMovementSpeedModifiers();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components
|
||||
{
|
||||
public abstract class SharedMagbootsComponent : Component, IMoveSpeedModifier
|
||||
{
|
||||
public sealed override string Name => "Magboots";
|
||||
public sealed override uint? NetID => ContentNetIDs.MAGBOOTS;
|
||||
|
||||
public abstract bool On { get; set; }
|
||||
|
||||
|
||||
protected void OnChanged()
|
||||
{
|
||||
MovementSpeedModifierComponent.RefreshItemModifiers(Owner);
|
||||
}
|
||||
|
||||
public float WalkSpeedModifier => On ? 0.85f : 1;
|
||||
public float SprintSpeedModifier => On ? 0.65f : 1;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class MagbootsComponentState : ComponentState
|
||||
{
|
||||
public bool On { get; }
|
||||
|
||||
public MagbootsComponentState(bool @on) : base(ContentNetIDs.MAGBOOTS)
|
||||
{
|
||||
On = on;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,7 @@
|
||||
public const uint REAGENT_GRINDER = 1082;
|
||||
public const uint ACTIONS = 1083;
|
||||
public const uint DAMAGEABLE = 1084;
|
||||
public const uint MAGBOOTS = 1085;
|
||||
|
||||
// Net IDs for integration tests.
|
||||
public const uint PREDICTION_TEST = 10001;
|
||||
|
||||
13
Resources/Prototypes/Actions/magboots.yml
Normal file
13
Resources/Prototypes/Actions/magboots.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
- type: itemAction
|
||||
actionType: ToggleMagboots
|
||||
icon: Clothing/Shoes/Boots/magboots.rsi/icon.png
|
||||
iconOn: Clothing/Shoes/Boots/magboots.rsi/icon-on.png
|
||||
name: "Toggle Magboots"
|
||||
description: "Turn your magboots on."
|
||||
filters:
|
||||
- tools
|
||||
keywords:
|
||||
- atmos
|
||||
- air
|
||||
behaviorType: Toggle
|
||||
behavior: !type:ToggleMagbootsAction { }
|
||||
@@ -15,6 +15,7 @@
|
||||
- category: Temperature
|
||||
- category: Hunger
|
||||
- category: Thirst
|
||||
- alertType: Magboots
|
||||
|
||||
- type: alert
|
||||
alertType: LowOxygen
|
||||
|
||||
5
Resources/Prototypes/Alerts/magboots.yml
Normal file
5
Resources/Prototypes/Alerts/magboots.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
- type: alert
|
||||
alertType: Magboots
|
||||
icon: { sprite: "/Textures/Clothing/Shoes/Boots/magboots.rsi", state: "icon-on" }
|
||||
name: "Magboots"
|
||||
description: You are immume to airflow, but slightly slower.
|
||||
@@ -1,15 +1,3 @@
|
||||
- type: entity
|
||||
parent: ClothingShoesBase
|
||||
id: ClothingShoesBootsMag
|
||||
name: magboots
|
||||
description: Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/Shoes/Boots/magboots.rsi
|
||||
state: icon
|
||||
- type: Clothing
|
||||
sprite: Clothing/Shoes/Boots/magboots.rsi
|
||||
|
||||
- type: entity
|
||||
parent: ClothingShoesBase
|
||||
id: ClothingShoesBootsWork
|
||||
|
||||
15
Resources/Prototypes/Entities/Clothing/Shoes/magboots.yml
Normal file
15
Resources/Prototypes/Entities/Clothing/Shoes/magboots.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
- type: entity
|
||||
parent: ClothingShoesBase
|
||||
id: ClothingShoesBootsMag
|
||||
name: magboots
|
||||
description: Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/Shoes/Boots/magboots.rsi
|
||||
state: icon
|
||||
- type: Clothing
|
||||
sprite: Clothing/Shoes/Boots/magboots.rsi
|
||||
- type: Magboots
|
||||
- type: ItemActions
|
||||
actions:
|
||||
- actionType: ToggleMagboots
|
||||
Reference in New Issue
Block a user