From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Date: Fri, 25 Apr 2025 18:18:23 +0000 (-0400)
Subject: PKA Modkits + Rebalance (#31247)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=f900d9f8b24f827722bd18fd919fc5a3afe4b753;p=space-station-14.git
PKA Modkits + Rebalance (#31247)
---
diff --git a/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeComponent.cs b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeComponent.cs
new file mode 100644
index 0000000000..3fd4b93eba
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeComponent.cs
@@ -0,0 +1,24 @@
+using Content.Shared.Tag;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Weapons.Ranged.Upgrades.Components;
+
+///
+/// Used to denote compatibility with . Does not contain explicit behavior.
+///
+[RegisterComponent, NetworkedComponent, Access(typeof(GunUpgradeSystem))]
+public sealed partial class GunUpgradeComponent : Component
+{
+ ///
+ /// Tags used to ensure mutually exclusive upgrades and duplicates are not stacked.
+ ///
+ [DataField]
+ public List> Tags = new();
+
+ ///
+ /// Markup added to the gun on examine to display the upgrades.
+ ///
+ [DataField]
+ public LocId ExamineText;
+}
diff --git a/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeDamageComponent.cs b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeDamageComponent.cs
new file mode 100644
index 0000000000..b69c7973a0
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeDamageComponent.cs
@@ -0,0 +1,17 @@
+using Content.Shared.Damage;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Weapons.Ranged.Upgrades.Components;
+
+///
+/// A for increasing the damage of a gun's projectile.
+///
+[RegisterComponent, NetworkedComponent, Access(typeof(GunUpgradeSystem))]
+public sealed partial class GunUpgradeDamageComponent : Component
+{
+ ///
+ /// Additional damage added onto the projectile's base damage.
+ ///
+ [DataField]
+ public DamageSpecifier Damage = new();
+}
diff --git a/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeFireRateComponent.cs b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeFireRateComponent.cs
new file mode 100644
index 0000000000..90556928d6
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeFireRateComponent.cs
@@ -0,0 +1,16 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Weapons.Ranged.Upgrades.Components;
+
+///
+/// A for increasing the firerate of a gun.
+///
+[RegisterComponent, NetworkedComponent, Access(typeof(GunUpgradeSystem))]
+public sealed partial class GunUpgradeFireRateComponent : Component
+{
+ ///
+ /// Multiplier for the speed of a gun's fire rate.
+ ///
+ [DataField]
+ public float Coefficient = 1;
+}
diff --git a/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeSpeedComponent.cs b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeSpeedComponent.cs
new file mode 100644
index 0000000000..82446d0bbc
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Upgrades/Components/GunUpgradeSpeedComponent.cs
@@ -0,0 +1,16 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Weapons.Ranged.Upgrades.Components;
+
+///
+/// A for increasing the speed of a gun's projectile.
+///
+[RegisterComponent, NetworkedComponent, Access(typeof(GunUpgradeSystem))]
+public sealed partial class GunUpgradeSpeedComponent : Component
+{
+ ///
+ /// Multiplier for the speed of a gun's projectile.
+ ///
+ [DataField]
+ public float Coefficient = 1;
+}
diff --git a/Content.Shared/Weapons/Ranged/Upgrades/Components/UpgradeableGunComponent.cs b/Content.Shared/Weapons/Ranged/Upgrades/Components/UpgradeableGunComponent.cs
new file mode 100644
index 0000000000..ef79c9c3e0
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Upgrades/Components/UpgradeableGunComponent.cs
@@ -0,0 +1,36 @@
+using Content.Shared.Whitelist;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Weapons.Ranged.Upgrades.Components;
+
+///
+/// Component that stores and manages that modify a given weapon.
+///
+[RegisterComponent, NetworkedComponent, Access(typeof(GunUpgradeSystem))]
+public sealed partial class UpgradeableGunComponent : Component
+{
+ ///
+ /// ID of container that holds upgrades.
+ ///
+ [DataField]
+ public string UpgradesContainerId = "upgrades";
+
+ ///
+ /// Whitelist which denotes the types of upgrades that can be added.
+ ///
+ [DataField]
+ public EntityWhitelist Whitelist = new();
+
+ ///
+ /// Sound played when upgrade is inserted.
+ ///
+ [DataField]
+ public SoundSpecifier? InsertSound = new SoundPathSpecifier("/Audio/Effects/thunk.ogg");
+
+ ///
+ /// The maximum amount of upgrades this gun can hold.
+ ///
+ [DataField]
+ public int MaxUpgradeCount = 2;
+}
diff --git a/Content.Shared/Weapons/Ranged/Upgrades/GunUpgradeSystem.cs b/Content.Shared/Weapons/Ranged/Upgrades/GunUpgradeSystem.cs
new file mode 100644
index 0000000000..b84446fea4
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Upgrades/GunUpgradeSystem.cs
@@ -0,0 +1,145 @@
+using System.Linq;
+using Content.Shared.Administration.Logs;
+using Content.Shared.Database;
+using Content.Shared.Examine;
+using Content.Shared.Interaction;
+using Content.Shared.Popups;
+using Content.Shared.Projectiles;
+using Content.Shared.Tag;
+using Content.Shared.Weapons.Ranged.Events;
+using Content.Shared.Weapons.Ranged.Systems;
+using Content.Shared.Weapons.Ranged.Upgrades.Components;
+using Content.Shared.Whitelist;
+using Robust.Shared.Audio.Systems;
+using Robust.Shared.Containers;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Weapons.Ranged.Upgrades;
+
+public sealed class GunUpgradeSystem : EntitySystem
+{
+ [Dependency] private readonly ISharedAdminLogManager _adminLog = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly SharedContainerSystem _container = default!;
+ [Dependency] private readonly SharedGunSystem _gun = default!;
+ [Dependency] private readonly EntityWhitelistSystem _entityWhitelist = default!;
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+
+ ///
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnInit);
+ SubscribeLocalEvent(OnAfterInteractUsing);
+ SubscribeLocalEvent(OnExamine);
+
+ SubscribeLocalEvent(RelayEvent);
+ SubscribeLocalEvent(RelayEvent);
+
+ SubscribeLocalEvent(OnFireRateRefresh);
+ SubscribeLocalEvent(OnSpeedRefresh);
+ SubscribeLocalEvent(OnDamageGunShot);
+ }
+
+ private void RelayEvent(Entity ent, ref T args) where T : notnull
+ {
+ foreach (var upgrade in GetCurrentUpgrades(ent))
+ {
+ RaiseLocalEvent(upgrade, ref args);
+ }
+ }
+
+ private void OnExamine(Entity ent, ref ExaminedEvent args)
+ {
+ using (args.PushGroup(nameof(UpgradeableGunComponent)))
+ {
+ foreach (var upgrade in GetCurrentUpgrades(ent))
+ {
+ args.PushMarkup(Loc.GetString(upgrade.Comp.ExamineText));
+ }
+ }
+ }
+
+ private void OnInit(Entity ent, ref ComponentInit args)
+ {
+ _container.EnsureContainer(ent, ent.Comp.UpgradesContainerId);
+ }
+
+ private void OnAfterInteractUsing(Entity ent, ref AfterInteractUsingEvent args)
+ {
+ if (args.Handled || !args.CanReach || !TryComp(args.Used, out var upgradeComponent))
+ return;
+
+ if (GetCurrentUpgrades(ent).Count >= ent.Comp.MaxUpgradeCount)
+ {
+ _popup.PopupPredicted(Loc.GetString("upgradeable-gun-popup-upgrade-limit"), ent, args.User);
+ return;
+ }
+
+ if (_entityWhitelist.IsWhitelistFail(ent.Comp.Whitelist, args.Used))
+ return;
+
+ if (GetCurrentUpgradeTags(ent).ToHashSet().IsSupersetOf(upgradeComponent.Tags))
+ {
+ _popup.PopupPredicted(Loc.GetString("upgradeable-gun-popup-already-present"), ent, args.User);
+ return;
+ }
+
+ _audio.PlayPredicted(ent.Comp.InsertSound, ent, args.User);
+ _popup.PopupClient(Loc.GetString("gun-upgrade-popup-insert", ("upgrade", args.Used),("gun", ent.Owner)), args.User);
+ _gun.RefreshModifiers(ent.Owner);
+ args.Handled = _container.Insert(args.Used, _container.GetContainer(ent, ent.Comp.UpgradesContainerId));
+
+ _adminLog.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.Used):player} inserted gun upgrade {ToPrettyString(args.Used)} into {ToPrettyString(ent.Owner)}.");
+ }
+
+ private void OnFireRateRefresh(Entity ent, ref GunRefreshModifiersEvent args)
+ {
+ args.FireRate *= ent.Comp.Coefficient;
+ }
+
+ private void OnSpeedRefresh(Entity ent, ref GunRefreshModifiersEvent args)
+ {
+ args.ProjectileSpeed *= ent.Comp.Coefficient;
+ }
+
+ private void OnDamageGunShot(Entity ent, ref GunShotEvent args)
+ {
+ foreach (var (ammo, _) in args.Ammo)
+ {
+ if (TryComp(ammo, out var proj))
+ proj.Damage += ent.Comp.Damage;
+ }
+ }
+
+ ///
+ /// Gets the entities inside the gun's upgrade container.
+ ///
+ public HashSet> GetCurrentUpgrades(Entity ent)
+ {
+ if (!_container.TryGetContainer(ent, ent.Comp.UpgradesContainerId, out var container))
+ return new HashSet>();
+
+ var upgrades = new HashSet>();
+ foreach (var contained in container.ContainedEntities)
+ {
+ if (TryComp(contained, out var upgradeComp))
+ upgrades.Add((contained, upgradeComp));
+ }
+
+ return upgrades;
+ }
+
+ ///
+ /// Gets the tags of the upgrades currently applied.
+ ///
+ public IEnumerable> GetCurrentUpgradeTags(Entity ent)
+ {
+ foreach (var upgrade in GetCurrentUpgrades(ent))
+ {
+ foreach (var tag in upgrade.Comp.Tags)
+ {
+ yield return tag;
+ }
+ }
+ }
+}
diff --git a/Resources/Locale/en-US/research/technologies.ftl b/Resources/Locale/en-US/research/technologies.ftl
index fc4f3e41e8..c3c1f1dad7 100644
--- a/Resources/Locale/en-US/research/technologies.ftl
+++ b/Resources/Locale/en-US/research/technologies.ftl
@@ -35,6 +35,7 @@ research-technology-wave-particle-harnessing = Wave Particle Harnessing
research-technology-advanced-riot-control = Advanced Riot Control
research-technology-portable-microfusion-weaponry = Portable Microfusion Weaponry
research-technology-experimental-battery-ammo = Experimental Battery Ammo
+research-technology-kinetic-modifications = Kinetic Modifications
research-technology-basic-shuttle-armament = Shuttle Basic Armament
research-technology-advanced-shuttle-weapon = Advanced Shuttle Weapons
research-technology-thermal-weaponry = Thermal Weaponry
diff --git a/Resources/Locale/en-US/weapons/ranged/upgrades.ftl b/Resources/Locale/en-US/weapons/ranged/upgrades.ftl
new file mode 100644
index 0000000000..c766b1e667
--- /dev/null
+++ b/Resources/Locale/en-US/weapons/ranged/upgrades.ftl
@@ -0,0 +1,7 @@
+upgradeable-gun-popup-already-present = Upgrade already installed!
+upgradeable-gun-popup-upgrade-limit = Max upgrades reached!
+gun-upgrade-popup-insert = Inserted {THE($upgrade)} into {THE($gun)}!
+
+gun-upgrade-examine-text-damage = This has upgraded [color=#ec9b2d][bold]damage.[/bold][/color]
+gun-upgrade-examine-text-range = This has upgraded [color=#2decec][bold]range.[/bold][/color]
+gun-upgrade-examine-text-reload = This has upgraded [color=#bbf134][bold]fire rate.[/bold][/color]
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml
index 4ce93028bf..dba4ec6789 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml
@@ -256,6 +256,12 @@
children:
- id: JetpackBlueFilled
- id: JetpackBlackFilled
+ - !type:GroupSelector
+ children:
+ - id: PKAUpgradeDamage
+ - id: PKAUpgradeRange
+ - id: PKAUpgradeFireRate
+
- type: entityTable
id: RandomGeneratorTable
diff --git a/Resources/Prototypes/Entities/Objects/Tools/pka_upgrade.yml b/Resources/Prototypes/Entities/Objects/Tools/pka_upgrade.yml
new file mode 100644
index 0000000000..e06597c0fa
--- /dev/null
+++ b/Resources/Prototypes/Entities/Objects/Tools/pka_upgrade.yml
@@ -0,0 +1,80 @@
+- type: entity
+ id: BasePKAUpgrade
+ parent: BaseItem
+ name: PKA modkit
+ description: A modkit for a proto-kinetic accelerator.
+ abstract: true
+ components:
+ - type: Sprite
+ sprite: Objects/Tools/upgrade.rsi
+ - type: Item
+ size: Small
+ - type: GunUpgrade
+ - type: StaticPrice
+ price: 750
+ - type: Tag
+ tags:
+ - PKAUpgrade
+
+- type: entity
+ id: PKAUpgradeDamage
+ parent: BasePKAUpgrade
+ name: PKA modkit (damage)
+ components:
+ - type: Sprite
+ layers:
+ - state: base
+ - state: overlay-1
+ color: "#ec9b2d"
+ - state: overlay-2
+ color: "#a71010"
+ - state: overlay-3
+ color: "#eb4c13"
+ - type: GunUpgrade
+ tags: [ GunUpgradeDamage ]
+ examineText: gun-upgrade-examine-text-damage
+ - type: GunUpgradeDamage
+ damage:
+ types:
+ Blunt: 10
+ Structural: 15
+
+- type: entity
+ id: PKAUpgradeRange
+ parent: BasePKAUpgrade
+ name: PKA modkit (range)
+ components:
+ - type: Sprite
+ layers:
+ - state: base
+ - state: overlay-1
+ color: "#2decec"
+ - state: overlay-2
+ color: "#1012a7"
+ - state: overlay-3
+ color: "#1373eb"
+ - type: GunUpgrade
+ tags: [ GunUpgradeRange ]
+ examineText: gun-upgrade-examine-text-range
+ - type: GunUpgradeSpeed
+ coefficient: 1.5
+
+- type: entity
+ id: PKAUpgradeFireRate
+ parent: BasePKAUpgrade
+ name: PKA modkit (fire rate)
+ components:
+ - type: Sprite
+ layers:
+ - state: base
+ - state: overlay-1
+ color: "#bbf134"
+ - state: overlay-2
+ color: "#07901b"
+ - state: overlay-3
+ color: "#9bf134"
+ - type: GunUpgrade
+ tags: [ GunUpgradeReloadSpeed ]
+ examineText: gun-upgrade-examine-text-reload
+ - type: GunUpgradeFireRate
+ coefficient: 1.5
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml
index f85e93b893..3107a50cfc 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml
@@ -7,7 +7,9 @@
sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi
- type: Item
sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi
- size: Normal
+ size: Large
+ shape:
+ - 0,0,2,1
- type: GunWieldBonus
minAngle: -43
maxAngle: -43
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/pka.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/pka.yml
index 409f622f89..9bf6268147 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/pka.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/pka.yml
@@ -13,3 +13,10 @@
map: [ "empty-icon" ]
# todo: add itemcomponent with inhandVisuals states using unused texture and animation assets in kinetic_accelerator.rsi
# todo: add clothingcomponent with clothingVisuals states using unused texture and animations assets in kinetic_accelerator.rsi
+ - type: UpgradeableGun
+ whitelist:
+ tags:
+ - PKAUpgrade
+ - type: ContainerContainer
+ containers:
+ upgrades: !type:Container
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml
index 31767ba8b3..bea1df8bca 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml
@@ -457,11 +457,11 @@
impactEffect: BulletImpactEffectKinetic
damage:
types:
- Blunt: 25
- Structural: 30
+ Blunt: 15
+ Structural: 15
# Short lifespan
- type: TimedDespawn
- lifetime: 0.4
+ lifetime: 0.170 # ~4 tiles of range.
- type: GatheringProjectile
- type: entity
diff --git a/Resources/Prototypes/Recipes/Lathes/Packs/science.yml b/Resources/Prototypes/Recipes/Lathes/Packs/science.yml
index c68b408cac..ef11d54ba0 100644
--- a/Resources/Prototypes/Recipes/Lathes/Packs/science.yml
+++ b/Resources/Prototypes/Recipes/Lathes/Packs/science.yml
@@ -53,6 +53,9 @@
- WeaponPistolCHIMP
- WeaponForceGun
- WeaponProtoKineticAccelerator
+ - PKAUpgradeDamage
+ - PKAUpgradeRange
+ - PKAUpgradeFireRate
- WeaponTetherGun
- WeaponGauntletGorilla
diff --git a/Resources/Prototypes/Recipes/Lathes/Packs/shared.yml b/Resources/Prototypes/Recipes/Lathes/Packs/shared.yml
index 6fb00c0257..07bdc5f2ea 100644
--- a/Resources/Prototypes/Recipes/Lathes/Packs/shared.yml
+++ b/Resources/Prototypes/Recipes/Lathes/Packs/shared.yml
@@ -59,3 +59,6 @@
id: SalvageSecurityWeapons
recipes:
- WeaponProtoKineticAccelerator
+ - PKAUpgradeDamage
+ - PKAUpgradeRange
+ - PKAUpgradeFireRate
diff --git a/Resources/Prototypes/Recipes/Lathes/salvage.yml b/Resources/Prototypes/Recipes/Lathes/salvage.yml
index 02eeb4bafb..517735a24f 100644
--- a/Resources/Prototypes/Recipes/Lathes/salvage.yml
+++ b/Resources/Prototypes/Recipes/Lathes/salvage.yml
@@ -68,3 +68,37 @@
Plastic: 200
Silver: 200
Diamond: 100
+
+- type: latheRecipe
+ id: PKAUpgradeDamage
+ result: PKAUpgradeDamage
+ categories:
+ - Weapons
+ completetime: 5
+ materials:
+ Steel: 1500
+ Gold: 500
+ Silver: 500
+
+- type: latheRecipe
+ id: PKAUpgradeRange
+ result: PKAUpgradeRange
+ categories:
+ - Weapons
+ completetime: 5
+ materials:
+ Steel: 1500
+ Gold: 500
+ Silver: 500
+
+- type: latheRecipe
+ id: PKAUpgradeFireRate
+ result: PKAUpgradeFireRate
+ categories:
+ - Weapons
+ completetime: 5
+ materials:
+ Steel: 1500
+ Gold: 500
+ Silver: 500
+
diff --git a/Resources/Prototypes/Research/arsenal.yml b/Resources/Prototypes/Research/arsenal.yml
index b848ae0998..7ba7cea9da 100644
--- a/Resources/Prototypes/Research/arsenal.yml
+++ b/Resources/Prototypes/Research/arsenal.yml
@@ -155,6 +155,20 @@
recipeUnlocks:
- WeaponXrayCannon
+- type: technology
+ id: KineticModifications
+ name: research-technology-kinetic-modifications
+ icon:
+ sprite: Objects/Tools/upgrade.rsi
+ state: display
+ discipline: Arsenal
+ tier: 2
+ cost: 7500
+ recipeUnlocks:
+ - PKAUpgradeDamage
+ - PKAUpgradeRange
+ - PKAUpgradeFireRate
+
- type: technology
id: BasicShuttleArmament
name: research-technology-basic-shuttle-armament
diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml
index c8e376d109..6eb882b984 100644
--- a/Resources/Prototypes/tags.yml
+++ b/Resources/Prototypes/tags.yml
@@ -617,6 +617,15 @@
- type: Tag
id: GuideEmbeded
+- type: Tag
+ id: GunUpgradeDamage
+
+- type: Tag
+ id: GunUpgradeRange
+
+- type: Tag
+ id: GunUpgradeReloadSpeed
+
- type: Tag
id: Hamster
@@ -981,6 +990,9 @@
- type: Tag
id: Pizza
+- type: Tag
+ id: PKAUpgrade
+
- type: Tag
id: PlantAnalyzer
diff --git a/Resources/Textures/Objects/Tools/upgrade.rsi/base.png b/Resources/Textures/Objects/Tools/upgrade.rsi/base.png
new file mode 100644
index 0000000000..e18a16b6cf
Binary files /dev/null and b/Resources/Textures/Objects/Tools/upgrade.rsi/base.png differ
diff --git a/Resources/Textures/Objects/Tools/upgrade.rsi/display.png b/Resources/Textures/Objects/Tools/upgrade.rsi/display.png
new file mode 100644
index 0000000000..34f48ebe58
Binary files /dev/null and b/Resources/Textures/Objects/Tools/upgrade.rsi/display.png differ
diff --git a/Resources/Textures/Objects/Tools/upgrade.rsi/meta.json b/Resources/Textures/Objects/Tools/upgrade.rsi/meta.json
new file mode 100644
index 0000000000..17fd84c2e9
--- /dev/null
+++ b/Resources/Textures/Objects/Tools/upgrade.rsi/meta.json
@@ -0,0 +1,28 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from https://github.com/tgstation/tgstation at commit 6665eec76c98a4f3f89bebcd10b34b47dcc0b8ae.",
+ "size":
+ {
+ "x": 32,
+ "y": 32
+ },
+ "states":
+ [
+ {
+ "name": "base"
+ },
+ {
+ "name": "overlay-1"
+ },
+ {
+ "name": "overlay-2"
+ },
+ {
+ "name": "overlay-3"
+ },
+ {
+ "name": "display"
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-1.png b/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-1.png
new file mode 100644
index 0000000000..89d0eea7eb
Binary files /dev/null and b/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-1.png differ
diff --git a/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-2.png b/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-2.png
new file mode 100644
index 0000000000..cbcaa4c099
Binary files /dev/null and b/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-2.png differ
diff --git a/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-3.png b/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-3.png
new file mode 100644
index 0000000000..7f554f4cd0
Binary files /dev/null and b/Resources/Textures/Objects/Tools/upgrade.rsi/overlay-3.png differ