diff --git a/Content.Client/PowerCell/PowerCellSystem.cs b/Content.Client/PowerCell/PowerCellSystem.cs index ec69f0d56b..1423dffaa3 100644 --- a/Content.Client/PowerCell/PowerCellSystem.cs +++ b/Content.Client/PowerCell/PowerCellSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.PowerCell; +using Content.Shared.PowerCell.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; @@ -15,6 +16,29 @@ public sealed class PowerCellSystem : SharedPowerCellSystem SubscribeLocalEvent(OnPowerCellVisualsChange); } + /// + public override bool HasActivatableCharge(EntityUid uid, PowerCellDrawComponent? battery = null, PowerCellSlotComponent? cell = null, + EntityUid? user = null) + { + if (!Resolve(uid, ref battery, ref cell, false)) + return true; + + return battery.CanUse; + } + + /// + public override bool HasDrawCharge( + EntityUid uid, + PowerCellDrawComponent? battery = null, + PowerCellSlotComponent? cell = null, + EntityUid? user = null) + { + if (!Resolve(uid, ref battery, ref cell, false)) + return true; + + return battery.CanDraw; + } + private void OnPowerCellVisualsChange(EntityUid uid, PowerCellVisualsComponent component, ref AppearanceChangeEvent args) { if (args.Sprite == null) diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index d041f8ee9d..dd9f1ec91e 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -16,6 +16,7 @@ using Content.Shared.Mind; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; +using Content.Shared.PowerCell; using Content.Shared.Timing; using Content.Shared.Toggleable; using Robust.Shared.Player; diff --git a/Content.Server/PowerCell/PowerCellSystem.Draw.cs b/Content.Server/PowerCell/PowerCellSystem.Draw.cs index 9d73138346..c6d8e1e709 100644 --- a/Content.Server/PowerCell/PowerCellSystem.Draw.cs +++ b/Content.Server/PowerCell/PowerCellSystem.Draw.cs @@ -22,7 +22,7 @@ public sealed partial class PowerCellSystem if (!comp.Drawing) continue; - if (_timing.CurTime < comp.NextUpdateTime) + if (Timing.CurTime < comp.NextUpdateTime) continue; comp.NextUpdateTime += Delay; diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index 1cfb4d1d70..b424f34de5 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -1,9 +1,5 @@ -using Content.Server.Administration.Logs; -using Content.Server.Chemistry.EntitySystems; -using Content.Server.Explosion.EntitySystems; using Content.Server.Emp; using Content.Server.Power.Components; -using Content.Shared.Database; using Content.Shared.Examine; using Content.Shared.PowerCell; using Content.Shared.PowerCell.Components; @@ -15,7 +11,6 @@ using Content.Server.Power.EntitySystems; using Content.Server.UserInterface; using Content.Shared.Containers.ItemSlots; using Content.Shared.Popups; -using Robust.Shared.Timing; namespace Content.Server.PowerCell; @@ -24,7 +19,6 @@ namespace Content.Server.PowerCell; /// public sealed partial class PowerCellSystem : SharedPowerCellSystem { - [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly ActivatableUISystem _activatable = default!; [Dependency] private readonly BatterySystem _battery = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; @@ -95,12 +89,8 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem } #region Activatable - - /// - /// Returns whether the entity has a slotted battery and charge. - /// - /// Popup to this user with the relevant detail if specified. - public bool HasActivatableCharge(EntityUid uid, PowerCellDrawComponent? battery = null, PowerCellSlotComponent? cell = null, EntityUid? user = null) + /// + public override bool HasActivatableCharge(EntityUid uid, PowerCellDrawComponent? battery = null, PowerCellSlotComponent? cell = null, EntityUid? user = null) { // Default to true if we don't have the components. if (!Resolve(uid, ref battery, ref cell, false)) @@ -108,6 +98,7 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem return HasCharge(uid, battery.UseRate, cell, user); } + /// /// Tries to use the for this entity. /// @@ -128,11 +119,12 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem return false; } - /// - /// Whether the power cell has any power at all for the draw rate. - /// - public bool HasDrawCharge(EntityUid uid, PowerCellDrawComponent? battery = null, - PowerCellSlotComponent? cell = null, EntityUid? user = null) + /// + public override bool HasDrawCharge( + EntityUid uid, + PowerCellDrawComponent? battery = null, + PowerCellSlotComponent? cell = null, + EntityUid? user = null) { if (!Resolve(uid, ref battery, ref cell, false)) return true; @@ -142,15 +134,6 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem #endregion - public void SetPowerCellDrawEnabled(EntityUid uid, bool enabled, PowerCellDrawComponent? component = null) - { - if (!Resolve(uid, ref component, false) || enabled == component.Drawing) - return; - - component.Drawing = enabled; - component.NextUpdateTime = _timing.CurTime; - } - /// /// Returns whether the entity has a slotted battery and charge for the requested action. /// diff --git a/Content.Server/Weapons/Misc/TetherGunSystem.cs b/Content.Server/Weapons/Misc/TetherGunSystem.cs index 44d0c49e3f..f6aafe376d 100644 --- a/Content.Server/Weapons/Misc/TetherGunSystem.cs +++ b/Content.Server/Weapons/Misc/TetherGunSystem.cs @@ -1,4 +1,5 @@ using Content.Server.PowerCell; +using Content.Shared.PowerCell; using Content.Shared.Weapons.Misc; using Robust.Shared.Physics.Components; diff --git a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs index 74b5369aa3..66ff5c624a 100644 --- a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs +++ b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs @@ -1,6 +1,11 @@ +using Content.Shared.Actions; +using Content.Shared.Clothing.Components; using Content.Shared.Examine; +using Content.Shared.IdentityManagement; using Content.Shared.Inventory; using Content.Shared.Movement.Systems; +using Content.Shared.PowerCell; +using Content.Shared.Toggleable; using Content.Shared.Verbs; using Robust.Shared.Containers; using Robust.Shared.GameStates; @@ -10,9 +15,13 @@ namespace Content.Shared.Clothing; public sealed class ClothingSpeedModifierSystem : EntitySystem { - [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly ClothingSpeedModifierSystem _clothingSpeedModifier = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly ExamineSystemShared _examine = default!; + [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; + [Dependency] private readonly SharedPowerCellSystem _powerCell = default!; public override void Initialize() { @@ -22,6 +31,12 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent>(OnRefreshMoveSpeed); SubscribeLocalEvent>(OnClothingVerbExamine); + + SubscribeLocalEvent>(AddToggleVerb); + SubscribeLocalEvent(OnGetActions); + SubscribeLocalEvent(OnToggleSpeed); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnPowerCellSlotEmpty); } // Public API @@ -34,7 +49,7 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem if (component.Enabled != enabled) { component.Enabled = enabled; - Dirty(component); + Dirty(uid, component); // inventory system will automatically hook into the event raised by this and update accordingly if (_container.TryGetContainingContainer(uid, out var container)) @@ -126,4 +141,61 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem _examine.AddDetailedExamineVerb(args, component, msg, Loc.GetString("clothing-speed-examinable-verb-text"), "/Textures/Interface/VerbIcons/outfit.svg.192dpi.png", Loc.GetString("clothing-speed-examinable-verb-message")); } + + private void OnMapInit(Entity uid, ref MapInitEvent args) + { + _actions.AddAction(uid, ref uid.Comp.ToggleActionEntity, uid.Comp.ToggleAction); + } + + private void OnToggleSpeed(Entity uid, ref ToggleClothingSpeedEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + SetSpeedToggleEnabled(uid, !uid.Comp.Enabled, args.Performer); + } + + private void SetSpeedToggleEnabled(Entity uid, bool value, EntityUid? user) + { + if (uid.Comp.Enabled == value) + return; + + TryComp(uid, out var draw); + if (value && !_powerCell.HasDrawCharge(uid, draw, user: user)) + return; + + uid.Comp.Enabled = value; + + _appearance.SetData(uid, ToggleVisuals.Toggled, uid.Comp.Enabled); + _actions.SetToggled(uid.Comp.ToggleActionEntity, uid.Comp.Enabled); + _clothingSpeedModifier.SetClothingSpeedModifierEnabled(uid.Owner, uid.Comp.Enabled); + _powerCell.SetPowerCellDrawEnabled(uid, uid.Comp.Enabled, draw); + Dirty(uid, uid.Comp); + } + + private void AddToggleVerb(Entity uid, ref GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + var user = args.User; + ActivationVerb verb = new() + { + Text = Loc.GetString("toggle-clothing-verb-text", + ("entity", Identity.Entity(uid, EntityManager))), + Act = () => SetSpeedToggleEnabled(uid, !uid.Comp.Enabled, user) + }; + args.Verbs.Add(verb); + } + + private void OnGetActions(Entity uid, ref GetItemActionsEvent args) + { + args.AddAction(ref uid.Comp.ToggleActionEntity, uid.Comp.ToggleAction); + } + + private void OnPowerCellSlotEmpty(Entity uid, ref PowerCellSlotEmptyEvent args) + { + SetSpeedToggleEnabled(uid, false, null); + } } diff --git a/Content.Shared/Clothing/Components/ToggleClothingSpeedComponent.cs b/Content.Shared/Clothing/Components/ToggleClothingSpeedComponent.cs new file mode 100644 index 0000000000..90b2d7322e --- /dev/null +++ b/Content.Shared/Clothing/Components/ToggleClothingSpeedComponent.cs @@ -0,0 +1,35 @@ +using Content.Shared.Actions; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Clothing.Components; + +/// +/// This is used for a clothing item that gives a speed modification that is toggleable. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(ClothingSpeedModifierSystem)), AutoGenerateComponentState] +public sealed partial class ToggleClothingSpeedComponent : Component +{ + /// + /// The action for toggling the clothing. + /// + [DataField] + public EntProtoId ToggleAction = "ActionToggleSpeedBoots"; + + /// + /// The action entity + /// + [DataField, AutoNetworkedField] + public EntityUid? ToggleActionEntity; + + /// + /// The state of the toggle. + /// + [DataField, AutoNetworkedField] + public bool Enabled; +} + +public sealed partial class ToggleClothingSpeedEvent : InstantActionEvent +{ + +} diff --git a/Content.Server/PowerCell/PowerCellSlotEmptyEvent.cs b/Content.Shared/PowerCell/PowerCellSlotEmptyEvent.cs similarity index 83% rename from Content.Server/PowerCell/PowerCellSlotEmptyEvent.cs rename to Content.Shared/PowerCell/PowerCellSlotEmptyEvent.cs index b2930ee50f..e4075175ae 100644 --- a/Content.Server/PowerCell/PowerCellSlotEmptyEvent.cs +++ b/Content.Shared/PowerCell/PowerCellSlotEmptyEvent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.PowerCell; +namespace Content.Shared.PowerCell; /// /// Raised directed on an entity when its active power cell has no more charge to supply. diff --git a/Content.Shared/PowerCell/SharedPowerCellSystem.cs b/Content.Shared/PowerCell/SharedPowerCellSystem.cs index 57af440360..508bfc85f0 100644 --- a/Content.Shared/PowerCell/SharedPowerCellSystem.cs +++ b/Content.Shared/PowerCell/SharedPowerCellSystem.cs @@ -2,24 +2,26 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.PowerCell.Components; using Content.Shared.Rejuvenate; using Robust.Shared.Containers; +using Robust.Shared.Timing; namespace Content.Shared.PowerCell; public abstract class SharedPowerCellSystem : EntitySystem { + [Dependency] protected readonly IGameTiming Timing = default!; [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnRejuventate); + SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(OnCellInserted); SubscribeLocalEvent(OnCellRemoved); SubscribeLocalEvent(OnCellInsertAttempt); } - private void OnRejuventate(EntityUid uid, PowerCellSlotComponent component, RejuvenateEvent args) + private void OnRejuvenate(EntityUid uid, PowerCellSlotComponent component, RejuvenateEvent args) { if (!_itemSlots.TryGetSlot(uid, component.CellSlotId, out var itemSlot) || !itemSlot.Item.HasValue) return; @@ -60,4 +62,35 @@ public abstract class SharedPowerCellSystem : EntitySystem _appearance.SetData(uid, PowerCellSlotVisuals.Enabled, false); RaiseLocalEvent(uid, new PowerCellChangedEvent(true), false); } + + public void SetPowerCellDrawEnabled(EntityUid uid, bool enabled, PowerCellDrawComponent? component = null) + { + if (!Resolve(uid, ref component, false) || enabled == component.Drawing) + return; + + component.Drawing = enabled; + component.NextUpdateTime = Timing.CurTime; + } + + /// + /// Returns whether the entity has a slotted battery and charge. + /// + /// + /// + /// + /// Popup to this user with the relevant detail if specified. + public abstract bool HasActivatableCharge( + EntityUid uid, + PowerCellDrawComponent? battery = null, + PowerCellSlotComponent? cell = null, + EntityUid? user = null); + + /// + /// Whether the power cell has any power at all for the draw rate. + /// + public abstract bool HasDrawCharge( + EntityUid uid, + PowerCellDrawComponent? battery = null, + PowerCellSlotComponent? cell = null, + EntityUid? user = null); } diff --git a/Resources/Locale/en-US/clothing/components/toggleable-clothing-component.ftl b/Resources/Locale/en-US/clothing/components/toggleable-clothing-component.ftl index eb342d028d..746eea4a28 100644 --- a/Resources/Locale/en-US/clothing/components/toggleable-clothing-component.ftl +++ b/Resources/Locale/en-US/clothing/components/toggleable-clothing-component.ftl @@ -1,2 +1,3 @@ +toggle-clothing-verb-text = Toggle {CAPITALIZE($entity)} -toggleable-clothing-remove-first = You have to unequip {$entity} first. \ No newline at end of file +toggleable-clothing-remove-first = You have to unequip {$entity} first. diff --git a/Resources/Locale/en-US/research/technologies.ftl b/Resources/Locale/en-US/research/technologies.ftl index 0f8a657aa4..7f90f134ea 100644 --- a/Resources/Locale/en-US/research/technologies.ftl +++ b/Resources/Locale/en-US/research/technologies.ftl @@ -70,3 +70,4 @@ research-technology-meat-manipulation = Meat Manipulation research-technology-honk-mech = H.O.N.K. Mech research-technology-advanced-spray = Advanced Spray research-technology-bluespace-cargo-transport = Bluespace Cargo Transport +research-technology-quantum-fiber-weaving = Quantum Fiber Weaving diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml b/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml index e531e212e9..30cf878ad1 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml @@ -69,3 +69,52 @@ sprite: Clothing/Shoes/Misc/damedaneshoes.rsi - type: Clothing sprite: Clothing/Shoes/Misc/damedaneshoes.rsi + +- type: entity + parent: [ClothingShoesBase, PowerCellSlotSmallItem] + id: ClothingShoesBootsSpeed + name: speed boots + description: High-tech boots woven with quantum fibers, able to convert electricity into pure speed! + components: + - type: Sprite + sprite: Clothing/Shoes/Boots/speedboots.rsi + layers: + - state: icon + map: [ "enum.ToggleVisuals.Layer" ] + - type: Clothing + sprite: Clothing/Shoes/Boots/speedboots.rsi + - type: ToggleClothingSpeed + toggleAction: ActionToggleSpeedBoots + - type: ClothingSpeedModifier + walkModifier: 1.25 + sprintModifier: 1.25 + enabled: false + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: {state: icon-on} + False: {state: icon} + - type: StaticPrice + price: 500 + - type: PowerCellDraw + drawRate: 4 + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + - type: Tag + tags: [] + +- type: entity + id: ActionToggleSpeedBoots + name: Toggle Speed Boots + description: Toggles the speed boots on and off. + noSpawn: true + components: + - type: InstantAction + itemIconStyle: NoItem + event: !type:ToggleClothingSpeedEvent + icon: { sprite: Clothing/Shoes/Boots/speedboots.rsi, state: icon } + iconOn: { sprite: Clothing/Shoes/Boots/speedboots.rsi, state: icon-on } diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index b82f3f6828..5be2f17c9b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -255,6 +255,7 @@ - SynthesizerInstrument - RPED - ClothingShoesBootsMag + - ClothingShoesBootsSpeed - NodeScanner - HolofanProjector - BluespaceBeaker diff --git a/Resources/Prototypes/Recipes/Lathes/misc.yml b/Resources/Prototypes/Recipes/Lathes/misc.yml index 5aff63ed92..266cdf6e51 100644 --- a/Resources/Prototypes/Recipes/Lathes/misc.yml +++ b/Resources/Prototypes/Recipes/Lathes/misc.yml @@ -85,6 +85,15 @@ Steel: 1000 Plastic: 500 +- type: latheRecipe + id: ClothingShoesBootsSpeed + result: ClothingShoesBootsSpeed + completetime: 2 + materials: + Steel: 1500 + Plastic: 1000 + Silver: 500 + - type: latheRecipe id: ModularReceiver result: ModularReceiver diff --git a/Resources/Prototypes/Research/civilianservices.yml b/Resources/Prototypes/Research/civilianservices.yml index d82090719e..c49ba37160 100644 --- a/Resources/Prototypes/Research/civilianservices.yml +++ b/Resources/Prototypes/Research/civilianservices.yml @@ -204,3 +204,15 @@ cost: 15000 recipeUnlocks: - CargoTelepadMachineCircuitboard + +- type: technology + id: QuantumFiberWeaving + name: research-technology-quantum-fiber-weaving + icon: + sprite: Clothing/Shoes/Boots/speedboots.rsi + state: icon + discipline: CivilianServices + tier: 3 + cost: 10000 + recipeUnlocks: + - ClothingShoesBootsSpeed diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/equipped-FEET.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/equipped-FEET.png new file mode 100644 index 0000000000..70618221d7 Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/equipped-FEET.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/icon-on.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/icon-on.png new file mode 100644 index 0000000000..9f487123c0 Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/icon-on.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/icon.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/icon.png new file mode 100644 index 0000000000..2fda82988f Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/inhand-left.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/inhand-left.png new file mode 100644 index 0000000000..fbb48f5824 Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/inhand-left.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/inhand-right.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/inhand-right.png new file mode 100644 index 0000000000..92620635af Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/inhand-right.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json new file mode 100644 index 0000000000..3aa61e31c5 --- /dev/null +++ b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json @@ -0,0 +1,41 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "Created by EmoGarbage404", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "equipped-FEET", + "directions": 4 + }, + { + "name": "on-equipped-FEET", + "directions": 4 + }, + { + "name": "icon" + }, + { + "name": "icon-on" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4 + }, + { + "name": "on-inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-equipped-FEET.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-equipped-FEET.png new file mode 100644 index 0000000000..b8b1846e16 Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-equipped-FEET.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-inhand-left.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-inhand-left.png new file mode 100644 index 0000000000..3077ae093f Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-inhand-left.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-inhand-right.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-inhand-right.png new file mode 100644 index 0000000000..ee0c1be1dd Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-inhand-right.png differ