From 0536fc8645cddd4b757713e2ade3a11efa0011fe Mon Sep 17 00:00:00 2001 From: RedFoxIV <38788538+RedFoxIV@users.noreply.github.com> Date: Sat, 28 Jun 2025 11:31:07 +0300 Subject: [PATCH] Fuselage rust stage 2 (#629) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * the definition of insanity * the definition of insanity * the definition of insanity * we have hullrot at home * maybe the real hullrot was the friends we made along the way * john hullrot * i am going to hullroooooot * it's hullrotver * we're so hullback * we're rotting the hull with this one * hullmerge * the hullrot is leaking * never gonna rot you up * hullfresh * john starsector * god i wish we had grid collision damage * you can tell I am very tired because I stopped forcing a hullrot joke into every commit message * hr * this is a surprise sprite that will help us later * motherfucker * i have nothing good to say * still nothing * brb * random letter random letter random letter dash random number random number random number * ass * blast * ffs * fcuk * RE: ffs * RE: RE: ffs * гнида жестяная * continue * i hate tests * i love tests * slide to the right * i hate tests again * what the fuck * ты шиз? * ?? * bbgun --- .../Shuttles/UI/ShuttleNavControl.xaml.cs | 5 +- .../Weapons/Ranged/Systems/GunSystem.cs | 9 +- .../DollyMixture/DollyMixtureComponent.cs | 39 -- .../_White/DollyMixture/DollyMixtureSystem.cs | 154 ++++++-- .../_White/Guns/ModularTurretSystem.cs | 5 + Content.Server/Entry/IgnoredComponents.cs | 1 - .../Components/SpawnOnTriggerComponent.cs | 6 + .../Explosion/EntitySystems/TriggerSystem.cs | 11 +- Content.Server/Language/LanguageSystem.cs | 4 +- .../EntitySystems/UpgradeBatterySystem.cs | 2 +- .../Salvage/SalvageSystem.Magnet.cs | 1 + .../Ranged/Systems/GunSystem.Battery.cs | 56 ++- .../Weapons/Ranged/Systems/GunSystem.cs | 161 ++++---- .../_White/DollyMixture/DollyMixtureSystem.cs | 8 + .../Guns/ModularTurret/ModularTurretSystem.cs | 53 +++ .../Systems/RemoteControlSystem.Console.cs | 41 +- .../Systems/RemoteControlSystem.Target.cs | 28 +- .../Systems/RemoteControlSystem.User.cs | 10 +- .../Systems/RemoteControlSystem.cs | 46 +-- .../Mech/EntitySystems/SharedMechSystem.cs | 10 + .../Components/InputMoverComponent.cs | 2 +- .../Components/SharedRadioJammerComponent.cs | 6 +- .../Systems/SharedShuttleSystem.IFF.cs | 1 + .../Weapons/Ranged/HitscanPrototype.cs | 9 + .../Ranged/Systems/SharedGunSystem.Battery.cs | 21 + .../Weapons/Ranged/Systems/SharedGunSystem.cs | 2 +- .../DollyMixture/DollyMixtureComponent.cs | 40 ++ .../DollyMixture/SharedDollyMixtureSystem.cs | 29 ++ .../AmmoProviderRedirectComponents.cs | 6 + .../AmmoProviderRedirectSystem.cs | 21 + .../ModularTurret/ModularTurretComponents.cs | 28 ++ .../SharedModularTurretSystem.cs | 61 +++ ...leContainerBatteryAmmoProviderComponent.cs | 36 ++ .../_White/Guns/ProjectileDamageModifier.cs | 53 +++ .../_White/Lock/LockDeviceLinksComponent.cs | 23 ++ .../RemoteControlConsoleComponent.cs | 2 +- .../RemoteControlTargetComponent.cs | 4 +- .../Components/RemoteControlUserComponent.cs | 2 +- Resources/Prototypes/Damage/modifier_sets.yml | 14 +- .../Entities/Effects/admin_triggers.yml | 31 +- .../Specific/Mech/Weapons/Gun/base.yml | 2 +- .../_White/Catalog/Cargo/ship_weapons.yml | 119 ++++++ .../_White/DeviceLinking/sink_ports.yml | 12 +- .../_White/DeviceLinking/source_ports.yml | 5 - .../Objects/Devices/Circuitboards/misc.yml | 7 +- .../Objects/Weapons/Guns/Ship/weapons.yml | 369 ++++++++++++++++++ .../Weapons/Guns/Turrets/ship_turrets.yml | 176 +++++++++ .../Weapons/Guns/Turrets/turret_base.yml | 10 +- .../Weapons/Guns/Turrets/turrets_energy.yml | 36 -- ...rets_ballistic.yml => universal_mount.yml} | 46 ++- .../{computers.yml => remote_control.yml} | 2 +- .../_White/Ghosts/custom_ghosts.yml | 102 +---- .../_White/Innate/InnateMassScanner.yml | 62 +++ .../Guns/Projectiles/projectiles.rsi/fast.png | Bin 0 -> 141 bytes .../projectiles.rsi/impact_fast.png | Bin 0 -> 155 bytes .../projectiles.rsi/impact_mining_laser.png | Bin 0 -> 1149 bytes .../Projectiles/projectiles.rsi/meta.json | 101 +++++ .../projectiles.rsi/mining_laser.png | Bin 0 -> 213 bytes .../projectiles.rsi/muzzle_fast.png | Bin 0 -> 497 bytes .../projectiles.rsi/muzzle_mining_laser.png | Bin 0 -> 680 bytes .../Guns/Turrets/IR_laser.rsi/dollymix1.png | Bin 0 -> 195 bytes .../Guns/Turrets/IR_laser.rsi/dollymix2.png | Bin 0 -> 336 bytes .../Guns/Turrets/IR_laser.rsi/dollymix3.png | Bin 0 -> 336 bytes .../IR_laser.rsi/dollymix4-unshaded.png | Bin 0 -> 158 bytes .../Guns/Turrets/IR_laser.rsi/dollymix4.png | Bin 0 -> 319 bytes .../Guns/Turrets/IR_laser.rsi/dollymix5.png | Bin 0 -> 165 bytes .../Guns/Turrets/IR_laser.rsi/icon.png | Bin 0 -> 379 bytes .../Guns/Turrets/IR_laser.rsi/meta.json | 18 + .../Turrets/annihilator.rsi/dollymix1.png | Bin 0 -> 175 bytes .../Turrets/annihilator.rsi/dollymix2.png | Bin 0 -> 193 bytes .../Turrets/annihilator.rsi/dollymix3.png | Bin 0 -> 202 bytes .../Turrets/annihilator.rsi/dollymix4.png | Bin 0 -> 209 bytes .../Turrets/annihilator.rsi/dollymix5.png | Bin 0 -> 179 bytes .../Turrets/annihilator.rsi/dollymix6.png | Bin 0 -> 172 bytes .../Turrets/annihilator.rsi/dollymix7.png | Bin 0 -> 154 bytes .../Turrets/annihilator.rsi/dollymix8.png | Bin 0 -> 133 bytes .../Guns/Turrets/annihilator.rsi/icon.png | Bin 0 -> 257 bytes .../Guns/Turrets/annihilator.rsi/meta.json | 20 + .../Guns/Turrets/blaster.rsi/dollymix1.png | Bin 0 -> 165 bytes .../Guns/Turrets/blaster.rsi/dollymix2.png | Bin 0 -> 256 bytes .../Guns/Turrets/blaster.rsi/dollymix3.png | Bin 0 -> 298 bytes .../Guns/Turrets/blaster.rsi/dollymix4.png | Bin 0 -> 286 bytes .../Guns/Turrets/blaster.rsi/dollymix5.png | Bin 0 -> 161 bytes .../Weapons/Guns/Turrets/blaster.rsi/icon.png | Bin 0 -> 411 bytes .../Guns/Turrets/blaster.rsi/meta.json | 17 + .../Guns/Turrets/hmg.rsi/dollymix1.png | Bin 0 -> 177 bytes .../Guns/Turrets/hmg.rsi/dollymix2.png | Bin 0 -> 179 bytes .../Guns/Turrets/hmg.rsi/dollymix3.png | Bin 0 -> 163 bytes .../Guns/Turrets/hmg.rsi/dollymix4.png | Bin 0 -> 151 bytes .../Weapons/Guns/Turrets/hmg.rsi/icon.png | Bin 0 -> 244 bytes .../Weapons/Guns/Turrets/hmg.rsi/meta.json | 16 + .../Guns/Turrets/hotspot.rsi/dollymix1.png | Bin 0 -> 137 bytes .../Guns/Turrets/hotspot.rsi/dollymix2.png | Bin 0 -> 192 bytes .../Guns/Turrets/hotspot.rsi/dollymix3.png | Bin 0 -> 193 bytes .../Guns/Turrets/hotspot.rsi/dollymix4.png | Bin 0 -> 135 bytes .../Guns/Turrets/hotspot.rsi/dollymix5.png | Bin 0 -> 134 bytes .../Weapons/Guns/Turrets/hotspot.rsi/icon.png | Bin 0 -> 286 bytes .../Guns/Turrets/hotspot.rsi/meta.json | 17 + .../Turrets/mining_laser.rsi/dollymix1.png | Bin 0 -> 251 bytes .../Turrets/mining_laser.rsi/dollymix2.png | Bin 0 -> 245 bytes .../mining_laser.rsi/dollymix3-unshaded.png | Bin 0 -> 133 bytes .../Turrets/mining_laser.rsi/dollymix3.png | Bin 0 -> 301 bytes .../Turrets/mining_laser.rsi/dollymix4.png | Bin 0 -> 372 bytes .../mining_laser.rsi/dollymix5-unshaded.png | Bin 0 -> 129 bytes .../Turrets/mining_laser.rsi/dollymix5.png | Bin 0 -> 395 bytes .../Turrets/mining_laser.rsi/dollymix6.png | Bin 0 -> 296 bytes .../mining_laser.rsi/dollymix7-unshaded.png | Bin 0 -> 149 bytes .../Turrets/mining_laser.rsi/dollymix7.png | Bin 0 -> 324 bytes .../Turrets/mining_laser.rsi/dollymix8.png | Bin 0 -> 293 bytes .../mining_laser.rsi/dollymix9-unshaded.png | Bin 0 -> 128 bytes .../Turrets/mining_laser.rsi/dollymix9.png | Bin 0 -> 327 bytes .../Guns/Turrets/mining_laser.rsi/icon.png | Bin 0 -> 620 bytes .../Guns/Turrets/mining_laser.rsi/meta.json | 25 ++ .../Weapons/Guns/Turrets/mounts.rsi/light.png | Bin 0 -> 234 bytes .../Guns/Turrets/mounts.rsi/light_broken.png | Bin 0 -> 429 bytes .../Weapons/Guns/Turrets/mounts.rsi/meta.json | 13 + .../rift_lance.rsi/dollymix1-unshaded.png | Bin 0 -> 163 bytes .../Guns/Turrets/rift_lance.rsi/dollymix1.png | Bin 0 -> 227 bytes .../rift_lance.rsi/dollymix2-unshaded.png | Bin 0 -> 93 bytes .../Guns/Turrets/rift_lance.rsi/dollymix2.png | Bin 0 -> 192 bytes .../rift_lance.rsi/dollymix3-unshaded.png | Bin 0 -> 93 bytes .../Guns/Turrets/rift_lance.rsi/dollymix3.png | Bin 0 -> 192 bytes .../rift_lance.rsi/dollymix4-unshaded.png | Bin 0 -> 219 bytes .../Guns/Turrets/rift_lance.rsi/dollymix4.png | Bin 0 -> 274 bytes .../rift_lance.rsi/dollymix5-unshaded.png | Bin 0 -> 163 bytes .../Guns/Turrets/rift_lance.rsi/dollymix5.png | Bin 0 -> 163 bytes .../Guns/Turrets/rift_lance.rsi/icon.png | Bin 0 -> 354 bytes .../Guns/Turrets/rift_lance.rsi/meta.json | 22 ++ Tools/dollymix/readme.txt | 19 + Tools/dollymix/zicon.py | 25 ++ Tools/dollymix/zslice.py | 64 +++ Tools/dollymix/ztest.py | 36 ++ 132 files changed, 1957 insertions(+), 425 deletions(-) delete mode 100644 Content.Client/_White/DollyMixture/DollyMixtureComponent.cs create mode 100644 Content.Client/_White/Guns/ModularTurretSystem.cs create mode 100644 Content.Server/_White/DollyMixture/DollyMixtureSystem.cs create mode 100644 Content.Server/_White/Guns/ModularTurret/ModularTurretSystem.cs create mode 100644 Content.Shared/_White/DollyMixture/DollyMixtureComponent.cs create mode 100644 Content.Shared/_White/DollyMixture/SharedDollyMixtureSystem.cs create mode 100644 Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectComponents.cs create mode 100644 Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectSystem.cs create mode 100644 Content.Shared/_White/Guns/ModularTurret/ModularTurretComponents.cs create mode 100644 Content.Shared/_White/Guns/ModularTurret/SharedModularTurretSystem.cs create mode 100644 Content.Shared/_White/Guns/ProjectileContainerBatteryAmmoProviderComponent.cs create mode 100644 Content.Shared/_White/Guns/ProjectileDamageModifier.cs create mode 100644 Content.Shared/_White/Lock/LockDeviceLinksComponent.cs create mode 100644 Resources/Prototypes/_White/Catalog/Cargo/ship_weapons.yml delete mode 100644 Resources/Prototypes/_White/DeviceLinking/source_ports.yml create mode 100644 Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Ship/weapons.yml create mode 100644 Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/ship_turrets.yml rename Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/{turrets_ballistic.yml => universal_mount.yml} (57%) rename Resources/Prototypes/_White/Entities/Structures/Machines/Computers/{computers.yml => remote_control.yml} (96%) create mode 100644 Resources/Prototypes/_White/Innate/InnateMassScanner.yml create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/fast.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/impact_fast.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/impact_mining_laser.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/mining_laser.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/muzzle_fast.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/muzzle_mining_laser.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix4-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix5.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix5.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix6.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix7.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix8.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix5.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix5.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix3-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix5-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix5.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix6.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix7-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix7.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix8.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix9-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix9.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/light.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/light_broken.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/meta.json create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix1-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix1.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix2-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix2.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix3-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix3.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix4-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix4.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix5-unshaded.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix5.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/icon.png create mode 100644 Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/meta.json create mode 100644 Tools/dollymix/readme.txt create mode 100644 Tools/dollymix/zicon.py create mode 100644 Tools/dollymix/zslice.py create mode 100644 Tools/dollymix/ztest.py diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index f2c68d4959..b896ecc49e 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -1,6 +1,7 @@ using System; using System.Numerics; using Content.Client.Station; // Frontier +using Content.Client.Weapons.Ranged.Systems; using Content.Shared.Projectiles; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Components; @@ -29,6 +30,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl private readonly SharedShuttleSystem _shuttles; private readonly SharedTransformSystem _transform; private readonly EntityLookupSystem _lookup; // WD EDIT + private readonly GunSystem _gun; // WD EDIT /// /// Used to transform all of the radar objects. Typically is a shuttle console parented to a grid. @@ -57,6 +59,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl _transform = EntManager.System(); _station = EntManager.System(); // Frontier _lookup = EntManager.System(); // WWDP EDIT + _gun = EntManager.System(); // WWDP EDIT } public void SetMatrix(EntityCoordinates? coordinates, Angle? angle) @@ -141,7 +144,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var fixturesQuery = EntManager.GetEntityQuery(); var bodyQuery = EntManager.GetEntityQuery(); - EntManager.TryGetComponent(_coordinates.Value.EntityId, out var ourGunComp); // WD EDIT + _gun.TryGetGun(_coordinates.Value.EntityId, out _, out var ourGunComp); // WWDP EDIT if (!xformQuery.TryGetComponent(_coordinates.Value.EntityId, out var xform) || xform.MapID == MapId.Nullspace) diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs index 58eb70e0a8..e67c144d98 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs @@ -157,15 +157,8 @@ public sealed partial class GunSystem : SharedGunSystem if (a.Sprite is not SpriteSpecifier.Rsi rsi) continue; - var coords = GetCoordinates(a.coordinates); - - if (Deleted(coords.EntityId)) - continue; - - var ent = Spawn(HitscanProto, coords); + var ent = Spawn(HitscanProto, a.coordinates, rotation: a.angle); // WWDP EDIT var sprite = Comp(ent); - var xform = Transform(ent); - xform.LocalRotation = a.angle; sprite[EffectLayers.Unshaded].AutoAnimated = false; sprite.LayerSetSprite(EffectLayers.Unshaded, rsi); sprite.LayerSetState(EffectLayers.Unshaded, rsi.RsiState); diff --git a/Content.Client/_White/DollyMixture/DollyMixtureComponent.cs b/Content.Client/_White/DollyMixture/DollyMixtureComponent.cs deleted file mode 100644 index 1e6501778b..0000000000 --- a/Content.Client/_White/DollyMixture/DollyMixtureComponent.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Robust.Client.Graphics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Text; -using System.Threading.Tasks; - -namespace Content.Client._White.DollyMixture; - -[RegisterComponent] -public sealed partial class DollyMixtureComponent : Component -{ - [DataField("sprite")] - public string RSIPath = ""; - - [DataField(required: true)] - public List States = default!; - - public RSI? RSI; - - [DataField] - public Vector2 LayerOffset = new(0, 1); - - [DataField] - public Vector2 Offset; - - public Angle LastAngle; - public List LayerIndices = new(); - - [DataField] - public int RepeatLayers = 1; - - [DataField] - public Vector2 LayerScale = Vector2.One; - - [DataField] - public string? DefaultShader; -} diff --git a/Content.Client/_White/DollyMixture/DollyMixtureSystem.cs b/Content.Client/_White/DollyMixture/DollyMixtureSystem.cs index d0e563bfae..3c4771682a 100644 --- a/Content.Client/_White/DollyMixture/DollyMixtureSystem.cs +++ b/Content.Client/_White/DollyMixture/DollyMixtureSystem.cs @@ -1,19 +1,25 @@ +using Content.Shared._White.DollyMixture; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; +using Robust.Shared.Timing; using System.Numerics; namespace Content.Client._White.DollyMixture; -public sealed class DollyMixtureSystem : EntitySystem +public sealed class DollyMixtureSystem : SharedDollyMixtureSystem { [Dependency] private readonly IResourceCache _res = default!; [Dependency] private readonly IEyeManager _eye = default!; [Dependency] private readonly SharedTransformSystem _xform = default!; + [Dependency] private readonly IGameTiming _timing = default!; public override void Initialize() { + base.Initialize(); SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnAutoState); } public override void FrameUpdate(float frameTime) @@ -22,85 +28,153 @@ public sealed class DollyMixtureSystem : EntitySystem while (query.MoveNext(out var uid, out var dollymix, out var sprite, out var xform)) { Angle angle = _xform.GetWorldRotation(xform) + _eye.CurrentEye.Rotation; + if (dollymix.DirectionCount > 0) + angle = Math.Round(angle / Math.Tau * dollymix.DirectionCount) * Math.Tau / dollymix.DirectionCount; + const float MinAngleDelta = MathF.PI / 180 * 0.01f; if (MathHelper.CloseTo(dollymix.LastAngle, angle, MinAngleDelta)) continue; dollymix.LastAngle = angle; - for (int i = 0; i < dollymix.LayerIndices.Count; i++) - { - sprite.LayerSetRotation(dollymix.LayerIndices[i], angle); - } + for (int i = 0; i < dollymix.LayerMappings.Count; i++) + sprite.LayerSetRotation(dollymix.LayerMappings[i], angle); } } + private void OnAutoState(EntityUid uid, DollyMixtureComponent comp, AfterAutoHandleStateEvent args) + { + UpdateDollyMixture(uid, comp); + } + + private void UpdateDollyMixture(EntityUid uid, DollyMixtureComponent comp) + { + if (comp.CurrentRSIPath == comp.RSIPath) + return; + + if (comp.RSIPath is null) + { + RemoveLayers(uid, comp); + return; + } + + if (comp.CurrentRSIPath is not null) + RemoveLayers(uid, comp); + + BuildLayers(uid, comp); + } + + private void OnRemove(EntityUid uid, DollyMixtureComponent comp, ComponentRemove args) + { + if (!_timing.IsFirstTimePredicted) + return; + + RemoveLayers(uid, comp); + } + // more than half of this method is handling missing shit. gg. private void OnInit(EntityUid uid, DollyMixtureComponent comp, ComponentInit args) { - if (!TryComp(uid, out var sprite)) - { + if (!_timing.IsFirstTimePredicted) + return; + + if (!TryComp(uid, out var sprite)) // unlike OnRemove() and RemoveLayers(), this doesn't get executed when placing a prototype + { // i cry Log.Error($"Failed to get SpriteComponent for {ToPrettyString(uid)}. Removing DollyMixtureComponent."); RemComp(uid); return; } - if (!TryComp(uid, out var xform)) + var xform = Transform(uid); + sprite.NoRotation = true; + + if (comp.RSIPath is not null) + BuildLayers(uid, comp, sprite); + } + + public override void Apply3D(EntityUid uid, string RsiPath, string? statePrefix = null, Vector2? layerOffset = null, DollyMixtureComponent? comp = null) + { + comp ??= EnsureComp(uid); + + base.Apply3D(uid, RsiPath, statePrefix, layerOffset, comp); + UpdateDollyMixture(uid, comp); + } + + public override void Remove3D(EntityUid uid, DollyMixtureComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return; + + base.Remove3D(uid, comp); + UpdateDollyMixture(uid, comp); + } + + private void RemoveLayers(EntityUid uid, DollyMixtureComponent comp) + { + SpriteComponent? sprite = null; + if (!Resolve(uid, ref sprite, false)) // this gets executed after simply placing a prototype with this comp + return; // i assume it is some prediction-related bullshit + foreach (var layerMapping in comp.LayerMappings) + sprite.RemoveLayer(layerMapping); + comp.CurrentRSIPath = null; + comp.LayerMappings.Clear(); + } + + private void BuildLayers(EntityUid uid, DollyMixtureComponent comp, SpriteComponent? sprite = null) + { + if (string.IsNullOrEmpty(comp.RSIPath)) { - Log.Error($"Failed to get SpriteComponent for {ToPrettyString(uid)}. Removing DollyMixtureComponent."); - RemComp(uid); + Log.Error($"An empty rsi path was passed to BuildLayers()."); return; } - RSIResource? RSIres = null; - if (!string.IsNullOrEmpty(comp.RSIPath) && !_res.TryGetResource($"/Textures/{comp.RSIPath}", out RSIres)) + if (!Resolve(uid, ref sprite, false)) + return; + + var xform = Transform(uid); + if (!_res.TryGetResource($"/Textures/{comp.RSIPath}", out RSIResource? RSIres)) { - Log.Error($"Failed to get RSI {$"/Textures/{comp.RSIPath}"} for a dolly mixture component. Removing component. ({ToPrettyString(uid)})"); - RemComp(uid); + Log.Error($"Failed to get RSI {$"/Textures/{comp.RSIPath}"} for a dolly mixture component."); return; } - var RSI = RSIres?.RSI ?? sprite.BaseRSI; - if(RSI is null) - { - Log.Error($"No RSI specified for both DollyMixtureComponent and SpriteComponent. Removing DollyMixtureComponent. ({ToPrettyString(uid)})"); - RemComp(uid); - return; - } + var RSI = RSIres.RSI; - comp.RSI = RSI; - comp.LayerIndices = new(comp.States.Count); - - for (int i = 0; i < comp.States.Count; i++) + int i = 1; + while (RSI.TryGetState($"{comp.StatePrefix}{i}", out var state)) { - string stateId = comp.States[i]; - for (int repeat = 0; repeat < comp.RepeatLayers; repeat++) + for (int repeat = 0; repeat <= comp.RepeatLayers; repeat++) { - Vector2 layerOffset = comp.Offset / EyeManager.PixelsPerMeter + comp.LayerOffset / EyeManager.PixelsPerMeter * i; - layerOffset += comp.LayerOffset * ((float)repeat / comp.RepeatLayers); + float fraction = comp.RepeatLayers > 0 ? (float) repeat / comp.RepeatLayers : 0f; + + Vector2 layerOffset = comp.Offset / EyeManager.PixelsPerMeter + comp.LayerOffset / EyeManager.PixelsPerMeter * (i - 1 + fraction); int layerIndex = sprite.AddBlankLayer(); sprite.LayerSetRSI(layerIndex, RSI); - sprite.LayerSetState(layerIndex, stateId); + sprite.LayerSetState(layerIndex, state.StateId); sprite.LayerSetOffset(layerIndex, layerOffset); - sprite.LayerSetScale(layerIndex, comp.LayerScale); sprite.LayerSetRotation(layerIndex, xform.LocalRotation + _eye.CurrentEye.Rotation); - if (comp.DefaultShader is not null) - sprite.LayerSetShader(layerIndex, comp.DefaultShader); // crutch, need to assign a proper datadef for each dollymix layer instead of this. - comp.LayerIndices.Add(layerIndex); + if (comp.DefaultShader is string defaultshader) + sprite.LayerSetShader(layerIndex, defaultshader); // crutch for customghosts + string layerMap = $"dmm-{comp.StatePrefix}{i}({repeat}/{comp.RepeatLayers})"; + sprite.LayerMapSet(layerMap, layerIndex); + comp.LayerMappings.Add(layerMap); - if (sprite.BaseRSI?.TryGetState($"{stateId}-unshaded", out var unshadedState) ?? false) // todo: assign a proper datadef for each dollymix layer instead of this. + if (RSI.TryGetState($"{comp.StatePrefix}{i}-unshaded", out var unshadedState)) { layerIndex = sprite.AddBlankLayer(); sprite.LayerSetRSI(layerIndex, RSI); - sprite.LayerSetState(layerIndex, $"{stateId}-unshaded"); - sprite.LayerSetShader(layerIndex, "unshaded"); + sprite.LayerSetState(layerIndex, unshadedState.StateId); sprite.LayerSetOffset(layerIndex, layerOffset); - sprite.LayerSetScale(layerIndex, comp.LayerScale); sprite.LayerSetRotation(layerIndex, xform.LocalRotation + _eye.CurrentEye.Rotation); - comp.LayerIndices.Add(layerIndex); + sprite.LayerSetShader(layerIndex, "unshaded"); + layerMap = $"{layerMap}u"; + sprite.LayerMapSet(layerMap, layerIndex); + comp.LayerMappings.Add(layerMap); } } + i++; } - //sprite.GranularLayersRendering = true; + comp.CurrentRSIPath = comp.RSIPath; } } + diff --git a/Content.Client/_White/Guns/ModularTurretSystem.cs b/Content.Client/_White/Guns/ModularTurretSystem.cs new file mode 100644 index 0000000000..9db7a3b8f4 --- /dev/null +++ b/Content.Client/_White/Guns/ModularTurretSystem.cs @@ -0,0 +1,5 @@ +using Content.Shared._White.Guns.ModularTurret; + +namespace Content.Client._White.Guns; + +public sealed class ModularTurretSystem : SharedModularTurretSystem; diff --git a/Content.Server/Entry/IgnoredComponents.cs b/Content.Server/Entry/IgnoredComponents.cs index 13d7f6a600..3affeaa89c 100644 --- a/Content.Server/Entry/IgnoredComponents.cs +++ b/Content.Server/Entry/IgnoredComponents.cs @@ -21,7 +21,6 @@ namespace Content.Server.Entry "HolidayRsiSwap", "OptionsVisualizer", "ToggleableLightWieldable", // Goobstation - "DollyMixture", // WWDP EDIT "ItemSlotRenderer", // WWDP EDIT }; } diff --git a/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs b/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs index a8b36fbd84..0aa00c0abd 100644 --- a/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs +++ b/Content.Server/Explosion/Components/SpawnOnTriggerComponent.cs @@ -1,6 +1,7 @@ using Content.Server.Explosion.EntitySystems; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using System.Numerics; namespace Content.Server.Explosion.Components; @@ -9,4 +10,9 @@ public sealed partial class SpawnOnTriggerComponent : Component { [ViewVariables(VVAccess.ReadWrite), DataField("proto", required: true, customTypeSerializer:typeof(PrototypeIdSerializer))] public string Proto = string.Empty; + + // WWDP EDIT START + [DataField] + public List Offsets = new() { Vector2.Zero }; + // WWDP EDIT END } diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index a18f3ef725..d02fe9aed6 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -141,8 +141,15 @@ namespace Content.Server.Explosion.EntitySystems if (!coords.IsValid(EntityManager)) return; - - Spawn(component.Proto, coords); + // WWDP EDIT START + if(component.Offsets.Count == 0) + { + Log.Warning($"SpawnOnTriggerComponent on {ToPrettyString(uid)} has empty offsets."); + return; + } + foreach(var offset in component.Offsets) + Spawn(component.Proto, new Robust.Shared.Map.EntityCoordinates(uid, offset)); + // WWDP EDIT END } private void HandleExplodeTrigger(EntityUid uid, ExplodeOnTriggerComponent component, TriggerEvent args) diff --git a/Content.Server/Language/LanguageSystem.cs b/Content.Server/Language/LanguageSystem.cs index 7b40d895d2..932bf27f7d 100644 --- a/Content.Server/Language/LanguageSystem.cs +++ b/Content.Server/Language/LanguageSystem.cs @@ -76,7 +76,7 @@ public sealed partial class LanguageSystem : SharedLanguageSystem // WWDP EDIT START // quick fix // todo: reimplement as an event handler on RemoteControllableComponent. - if(TryComp(ent.Owner, out var remoteControlTarget) && remoteControlTarget.User is { } controller) + if(TryComp(ent.Owner, out var remoteControlTarget) && remoteControlTarget.User is { } controller) return CanUnderstand(controller, language); // WWDP EDIT END return Resolve(ent, ref ent.Comp, logMissing: false) && ent.Comp.UnderstoodLanguages.Contains(language); @@ -89,7 +89,7 @@ public sealed partial class LanguageSystem : SharedLanguageSystem // WWDP EDIT START // quick fix // todo: reimplement as an event handler on RemoteControllableComponent. - if (TryComp(ent.Owner, out var remoteControlTarget) && remoteControlTarget.User is { } controller) + if (TryComp(ent.Owner, out var remoteControlTarget) && remoteControlTarget.User is { } controller) return CanSpeak(controller, language); // WWDP EDIT END return ent.Comp.SpokenLanguages.Contains(language); diff --git a/Content.Server/Power/EntitySystems/UpgradeBatterySystem.cs b/Content.Server/Power/EntitySystems/UpgradeBatterySystem.cs index 734cf9d89c..efe60462a5 100644 --- a/Content.Server/Power/EntitySystems/UpgradeBatterySystem.cs +++ b/Content.Server/Power/EntitySystems/UpgradeBatterySystem.cs @@ -23,7 +23,7 @@ namespace Content.Server.Power.EntitySystems if (TryComp(uid, out var batteryComp)) { - _batterySystem.SetMaxCharge(uid, MathF.Pow(component.MaxChargeMultiplier, powerCellRating - 1) * component.BaseMaxCharge, batteryComp); + _batterySystem.SetMaxCharge(uid, MathF.Pow(component.MaxChargeMultiplier, powerCellRating) * component.BaseMaxCharge, batteryComp); } } diff --git a/Content.Server/Salvage/SalvageSystem.Magnet.cs b/Content.Server/Salvage/SalvageSystem.Magnet.cs index 7d7845bf68..0ca3282e2a 100644 --- a/Content.Server/Salvage/SalvageSystem.Magnet.cs +++ b/Content.Server/Salvage/SalvageSystem.Magnet.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Numerics; using System.Threading.Tasks; +using Content.Server.Popups; using Content.Server.Salvage.Magnet; using Content.Shared._White.CCVar; using Content.Shared.Humanoid; diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs index cc9af0e490..72990110f3 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs @@ -1,12 +1,16 @@ using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; using Content.Server.Temperature.Components; using Content.Server.Temperature.Systems; +using Content.Shared._White.Guns; using Content.Shared.Damage; using Content.Shared.Damage.Events; using Content.Shared.FixedPoint; +using Content.Shared.PowerCell.Components; using Content.Shared.Projectiles; using Content.Shared.Weapons.Ranged; using Content.Shared.Weapons.Ranged.Components; +using Robust.Shared.Containers; using Robust.Shared.Prototypes; namespace Content.Server.Weapons.Ranged.Systems; @@ -28,6 +32,18 @@ public sealed partial class GunSystem SubscribeLocalEvent(OnBatteryStartup); SubscribeLocalEvent(OnBatteryChargeChange); SubscribeLocalEvent(OnBatteryDamageExamine); + //// WWDP EDIT START + SubscribeLocalEvent(OnBatteryStartup); + SubscribeLocalEvent(OnContainerBatteryInserted); + SubscribeLocalEvent(OnContainerBatteryRemoved); + SubscribeLocalEvent(OnBatteryDamageExamine); + SubscribeLocalEvent(OnBatteryChargeChangeTracker); + + SubscribeLocalEvent(OnBatteryStartup); + SubscribeLocalEvent(OnContainerBatteryInserted); + SubscribeLocalEvent(OnContainerBatteryRemoved); + SubscribeLocalEvent(OnBatteryDamageExamine); + //// WWDP EDIT END } private void OnBatteryStartup(EntityUid uid, BatteryAmmoProviderComponent component, ComponentStartup args) @@ -42,7 +58,8 @@ public sealed partial class GunSystem public void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component) // WWDP EDIT - private -> public { - if (!TryComp(uid, out var battery)) + var batteryUid = component is ContainerBatteryAmmoProviderComponent ? Transform(uid).ParentUid : uid; // WWDP EDIT + if (!TryComp(batteryUid, out var battery)) // WWDP EDIT return; UpdateShots(uid, component, battery.CurrentCharge, battery.MaxCharge); @@ -108,7 +125,44 @@ public sealed partial class GunSystem protected override void TakeCharge(EntityUid uid, BatteryAmmoProviderComponent component) { + if(component is ContainerBatteryAmmoProviderComponent comp) + { + uid = comp.Linked!.Value; // the validity of this should be enforced by EntGotInserted/Removed event handlers below. + } // Will raise ChargeChangedEvent _battery.UseCharge(uid, component.FireCost); } + + // WWDP EDIT START + private void OnContainerBatteryInserted(EntityUid uid, ContainerBatteryAmmoProviderComponent comp, EntGotInsertedIntoContainerMessage args) + { + var contUid = args.Container.Owner; + var tracker = EnsureComp(contUid); + tracker.Linked.Add(uid); + comp.Linked = contUid; + UpdateShots(uid, comp); + } + + private void OnContainerBatteryRemoved(EntityUid uid, ContainerBatteryAmmoProviderComponent comp, EntGotRemovedFromContainerMessage args) + { + var contUid = args.Container.Owner; + var tracker = Comp(contUid); // intended to throw on failure, should not happen + tracker.Linked.Remove(uid); + comp.Linked = null; + if (tracker.Linked.Count == 0) + RemComp(contUid, tracker); + UpdateShots(uid, comp, 0, 0); + } + + private void OnBatteryChargeChangeTracker(EntityUid uid, ContainerBatteryAmmoTrackerComponent comp, ref ChargeChangedEvent args) + { + foreach (var gunUid in comp.Linked) + { + if(TryComp(gunUid, out var projectileAmmoProvider)) + UpdateShots(gunUid, projectileAmmoProvider, args.Charge, args.MaxCharge); + else if(TryComp(gunUid, out var hitscanAmmoProvider)) + UpdateShots(gunUid, hitscanAmmoProvider, args.Charge, args.MaxCharge); + } + } + // WWDP EDIT END } diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index 8ab8fcc9df..c2b4d92643 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -25,8 +25,8 @@ using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; using Robust.Shared.Containers; -using Content.Shared._Lavaland.Weapons.Ranged.Events; -using ProjectileShotEvent = Content.Shared._Lavaland.Weapons.Ranged.Events.ProjectileShotEvent; // Lavaland Change +using ProjectileShotEvent = Content.Shared._Lavaland.Weapons.Ranged.Events.ProjectileShotEvent; +using Content.Shared.Mech.Components; namespace Content.Server.Weapons.Ranged.Systems; @@ -71,6 +71,13 @@ public sealed partial class GunSystem : SharedGunSystem EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, out bool userImpulse, EntityUid? user = null, bool throwItems = false) { userImpulse = true; + // WWDP EDIT START // All code related to mechs is fucking vile. + var trueUser = user; + if(TryComp(user, out var mechComp)) + { + trueUser = mechComp.PilotSlot.ContainedEntity; + } + // WWDP EDIT END if (user != null) { @@ -157,66 +164,64 @@ public sealed partial class GunSystem : SharedGunSystem EntityUid? lastHit = null; var from = fromMap; - // can't use map coords above because funny FireEffects - var fromEffect = fromCoordinates; + // can't use map coords above because funny FireEffects // my brother in christ, you wrote that method var dir = mapDirection.Normalized(); - //in the situation when user == null, means that the cannon fires on its own (via signals). And we need the gun to not fire by itself in this case var lastUser = user ?? gunUid; - - if (hitscan.Reflective != ReflectType.None) + RayCastResults? lastResult = null; // WWDP EDIT + for (var reflectAttempt = 0; reflectAttempt < 3; reflectAttempt++) { - for (var reflectAttempt = 0; reflectAttempt < 3; reflectAttempt++) + var ray = new CollisionRay(from.Position, dir, hitscan.CollisionMask); + var rayCastResults = + Physics.IntersectRay(from.MapId, ray, hitscan.MaxLength, lastUser, false).ToList(); + if (!rayCastResults.Any()) + break; + + var raycastEvent = new HitScanAfterRayCastEvent(rayCastResults); + RaiseLocalEvent(lastUser, ref raycastEvent); + + if (raycastEvent.RayCastResults == null) + break; + + var result = raycastEvent.RayCastResults[0]; + lastResult = result; // WWDP EDIT + // Check if laser is shot from in a container + if (!_container.IsEntityOrParentInContainer(lastUser)) { - var ray = new CollisionRay(from.Position, dir, hitscan.CollisionMask); - var rayCastResults = - Physics.IntersectRay(from.MapId, ray, hitscan.MaxLength, lastUser, false).ToList(); - if (!rayCastResults.Any()) - break; - - var raycastEvent = new HitScanAfterRayCastEvent(rayCastResults); - RaiseLocalEvent(lastUser, ref raycastEvent); - - if (raycastEvent.RayCastResults == null) - break; - - var result = raycastEvent.RayCastResults[0]; - - // Check if laser is shot from in a container - if (!_container.IsEntityOrParentInContainer(lastUser)) + // Checks if the laser should pass over unless targeted by its user + foreach (var collide in rayCastResults) { - // Checks if the laser should pass over unless targeted by its user - foreach (var collide in rayCastResults) + if (collide.HitEntity != gun.Target && + CompOrNull(collide.HitEntity)?.Active == true) { - if (collide.HitEntity != gun.Target && - CompOrNull(collide.HitEntity)?.Active == true) - { - continue; - } - - result = collide; - break; + continue; } - } - var hit = result.HitEntity; - lastHit = hit; - - FireEffects(fromEffect, result.Distance, dir.Normalized().ToAngle(), hitscan, hit); - - var ev = new HitScanReflectAttemptEvent(user, gunUid, hitscan.Reflective, dir, false, hitscan.Damage); // WD EDIT - RaiseLocalEvent(hit, ref ev); - - if (!ev.Reflected) + result = collide; break; - - fromEffect = Transform(hit).Coordinates; - from = fromEffect.ToMap(EntityManager, _transform); - dir = ev.Direction; - lastUser = hit; + } } + + var hit = result.HitEntity; + lastHit = hit; + + FireEffects(from, result.Distance, dir.Normalized().ToAngle(), hitscan, hit); + + if (hitscan.Reflective == ReflectType.None) // WWDP EDIT + break; // WWDP EDIT + + var ev = new HitScanReflectAttemptEvent(user, gunUid, hitscan.Reflective, dir, false, hitscan.Damage); // WD EDIT + RaiseLocalEvent(hit, ref ev); + + if (!ev.Reflected) + break; + + from = _transform.GetMapCoordinates(hit); // WWDP EDIT + dir = ev.Direction; + lastUser = hit; } + if (lastHit != null) { var hitEntity = lastHit.Value; @@ -246,21 +251,33 @@ public sealed partial class GunSystem : SharedGunSystem if (user != null) { Logs.Add(LogType.HitScanHit, - $"{ToPrettyString(user.Value):user} hit {hitName:target} using hitscan and dealt {dmg.GetTotal():damage} damage"); + $"{ToPrettyString(user.Value):user} hit {hitName:target} using hitscan ({hitscan.ID}) and dealt {dmg.GetTotal():damage} damage"); } else { Logs.Add(LogType.HitScanHit, - $"{hitName:target} hit by hitscan dealing {dmg.GetTotal():damage} damage"); + $"{hitName:target} hit by hitscan ({hitscan.ID}) dealing {dmg.GetTotal():damage} damage"); } } + // WWDP EDIT START + if (hitscan.SpawnAtImpact is EntProtoId impactEntity) + { + Angle ang = hitscan.ImpactSpawnRandomAngle ? Random.NextAngle() : dir.ToAngle() - Math.PI/2; + Spawn(impactEntity, new MapCoordinates(lastResult!.Value.HitPos, from.MapId), rotation: ang); + } + // WWDP EDIT END } else { - FireEffects(fromEffect, hitscan.MaxLength, dir.ToAngle(), hitscan); + FireEffects(from, hitscan.MaxLength, dir.ToAngle(), hitscan); + // WWDP EDIT START + Angle ang = hitscan.ImpactSpawnRandomAngle ? Random.NextAngle() : dir.ToAngle() - Math.PI/2; + if (hitscan.SpawnAtMaxLength is EntProtoId impactEntity) + Spawn(impactEntity, from.Offset(dir * hitscan.MaxLength), rotation: ang); + // WWDP EDIT END } - Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user); + Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, trueUser); // WWDP EDIT break; default: throw new ArgumentOutOfRangeException(); @@ -330,8 +347,8 @@ public sealed partial class GunSystem : SharedGunSystem } SpreadBreak: - MuzzleFlash(gunUid, ammoComp, mapDirection.ToAngle(), user); - Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user); + MuzzleFlash(gunUid, ammoComp, mapDirection.ToAngle(), trueUser); // WWDP EDIT + Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, trueUser); // WWDP EDIT } } @@ -444,55 +461,37 @@ public sealed partial class GunSystem : SharedGunSystem // TODO: Pseudo RNG so the client can predict these. #region Hitscan effects - private void FireEffects(EntityCoordinates fromCoordinates, float distance, Angle mapDirection, HitscanPrototype hitscan, EntityUid? hitEntity = null) + private void FireEffects(MapCoordinates fromCoordinates, float distance, Angle mapDirection, HitscanPrototype hitscan, EntityUid? hitEntity = null) { // Lord - // Forgive me for the shitcode I am about to do + // Forgive me for the shitcode I am about to do // https://www.youtube.com/watch?v=sCAdVQNaDTE go fuck yourself // Effects tempt me not - var sprites = new List<(NetCoordinates coordinates, Angle angle, SpriteSpecifier sprite, float scale)>(); - var gridUid = fromCoordinates.GetGridUid(EntityManager); + var sprites = new List<(MapCoordinates coordinates, Angle angle, SpriteSpecifier sprite, float scale)>(); + var angle = mapDirection; - // We'll get the effects relative to the grid / map of the firer - // Look you could probably optimise this a bit with redundant transforms at this point. - var xformQuery = GetEntityQuery(); - - if (xformQuery.TryGetComponent(gridUid, out var gridXform)) - { - var (_, gridRot, gridInvMatrix) = TransformSystem.GetWorldPositionRotationInvMatrix(gridXform, xformQuery); - - fromCoordinates = new EntityCoordinates(gridUid.Value, - Vector2.Transform(fromCoordinates.ToMapPos(EntityManager, TransformSystem), gridInvMatrix)); - - // Use the fallback angle I guess? - angle -= gridRot; - } - if (distance >= 1f) { if (hitscan.MuzzleFlash != null) { var coords = fromCoordinates.Offset(angle.ToVec().Normalized() / 2); - var netCoords = GetNetCoordinates(coords); - sprites.Add((netCoords, angle, hitscan.MuzzleFlash, 1f)); + sprites.Add((coords, angle, hitscan.MuzzleFlash, 1f)); } if (hitscan.TravelFlash != null) { var coords = fromCoordinates.Offset(angle.ToVec() * (distance + 0.5f) / 2); - var netCoords = GetNetCoordinates(coords); - sprites.Add((netCoords, angle, hitscan.TravelFlash, distance - 1.5f)); + sprites.Add((coords, angle, hitscan.TravelFlash, distance - 1.5f)); } } if (hitscan.ImpactFlash != null) { var coords = fromCoordinates.Offset(angle.ToVec() * distance); - var netCoords = GetNetCoordinates(coords); - sprites.Add((netCoords, angle.FlipPositive(), hitscan.ImpactFlash, 1f)); + sprites.Add((coords, angle.FlipPositive(), hitscan.ImpactFlash, 1f)); } if (sprites.Count > 0) @@ -500,7 +499,7 @@ public sealed partial class GunSystem : SharedGunSystem RaiseNetworkEvent(new HitscanEvent { Sprites = sprites, - }, Filter.Pvs(fromCoordinates, entityMan: EntityManager)); + }, Filter.Pvs(fromCoordinates)); } } diff --git a/Content.Server/_White/DollyMixture/DollyMixtureSystem.cs b/Content.Server/_White/DollyMixture/DollyMixtureSystem.cs new file mode 100644 index 0000000000..4c3dd524e1 --- /dev/null +++ b/Content.Server/_White/DollyMixture/DollyMixtureSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared._White.DollyMixture; + +namespace Content.Server._White.DollyMixture; + +public sealed class DollyMixtureSystem : SharedDollyMixtureSystem +{ + +} diff --git a/Content.Server/_White/Guns/ModularTurret/ModularTurretSystem.cs b/Content.Server/_White/Guns/ModularTurret/ModularTurretSystem.cs new file mode 100644 index 0000000000..7bfb27af20 --- /dev/null +++ b/Content.Server/_White/Guns/ModularTurret/ModularTurretSystem.cs @@ -0,0 +1,53 @@ +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Shared._White.Guns.ModularTurret; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Weapons.Ranged.Events; +using Content.Shared.Weapons.Ranged.Systems; + +namespace Content.Server._White.Guns.ModularTurret; + +public sealed class ModularTurretSystem : SharedModularTurretSystem +{ + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly ItemSlotsSystem _slot = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnModularTurretShotAttempt); + SubscribeLocalEvent(OnModularTurretWeaponShot); + } + + + private void OnModularTurretShotAttempt(EntityUid turretUid, ModularTurretComponent comp, ref ShotAttemptedEvent args) + { + RechargeWeapon(turretUid, args.Used); + } + + private void OnModularTurretWeaponShot(EntityUid gunUid, ModularTurretWeaponComponent comp, ref GunShotEvent args) + { + if(comp.CurrentTurretHolder is EntityUid turretUid) + RechargeWeapon(turretUid, gunUid); + } + + + private void RechargeWeapon(EntityUid turretUid, EntityUid gunUid) + { + if (!HasComp(gunUid)) + return; + + //var turretComp = Comp(turretUid); + if (!TryComp(gunUid, out var gunBattery) || // || !turretComp.CanChargeWeapon + !TryComp(turretUid, out var turretBattery)) + return; + + float missing = gunBattery.MaxCharge - gunBattery.CurrentCharge; + + float recharged = -_battery.UseCharge(turretUid, missing, turretBattery); + + _battery.SetCharge(gunUid, gunBattery.CurrentCharge + recharged, gunBattery); + } +} + diff --git a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Console.cs b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Console.cs index 5ba44fc874..bc1fbd5b50 100644 --- a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Console.cs +++ b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Console.cs @@ -13,12 +13,14 @@ public partial class RemoteControlSystem { private void InitializeConsole() { + SubscribeLocalEvent(OnConsoleInit); SubscribeLocalEvent(OnConsoleMapInit); SubscribeLocalEvent(OnConsoleShutdown); SubscribeLocalEvent(OnActivateInWorld); SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnNewLinkAttempt); SubscribeLocalEvent(OnNewLink); SubscribeLocalEvent(OnPortDisconnected); @@ -27,13 +29,14 @@ public partial class RemoteControlSystem SubscribeLocalEvent(OnPowerChanged); } + private void OnConsoleInit(EntityUid uid, RemoteControlConsoleComponent comp, ComponentInit args) + { + _link.EnsureSourcePorts(uid, SourcePortId); + } + private void OnConsoleMapInit(EntityUid uid, RemoteControlConsoleComponent component, MapInitEvent args) { - EntityUid? actionUid = null; - _action.AddAction(uid, ref actionUid, component.SwitchToNextAction); - - if (actionUid.HasValue) - component.SwitchToNextActionUid = actionUid.Value; + _action.AddAction(uid, ref component.SwitchToNextActionUid, component.SwitchToNextAction); } private void OnConsoleShutdown(EntityUid uid, RemoteControlConsoleComponent component, ComponentShutdown args) @@ -50,16 +53,22 @@ public partial class RemoteControlSystem private void OnActivateInWorld(EntityUid uid, RemoteControlConsoleComponent component, ActivateInWorldEvent args) => TryActivate(uid, component, args.User); - private void OnNewLink(EntityUid uid, RemoteControlConsoleComponent component, NewLinkEvent args) + private void OnNewLinkAttempt(EntityUid uid, RemoteControlConsoleComponent component, LinkAttemptEvent args) { - if (!_whitelist.CheckBoth(args.Sink, component.Blacklist, component.Whitelist) - || args.Source != uid - || args.SourcePort != SourcePortId - || args.SinkPort != SinkPortId - || !HasComp(args.Sink)) + if (args.Source != uid || args.SourcePort != SourcePortId) return; - component.LinkedEntities.Add(args.Sink); + if (!HasComp(args.Sink) || + !_whitelist.CheckBoth(args.Sink, component.Blacklist, component.Whitelist) || + args.Source != uid || + args.SourcePort != SourcePortId || + args.SinkPort != SinkPortId) + args.Cancel(); + } + private void OnNewLink(EntityUid uid, RemoteControlConsoleComponent component, NewLinkEvent args) + { + if (args.Source == uid && args.SourcePort == SourcePortId) + component.LinkedEntities.Add(args.Sink); } private void OnPortDisconnected(EntityUid uid, RemoteControlConsoleComponent component, PortDisconnectedEvent args) @@ -71,7 +80,7 @@ public partial class RemoteControlSystem // the device link got severed while the turret was in use; either relink to another turret or kick the user out of the console. if (component.User is { } user - && TryComp(user, out var controlling) + && TryComp(user, out var controlling) && controlling.Target == args.RemovedPortUid) EndRemoteControl(user, (uid, component), true); } @@ -90,7 +99,7 @@ public partial class RemoteControlSystem private void TryActivate(EntityUid uid, RemoteControlConsoleComponent component, EntityUid user) { if (!this.IsPowered(uid, EntityManager) - || HasComp(user) + || HasComp(user) || component.User is not null || component.LinkedEntities.Count == 0 || GetFirstValid(component) is not { } target) @@ -101,7 +110,7 @@ public partial class RemoteControlSystem private bool TrySwitchToNextAvailable(EntityUid console, RemoteControlConsoleComponent component) { - if (component.User is not { } user || GetFirstValid(component, component.Target) is not {} target) + if (component.User is not { } user || GetFirstValid(component, component.Target) is not { } target) return false; component.LastIndex = component.LinkedEntities.IndexOf(target); @@ -123,7 +132,7 @@ public partial class RemoteControlSystem var ent = list[index]; if ((!exclude.HasValue || ent != exclude) - && HasComp(ent) + && HasComp(ent) || TryComp(ent, out var mindContainer) && mindContainer.HasMind) return ent; diff --git a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Target.cs b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Target.cs index b3ff840e4d..f0bfab34c3 100644 --- a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Target.cs +++ b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.Target.cs @@ -11,19 +11,19 @@ public partial class RemoteControlSystem { private void InitializeTarget() { - SubscribeLocalEvent(OnTargetMapInit); - SubscribeLocalEvent(OnTargetShutdown); + SubscribeLocalEvent(OnTargetMapInit); + SubscribeLocalEvent(OnTargetShutdown); - SubscribeLocalEvent(OnTargetSpeechSourceOverride); + SubscribeLocalEvent(OnTargetSpeechSourceOverride); - SubscribeLocalEvent>(GetAltVerb); + SubscribeLocalEvent>(GetAltVerb); - SubscribeLocalEvent(OnTargetMobStateChanged); + SubscribeLocalEvent(OnTargetMobStateChanged); - SubscribeLocalEvent(OnExitAction); + SubscribeLocalEvent(OnExitAction); } - private void OnTargetMapInit(EntityUid uid, RemoteControlTargetComponent comp, MapInitEvent args) + private void OnTargetMapInit(EntityUid uid, RemoteControllableComponent comp, MapInitEvent args) { EntityUid? actionUid = null; _action.AddAction(uid, ref actionUid, comp.EndRemoteControlAction); @@ -32,11 +32,11 @@ public partial class RemoteControlSystem comp.EndRemoteControlActionUid = actionUid.Value; } - private void OnTargetShutdown(EntityUid uid, RemoteControlTargetComponent comp, ComponentShutdown args) + private void OnTargetShutdown(EntityUid uid, RemoteControllableComponent comp, ComponentShutdown args) { _action.RemoveAction(uid, comp.EndRemoteControlActionUid); - if (!TryComp(comp.User, out var userComponent)) + if (!TryComp(comp.User, out var userComponent)) return; if (TryComp(userComponent.Console, out var consoleComponent)) @@ -45,15 +45,15 @@ public partial class RemoteControlSystem EndRemoteControl((comp.User.Value, userComponent), (uid, comp), true); } - private void OnTargetSpeechSourceOverride(EntityUid uid, RemoteControlTargetComponent comp, SpeechSourceOverrideEvent args) + private void OnTargetSpeechSourceOverride(EntityUid uid, RemoteControllableComponent comp, SpeechSourceOverrideEvent args) { if (comp.User is { } user) args.Override = user; } - private void GetAltVerb(EntityUid uid, RemoteControlTargetComponent component, GetVerbsEvent args) + private void GetAltVerb(EntityUid uid, RemoteControllableComponent component, GetVerbsEvent args) { - if (!component.CanManually || !args.CanAccess || !args.CanInteract || !args.CanComplexInteract) + if (!component.ManualControl || !args.CanAccess || !args.CanInteract || !args.CanComplexInteract) return; args.Verbs.Add( @@ -82,13 +82,13 @@ public partial class RemoteControlSystem } - private void OnExitAction(EntityUid uid, RemoteControlTargetComponent component, RemoteControlExitActionEvent args) + private void OnExitAction(EntityUid uid, RemoteControllableComponent component, RemoteControlExitActionEvent args) { if(component.User is not null) EndRemoteControl(component.User.Value, (uid, component)); } - private void OnTargetMobStateChanged(EntityUid uid, RemoteControlTargetComponent component, MobStateChangedEvent args) + private void OnTargetMobStateChanged(EntityUid uid, RemoteControllableComponent component, MobStateChangedEvent args) { if (args.NewMobState != MobState.Alive && component.User.HasValue) EndRemoteControl(component.User.Value, (uid, component), true); diff --git a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.User.cs b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.User.cs index ff8c2f0361..f09677e27b 100644 --- a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.User.cs +++ b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.User.cs @@ -7,18 +7,18 @@ public partial class RemoteControlSystem { private void InitializeUser() { - SubscribeLocalEvent(OnUserShutdown); + SubscribeLocalEvent(OnUserShutdown); - SubscribeLocalEvent(OnUserMobStateChanged); + SubscribeLocalEvent(OnUserMobStateChanged); } - private void OnUserShutdown(EntityUid uid, RemoteControlUserComponent comp, ComponentShutdown args) + private void OnUserShutdown(EntityUid uid, RemoteControllingComponent comp, ComponentShutdown args) { - if (TryComp(comp.Target, out var targetComp) && targetComp.User == uid) + if (TryComp(comp.Target, out var targetComp) && targetComp.User == uid) EndRemoteControl((uid, comp), (comp.Target, targetComp)); } - private void OnUserMobStateChanged(EntityUid uid, RemoteControlUserComponent comp, MobStateChangedEvent args) + private void OnUserMobStateChanged(EntityUid uid, RemoteControllingComponent comp, MobStateChangedEvent args) { if (args.NewMobState != MobState.Alive) EndRemoteControl((uid, comp)); diff --git a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.cs b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.cs index 7a286972a5..d63e2c0d4a 100644 --- a/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.cs +++ b/Content.Server/_White/RemoteControl/Systems/RemoteControlSystem.cs @@ -1,5 +1,6 @@ using Content.Server.Actions; using Content.Server.Chat.Systems; +using Content.Server.DeviceLinking.Systems; using Content.Server.Interaction; using Content.Server.Mind; using Content.Server.Popups; @@ -13,11 +14,13 @@ using Content.Shared.Whitelist; using Robust.Server.GameObjects; using Robust.Shared.Player; using Robust.Shared.Prototypes; +using Robust.Shared.Utility; namespace Content.Server._White.RemoteControl.Systems; public sealed partial class RemoteControlSystem : EntitySystem { + [Dependency] private readonly DeviceLinkSystem _link = default!; [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; [Dependency] private readonly ActionsSystem _action = default!; [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; @@ -27,8 +30,8 @@ public sealed partial class RemoteControlSystem : EntitySystem [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly TransformSystem _transform = default!; - public static ProtoId SinkPortId = "RemoteControlOutputPort"; - public static ProtoId SourcePortId = "RemoteControlInputPort"; + public static ProtoId SinkPortId = "RemoteControlSinkPort"; + public static ProtoId SourcePortId = "RemoteControlSourcePort"; public override void Initialize() { @@ -44,7 +47,7 @@ public sealed partial class RemoteControlSystem : EntitySystem { var sourceXform = Transform(args.Source); - var query = EntityQueryEnumerator(); + var query = EntityQueryEnumerator(); while (query.MoveNext(out _, out var comp, out var xform)) { var range = xform.MapID != sourceXform.MapID @@ -61,7 +64,7 @@ public sealed partial class RemoteControlSystem : EntitySystem public override void Update(float frameTime) { - var query = EntityQueryEnumerator(); + var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp)) { if(!_actionBlocker.CanInteract(uid, comp.Console) @@ -70,17 +73,17 @@ public sealed partial class RemoteControlSystem : EntitySystem } } - private bool RemoteControl(Entity user, Entity target, Entity console, bool overlay = false) + private bool RemoteControl(EntityUid user, Entity target, Entity console, bool overlay = false) { if (!Resolve(target, ref target.Comp) - || HasComp(user) + || HasComp(user) || HasComp(target) || _mind.GetMind(user) is not { } userMind) return false; - user.Comp = EnsureComp(user); - user.Comp.Target = target; - user.Comp.Console = console; + var userComp = EnsureComp(user); + userComp.Target = target; + userComp.Console = console; target.Comp.User = user; @@ -89,8 +92,8 @@ public sealed partial class RemoteControlSystem : EntitySystem console.Comp.User = user; console.Comp.Target = target; console.Comp.LastIndex = console.Comp.LinkedEntities.IndexOf(target); - - _action.AddAction(target, console.Comp.SwitchToNextActionUid, console); + DebugTools.Assert(console.Comp.SwitchToNextActionUid.HasValue); + _action.AddAction(target, console.Comp.SwitchToNextActionUid.Value, console); } _mind.Visit(userMind, target); @@ -103,7 +106,7 @@ public sealed partial class RemoteControlSystem : EntitySystem return true; } - private bool EndRemoteControl(Entity user, bool shouldAutoSwitch = false) + private bool EndRemoteControl(Entity user, bool shouldAutoSwitch = false) { if (!Resolve(user, ref user.Comp)) return false; @@ -111,11 +114,7 @@ public sealed partial class RemoteControlSystem : EntitySystem return EndRemoteControl(user, user.Comp.Target, user.Comp.Console, shouldAutoSwitch); } - private bool EndRemoteControl( - Entity user, - Entity target, - bool shouldAutoSwitch = false - ) + private bool EndRemoteControl(Entity user, Entity target, bool shouldAutoSwitch = false) { if (!Resolve(user, ref user.Comp) || !Resolve(target, ref target.Comp)) return false; @@ -123,11 +122,7 @@ public sealed partial class RemoteControlSystem : EntitySystem return EndRemoteControl(user, target, user.Comp.Console, shouldAutoSwitch); } - private bool EndRemoteControl( - Entity user, - Entity console, - bool shouldAutoSwitch = false - ) + private bool EndRemoteControl(Entity user, Entity console, bool shouldAutoSwitch = false ) { if (!Resolve(user, ref user.Comp) || !Resolve(console, ref console.Comp)) return false; @@ -135,12 +130,7 @@ public sealed partial class RemoteControlSystem : EntitySystem return EndRemoteControl(user, user.Comp.Target, console, shouldAutoSwitch); } - private bool EndRemoteControl( - Entity user, - Entity target, - Entity console, - bool shouldAutoSwitch = false - ) + private bool EndRemoteControl(Entity user, Entity target, Entity console, bool shouldAutoSwitch = false ) { if (!Resolve(user, ref user.Comp) || !Resolve(target, ref target.Comp) diff --git a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs index f977a2eeb4..f16ac85777 100644 --- a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs +++ b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs @@ -31,6 +31,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Inventory.VirtualItem; using Robust.Shared.Configuration; using Content.Shared.Implants.Components; +using Content.Shared.Weapons.Ranged.Systems; namespace Content.Shared.Mech.EntitySystems; @@ -75,6 +76,7 @@ public abstract class SharedMechSystem : EntitySystem SubscribeLocalEvent(OnAttackAttempt); SubscribeLocalEvent(OnEntGotRemovedFromContainer); SubscribeLocalEvent(OnShotAttempted); // Goobstation + SubscribeLocalEvent(OnGunShot); // WWDP EDIT Subs.CVar(_config, GoobCVars.MechGunOutsideMech, value => _canUseMechGunOutside = value, true); // Goobstation } @@ -509,6 +511,14 @@ public abstract class SharedMechSystem : EntitySystem RaiseLocalEvent(uid, ev); } + // WWDP EDIT START + private void OnGunShot(EntityUid uid, MechEquipmentComponent component, ref GunShotEvent args) + { + var ev = new HandleMechEquipmentBatteryEvent(); + RaiseLocalEvent(uid, ev); + } + // WWDP EDIT END + private void UpdateAppearance(EntityUid uid, MechComponent? component = null, AppearanceComponent? appearance = null) { diff --git a/Content.Shared/Movement/Components/InputMoverComponent.cs b/Content.Shared/Movement/Components/InputMoverComponent.cs index 40cb532e60..16c712f3f8 100644 --- a/Content.Shared/Movement/Components/InputMoverComponent.cs +++ b/Content.Shared/Movement/Components/InputMoverComponent.cs @@ -32,7 +32,7 @@ namespace Content.Shared.Movement.Components // We change which vector we write into based on whether we were sprinting after the previous input. // (well maybe we do but the code is designed such that MoverSystem applies movement speed) // (and I'm not changing that) - + /// /// Should our velocity be applied to our parent? /// diff --git a/Content.Shared/Radio/Components/SharedRadioJammerComponent.cs b/Content.Shared/Radio/Components/SharedRadioJammerComponent.cs index e5e52a3e47..4209c47b82 100644 --- a/Content.Shared/Radio/Components/SharedRadioJammerComponent.cs +++ b/Content.Shared/Radio/Components/SharedRadioJammerComponent.cs @@ -30,20 +30,20 @@ public sealed partial class RadioJammerComponent : Component /// to this setting. /// [DataField(required: true)] - public LocId Message = string.Empty; + public LocId Message; /// /// Name of the setting. /// [DataField(required: true)] - public LocId Name = string.Empty; + public LocId Name; } /// /// List of all the settings for the radio jammer. /// [DataField(required: true), ViewVariables(VVAccess.ReadOnly)] - public RadioJamSetting[] Settings; + public RadioJamSetting[] Settings = default!; /// /// Index of the currently selected setting. diff --git a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs index e435bc1c4c..ba0a546c77 100644 --- a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs +++ b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs @@ -87,6 +87,7 @@ public abstract partial class SharedShuttleSystem UpdateIFFInterfaces(gridUid, component); } + [PublicAPI] public void RemoveIFFFlag(EntityUid gridUid, IFFFlags flags, IFFComponent? component = null) { diff --git a/Content.Shared/Weapons/Ranged/HitscanPrototype.cs b/Content.Shared/Weapons/Ranged/HitscanPrototype.cs index a5063e3ab5..6f2163857c 100644 --- a/Content.Shared/Weapons/Ranged/HitscanPrototype.cs +++ b/Content.Shared/Weapons/Ranged/HitscanPrototype.cs @@ -43,6 +43,15 @@ public sealed partial class HitscanPrototype : IPrototype, IShootable [DataField("sound")] public SoundSpecifier? Sound; + [DataField] + public EntProtoId? SpawnAtImpact = null; + + [DataField] + public EntProtoId? SpawnAtMaxLength = null; + + [DataField] + public bool ImpactSpawnRandomAngle = false; + /// /// Force the hitscan sound to play rather than potentially playing the entity's sound. /// diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Battery.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Battery.cs index f44273257d..c0e496e663 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Battery.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Battery.cs @@ -1,3 +1,4 @@ +using Content.Shared._White.Guns; using Content.Shared.Examine; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; @@ -25,6 +26,21 @@ public abstract partial class SharedGunSystem SubscribeLocalEvent(OnBatteryTakeAmmo); SubscribeLocalEvent(OnBatteryAmmoCount); SubscribeLocalEvent(OnBatteryExamine); + + // WWDP EDIT START + // Container, Projectile + SubscribeLocalEvent(OnBatteryGetState); + SubscribeLocalEvent(OnBatteryHandleState); + SubscribeLocalEvent(OnBatteryTakeAmmo); + SubscribeLocalEvent(OnBatteryAmmoCount); + //SubscribeLocalEvent(OnBatteryExamine); // you'll have trouble examining something inside a container + + // Container, Hitscan + SubscribeLocalEvent(OnBatteryGetState); + SubscribeLocalEvent(OnBatteryHandleState); + SubscribeLocalEvent(OnBatteryTakeAmmo); + SubscribeLocalEvent(OnBatteryAmmoCount); + // WWDP EDIT END } private void OnBatteryHandleState(EntityUid uid, BatteryAmmoProviderComponent component, ref ComponentHandleState args) @@ -109,6 +125,11 @@ public abstract partial class SharedGunSystem return (ent, EnsureShootable(ent)); case HitscanBatteryAmmoProviderComponent hitscan: return (null, ProtoManager.Index(hitscan.Prototype)); + case ProjectileContainerBatteryAmmoProviderComponent proj: + var entc = Spawn(proj.Prototype, coordinates); + return (entc, EnsureShootable(entc)); + case HitscanContainerBatteryAmmoProviderComponent hitscan: + return (null, ProtoManager.Index(hitscan.Prototype)); default: throw new ArgumentOutOfRangeException(); } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 7021f0d817..13fd2985dc 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -707,7 +707,7 @@ public abstract partial class SharedGunSystem : EntitySystem [Serializable, NetSerializable] public sealed class HitscanEvent : EntityEventArgs { - public List<(NetCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = new(); + public List<(MapCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = new(); // WWDP EDIT } } diff --git a/Content.Shared/_White/DollyMixture/DollyMixtureComponent.cs b/Content.Shared/_White/DollyMixture/DollyMixtureComponent.cs new file mode 100644 index 0000000000..1e26f20ec3 --- /dev/null +++ b/Content.Shared/_White/DollyMixture/DollyMixtureComponent.cs @@ -0,0 +1,40 @@ +using Robust.Shared.GameStates; +using System.Numerics; + +namespace Content.Shared._White.DollyMixture; + + +// this now lives in shared because it allows to add this component server-side and +// have it appear for all clients without additional syncing boilerplate +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class DollyMixtureComponent : Component +{ + [DataField("sprite"), AutoNetworkedField] + public string? RSIPath = null; + public string? CurrentRSIPath = null; + + [DataField] + public string StatePrefix = "dollymix"; + + // Crutch for customghosts, since i can't modify an existing spritecomponent through a ComponentRegistry. Or, at best, i don't know how. + [DataField] + public string? DefaultShader = null; + + // 0 to disable + [DataField] + public int DirectionCount = 0; + + [DataField] + public Vector2 LayerOffset = new(0, 1); + + [DataField] + public Vector2 Offset; + + [DataField] + public int RepeatLayers = 0; + + public Angle LastAngle; + + [ViewVariables(VVAccess.ReadOnly)] + public List LayerMappings = new(); +} diff --git a/Content.Shared/_White/DollyMixture/SharedDollyMixtureSystem.cs b/Content.Shared/_White/DollyMixture/SharedDollyMixtureSystem.cs new file mode 100644 index 0000000000..3efdc0d42c --- /dev/null +++ b/Content.Shared/_White/DollyMixture/SharedDollyMixtureSystem.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace Content.Shared._White.DollyMixture; + +public abstract class SharedDollyMixtureSystem : EntitySystem +{ + public virtual void Apply3D(EntityUid uid, string RsiPath, string? statePrefix = null, Vector2? layerOffset = null, DollyMixtureComponent? comp = null) + { + comp ??= EnsureComp(uid); + + comp.RSIPath = RsiPath; + Dirty(uid, comp); + } + + public virtual void Remove3D(EntityUid uid, DollyMixtureComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return; + + comp.RSIPath = null; + Dirty(uid, comp); + } +} + diff --git a/Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectComponents.cs b/Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectComponents.cs new file mode 100644 index 0000000000..58d1747ae7 --- /dev/null +++ b/Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectComponents.cs @@ -0,0 +1,6 @@ +namespace Content.Shared._White.Guns.AmmoProviderRedirect; + +[RegisterComponent] +public sealed partial class ParentAmmoProviderComponent : Component +{ +} diff --git a/Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectSystem.cs b/Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectSystem.cs new file mode 100644 index 0000000000..02bbe1cc51 --- /dev/null +++ b/Content.Shared/_White/Guns/AmmoProviderRedirect/AmmoProviderRedirectSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.Weapons.Ranged.Events; + +namespace Content.Shared._White.Guns.AmmoProviderRedirect; + +public sealed class AmmoProviderRedirectSystem : EntitySystem +{ + [Dependency] private readonly SharedTransformSystem _transform = default!; + + public override void Initialize() + { + SubscribeLocalEvent(RedirectParent); + } + + // todo figure out a way to check bullets' caliber before firing + // don't let people feed .50 cal rounds into methaphorical pea shooters + private void RedirectParent(EntityUid uid, ParentAmmoProviderComponent comp, TakeAmmoEvent args) + { + if (_transform.GetParentUid(uid) is { Valid: true } parent) + RaiseLocalEvent(parent, args); + } +} diff --git a/Content.Shared/_White/Guns/ModularTurret/ModularTurretComponents.cs b/Content.Shared/_White/Guns/ModularTurret/ModularTurretComponents.cs new file mode 100644 index 0000000000..311800caf3 --- /dev/null +++ b/Content.Shared/_White/Guns/ModularTurret/ModularTurretComponents.cs @@ -0,0 +1,28 @@ +namespace Content.Shared._White.Guns.ModularTurret; + + +[RegisterComponent] +public sealed partial class ModularTurretWeaponComponent : Component +{ + [DataField(required: true)] + public List WeaponClass = new(); + + [DataField] + public bool OnlyUsableByTurret = true; + + [DataField] + public EntityUid? CurrentTurretHolder; + + [DataField("dollyMixSprite")] + public string? DollyMixRSIPath = null; +} + +[RegisterComponent] +public sealed partial class ModularTurretComponent : Component +{ + [DataField] + public string? MountClass; + + [DataField(required: true)] + public string Slot = ""; +} diff --git a/Content.Shared/_White/Guns/ModularTurret/SharedModularTurretSystem.cs b/Content.Shared/_White/Guns/ModularTurret/SharedModularTurretSystem.cs new file mode 100644 index 0000000000..d82cc1ed58 --- /dev/null +++ b/Content.Shared/_White/Guns/ModularTurret/SharedModularTurretSystem.cs @@ -0,0 +1,61 @@ +using Content.Shared._White.DollyMixture; +using Content.Shared.Weapons.Ranged.Events; +using Robust.Shared.Containers; + +namespace Content.Shared._White.Guns.ModularTurret; + +public abstract class SharedModularTurretSystem : EntitySystem +{ + [Dependency] private readonly SharedDollyMixtureSystem _dolly = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnInsertAttempt); + SubscribeLocalEvent(OnInserted); + SubscribeLocalEvent(OnRemoved); + SubscribeLocalEvent(OnModularTurretWeaponShotAttempt); + } + + private void OnModularTurretWeaponShotAttempt(EntityUid turretUid, ModularTurretWeaponComponent comp, ref ShotAttemptedEvent args) + { + if (comp.OnlyUsableByTurret && !HasComp(args.User)) + args.Cancel(); + } + + private void OnInsertAttempt(EntityUid uid, ModularTurretComponent comp, ContainerIsInsertingAttemptEvent args) + { + if (args.Container.ID != comp.Slot) + return; + + if (!TryComp(args.EntityUid, out var modweapon)) + { + args.Cancel(); + return; + } + + if (comp.MountClass is string turretClass && + !modweapon.WeaponClass.Contains(turretClass)) + args.Cancel(); + } + + protected virtual void OnInserted(EntityUid uid, ModularTurretComponent comp, EntInsertedIntoContainerMessage args) + { + if (args.Container.ID == comp.Slot && TryComp(args.Entity, out var weapon)) + { + weapon.CurrentTurretHolder = uid; + if (weapon.DollyMixRSIPath is string path) + _dolly.Apply3D(uid, path); + } + } + + protected virtual void OnRemoved(EntityUid uid, ModularTurretComponent comp, EntRemovedFromContainerMessage args) + { + if (args.Container.ID == comp.Slot && TryComp(args.Entity, out var weapon)) + { + weapon.CurrentTurretHolder = null; + if (weapon.DollyMixRSIPath is not null) + _dolly.Remove3D(uid); + } + } + +} diff --git a/Content.Shared/_White/Guns/ProjectileContainerBatteryAmmoProviderComponent.cs b/Content.Shared/_White/Guns/ProjectileContainerBatteryAmmoProviderComponent.cs new file mode 100644 index 0000000000..c232f93b5a --- /dev/null +++ b/Content.Shared/_White/Guns/ProjectileContainerBatteryAmmoProviderComponent.cs @@ -0,0 +1,36 @@ +using Content.Shared.Weapons.Ranged; +using Content.Shared.Weapons.Ranged.Components; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared._White.Guns; + + +public abstract partial class ContainerBatteryAmmoProviderComponent : BatteryAmmoProviderComponent +{ + public EntityUid? Linked = null; +} + +/// +/// Uses the battery of the container it's currently in. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class ProjectileContainerBatteryAmmoProviderComponent : ContainerBatteryAmmoProviderComponent +{ + [ViewVariables(VVAccess.ReadWrite), DataField("proto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Prototype = default!; +} + +[RegisterComponent, NetworkedComponent] +public sealed partial class HitscanContainerBatteryAmmoProviderComponent : ContainerBatteryAmmoProviderComponent +{ + [ViewVariables(VVAccess.ReadWrite), DataField("proto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Prototype = default!; +} + +[RegisterComponent] +public sealed partial class ContainerBatteryAmmoTrackerComponent : Component +{ + public List Linked = new(); +} diff --git a/Content.Shared/_White/Guns/ProjectileDamageModifier.cs b/Content.Shared/_White/Guns/ProjectileDamageModifier.cs new file mode 100644 index 0000000000..f462bb4ab5 --- /dev/null +++ b/Content.Shared/_White/Guns/ProjectileDamageModifier.cs @@ -0,0 +1,53 @@ +using Content.Shared.Projectiles; +using Content.Shared.Whitelist; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Content.Shared._White.Guns; + +[RegisterComponent] +public sealed partial class ProjectileDamageModifierComponent : Component +{ + [DataField(required: true)] + public List Multipliers = new(); + + [DataField] + public float DefaultMultiplier = 1f; + +} + +[DataDefinition] +public sealed partial class WhitelistMultiplierPair +{ + [DataField(required: true)] + public EntityWhitelist Whitelist = new(); + + [DataField(required: true)] + public float Multiplier; +} + +public sealed class ProjectileDamageMultiplierSystem : EntitySystem +{ + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnHit); + } + + private void OnHit(EntityUid uid, ProjectileDamageModifierComponent comp, ref ProjectileHitEvent args) + { + foreach(var pair in comp.Multipliers) + { + if (_whitelist.IsWhitelistPass(pair.Whitelist, args.Target)) + { + args.Damage *= pair.Multiplier; + return; + } + } + args.Damage *= comp.DefaultMultiplier; + } +} diff --git a/Content.Shared/_White/Lock/LockDeviceLinksComponent.cs b/Content.Shared/_White/Lock/LockDeviceLinksComponent.cs new file mode 100644 index 0000000000..5f74e497e2 --- /dev/null +++ b/Content.Shared/_White/Lock/LockDeviceLinksComponent.cs @@ -0,0 +1,23 @@ +using Content.Shared.DeviceLinking.Events; +using Content.Shared.Lock; + +namespace Content.Shared._White.Lock; + +[RegisterComponent] +public sealed partial class LockDeviceLinksComponent : Component; + +public sealed class LockDeviceLinksSystem : EntitySystem +{ + [Dependency] private readonly LockSystem _lock = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnLinkAttempt); + } + + private void OnLinkAttempt(EntityUid uid, LockDeviceLinksComponent comp, LinkAttemptEvent args) + { + if (_lock.IsLocked(uid)) + args.Cancel(); + } +} diff --git a/Content.Shared/_White/RemoteControl/Components/RemoteControlConsoleComponent.cs b/Content.Shared/_White/RemoteControl/Components/RemoteControlConsoleComponent.cs index 43a9ae0253..7cf4a353d2 100644 --- a/Content.Shared/_White/RemoteControl/Components/RemoteControlConsoleComponent.cs +++ b/Content.Shared/_White/RemoteControl/Components/RemoteControlConsoleComponent.cs @@ -23,7 +23,7 @@ public sealed partial class RemoteControlConsoleComponent : Component public EntProtoId SwitchToNextAction = "RemoteControlConsoleSwitchToNextAction"; [ViewVariables] - public EntityUid SwitchToNextActionUid; + public EntityUid? SwitchToNextActionUid; [ViewVariables] public EntityUid? User; diff --git a/Content.Shared/_White/RemoteControl/Components/RemoteControlTargetComponent.cs b/Content.Shared/_White/RemoteControl/Components/RemoteControlTargetComponent.cs index d644cf2a29..c351db325d 100644 --- a/Content.Shared/_White/RemoteControl/Components/RemoteControlTargetComponent.cs +++ b/Content.Shared/_White/RemoteControl/Components/RemoteControlTargetComponent.cs @@ -4,13 +4,13 @@ using Robust.Shared.Prototypes; namespace Content.Shared._White.RemoteControl.Components; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class RemoteControlTargetComponent : Component +public sealed partial class RemoteControllableComponent : Component { [DataField] public EntProtoId EndRemoteControlAction = "ActionEndRemoteControl"; [DataField] - public bool CanManually; + public bool ManualControl; [ViewVariables, AutoNetworkedField] public EntityUid? User; diff --git a/Content.Shared/_White/RemoteControl/Components/RemoteControlUserComponent.cs b/Content.Shared/_White/RemoteControl/Components/RemoteControlUserComponent.cs index 9185e3045e..1da5ee7c6b 100644 --- a/Content.Shared/_White/RemoteControl/Components/RemoteControlUserComponent.cs +++ b/Content.Shared/_White/RemoteControl/Components/RemoteControlUserComponent.cs @@ -3,7 +3,7 @@ using Robust.Shared.GameStates; namespace Content.Shared._White.RemoteControl.Components; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class RemoteControlUserComponent : Component +public sealed partial class RemoteControllingComponent : Component { [ViewVariables, AutoNetworkedField] public EntityUid Target; diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 46b9b3d75b..d2092eef3d 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -35,7 +35,7 @@ Slash: 10 Piercing: 10 Heat: 10 - # Structural: 10 # WWDP its for structures bruh + Structural: 5 - type: damageModifierSet id: Rock @@ -51,17 +51,17 @@ - type: damageModifierSet id: RockStrong coefficients: - Structural: 1 # WWDP + Structural: 2 # WWDP Blunt: 0.25 Slash: 0.1 Piercing: 0.25 Heat: 0.5 flatReductions: - Blunt: 10 - Slash: 10 - Piercing: 10 - Heat: 10 - # Structural: 10 # WWDP + Blunt: 15 + Slash: 15 + Piercing: 15 + Heat: 15 + # Structural: 5 # WWDP # no - type: damageModifierSet id: PerforatedMetallic diff --git a/Resources/Prototypes/Entities/Effects/admin_triggers.yml b/Resources/Prototypes/Entities/Effects/admin_triggers.yml index e1f366678d..c9baefd00d 100644 --- a/Resources/Prototypes/Entities/Effects/admin_triggers.yml +++ b/Resources/Prototypes/Entities/Effects/admin_triggers.yml @@ -109,4 +109,33 @@ - type: SingularityDistortion intensity: 10 falloffPower: 1.5 - + +# WWDP # + +# This kills the SpawnAndDirtyAllEntities test. +# The test tries to get this entity's netuid to send the projectileComp's "Shooter" field to clients, +# but does this not fast enough, so this entity is long since deleted by that point. +# todo: kill that test +#- type: entity +# id: AdminInstantEffectShrapnel +# suffix: Shrapnel +# parent: AdminInstantEffectBase +# components: +# - type: ClusterGrenade +# fillPrototype: PelletClusterLethal +# maxGrenadesCount: 30 +# grenadeType: enum.GrenadeType.Shoot +# - type: ContainerContainer +# containers: +# cluster-payload: !type:Container + +- type: entity + id: AdminInstantEffectExplosionSmall + suffix: Small Explosion + parent: AdminInstantEffectBase + components: + - type: ExplodeOnTrigger + - type: Explosive + totalIntensity: 30 + explosionType: Default + tileBreakScale: 5 diff --git a/Resources/Prototypes/_Goobstation/Entities/Objects/Specific/Mech/Weapons/Gun/base.yml b/Resources/Prototypes/_Goobstation/Entities/Objects/Specific/Mech/Weapons/Gun/base.yml index f4b8f23f12..874ba6c56e 100644 --- a/Resources/Prototypes/_Goobstation/Entities/Objects/Specific/Mech/Weapons/Gun/base.yml +++ b/Resources/Prototypes/_Goobstation/Entities/Objects/Specific/Mech/Weapons/Gun/base.yml @@ -15,4 +15,4 @@ - type: ClothingSpeedModifier walkModifier: 0.5 sprintModifier: 0.5 - - type: HeldSpeedModifier \ No newline at end of file + - type: HeldSpeedModifier diff --git a/Resources/Prototypes/_White/Catalog/Cargo/ship_weapons.yml b/Resources/Prototypes/_White/Catalog/Cargo/ship_weapons.yml new file mode 100644 index 0000000000..685919210b --- /dev/null +++ b/Resources/Prototypes/_White/Catalog/Cargo/ship_weapons.yml @@ -0,0 +1,119 @@ +- type: cargoProduct + id: WeaponShipLightIR + description: A single IR laser. Low damage and even lower power draw. + icon: + sprite: _White/Objects/Weapons/Guns/Turrets/IR_laser.rsi + state: icon + product: CrateWeaponSecureWeaponShipLightIR + cost: 7500 + category: cargoproduct-category-name-shuttle + group: market + +- type: entity + parent: CrateWeaponSecure + id: CrateWeaponSecureWeaponShipLightIR + name: IR laser crate + components: + - type: StorageFill + contents: + - id: WeaponShipLightIR + +- type: cargoProduct + id: WeaponShipLightAnnihilator + description: A single annihilator MLRS. Fires a burst of low-damage rockets in a wide arc for suppression and area denial. + icon: + sprite: _White/Objects/Weapons/Guns/Turrets/annihilator.rsi + state: icon + product: CrateWeaponSecureWeaponShipLightAnnihilator + cost: 27500 + category: cargoproduct-category-name-shuttle + group: market + +- type: entity + parent: CrateWeaponSecure + id: CrateWeaponSecureWeaponShipLightAnnihilator + name: annihilator crate + components: + - type: StorageFill + contents: + - id: WeaponShipLightAnnihilator + +- type: cargoProduct + id: WeaponShipLightHotspot + description: A single Hotspot CIWS. Inaccurate dual-minigun, capable of firing in short bursts, intended for point-defense against soft targets. + icon: + sprite: _White/Objects/Weapons/Guns/Turrets/hotspot.rsi + state: icon + product: CrateWeaponSecureWeaponShipLightHotspot + cost: 16500 + category: cargoproduct-category-name-shuttle + group: market + +- type: entity + parent: CrateWeaponSecure + id: CrateWeaponSecureWeaponShipLightHotspot + name: hotspot crate + components: + - type: StorageFill + contents: + - id: WeaponShipLightHotspot + +- type: cargoProduct + id: WeaponShipLightHMG + description: A single heavy machine gun. Well suited for any task. + icon: + sprite: _White/Objects/Weapons/Guns/Turrets/hmg.rsi + state: icon + product: CrateWeaponSecureWeaponShipLightHMG + cost: 23000 + category: cargoproduct-category-name-shuttle + group: market + +- type: entity + parent: CrateWeaponSecure + id: CrateWeaponSecureWeaponShipLightHMG + name: ship HMG crate + components: + - type: StorageFill + contents: + - id: WeaponShipLightHMG + +- type: cargoProduct + id: WeaponShipLightBlaster + description: A single mining blaster. Tears apart hull and rock alike, but near useless in actual combat due to slow projectiles. + icon: + sprite: _White/Objects/Weapons/Guns/Turrets/blaster.rsi + state: icon + product: CrateWeaponSecureWeaponShipLightBlaster + cost: 18000 + category: cargoproduct-category-name-shuttle + group: market + +- type: entity + parent: CrateWeaponSecure + id: CrateWeaponSecureWeaponShipLightBlaster + name: mining blaster crate + components: + - type: StorageFill + contents: + - id: WeaponShipLightBlaster + +- type: cargoProduct + id: WeaponShipLightMiningLaser + description: A single mining laser. Effective at presicely cutting pieces of rock and hull, it is slower than a mining blaster. + icon: + sprite: _White/Objects/Weapons/Guns/Turrets/mining_laser.rsi + state: icon + product: CrateWeaponSecureWeaponShipLightMiningLaser + cost: 20500 + category: cargoproduct-category-name-shuttle + group: market + +- type: entity + parent: CrateWeaponSecure + id: CrateWeaponSecureWeaponShipLightMiningLaser + name: mining laser crate + components: + - type: StorageFill + contents: + - id: WeaponShipLightMiningLaser diff --git a/Resources/Prototypes/_White/DeviceLinking/sink_ports.yml b/Resources/Prototypes/_White/DeviceLinking/sink_ports.yml index b845b47a6f..2f6d1ef9de 100644 --- a/Resources/Prototypes/_White/DeviceLinking/sink_ports.yml +++ b/Resources/Prototypes/_White/DeviceLinking/sink_ports.yml @@ -1,4 +1,10 @@ +- type: sourcePort + id: RemoteControlSourcePort + name: signal-port-name-remote-control-source + description: signal-port-description-remote-control-source + defaultLinks: [ RemoteControlSinkPort ] + - type: sinkPort - id: RemoteControlOutputPort - name: signal-port-name-remote-control-output - description: signal-port-description-remote-control-output + id: RemoteControlSinkPort + name: signal-port-name-remote-control-sink + description: signal-port-description-remote-control-sink diff --git a/Resources/Prototypes/_White/DeviceLinking/source_ports.yml b/Resources/Prototypes/_White/DeviceLinking/source_ports.yml deleted file mode 100644 index 99fa14c837..0000000000 --- a/Resources/Prototypes/_White/DeviceLinking/source_ports.yml +++ /dev/null @@ -1,5 +0,0 @@ -- type: sourcePort - id: RemoteControlInputPort - name: signal-port-name-remote-control-input - description: signal-port-description-remote-control-input - defaultLinks: [ RemoteControlOutputPort ] diff --git a/Resources/Prototypes/_White/Entities/Objects/Devices/Circuitboards/misc.yml b/Resources/Prototypes/_White/Entities/Objects/Devices/Circuitboards/misc.yml index e85b54a32f..2d1a31ebef 100644 --- a/Resources/Prototypes/_White/Entities/Objects/Devices/Circuitboards/misc.yml +++ b/Resources/Prototypes/_White/Entities/Objects/Devices/Circuitboards/misc.yml @@ -14,7 +14,7 @@ - AiCoreBoard - type: entity - id: WeaponTurretModularCircuitBoard + id: WeaponTurretUniversalCircuitboard parent: BaseMachineCircuitboard name: modular turret machine board description: Circuitboard for a modular turret, which is a fancy way of saying "a servomotor tied to a gun's trigger with a string". @@ -22,10 +22,9 @@ - type: Sprite state: engineering - type: MachineBoard - prototype: WeaponTurretModular + prototype: WeaponTurretUniversal requirements: - MatterBin: 1 - Manipulator: 3 + Manipulator: 1 Capacitor: 1 materialRequirements: Cable: 5 diff --git a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Ship/weapons.yml b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Ship/weapons.yml new file mode 100644 index 0000000000..fe133f1478 --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Ship/weapons.yml @@ -0,0 +1,369 @@ +- type: entity + parent: BaseItem + id: BaseWeaponShip + abstract: True + components: + - type: Appearance + - type: StaticPrice + price: 1 + - type: Item + size: Ginormous + - type: MultiHandedItem + - type: ClothingSpeedModifier + walkModifier: 0.5 + sprintModifier: 0.5 + - type: HeldSpeedModifier + - type: ModularTurretWeapon + onlyUsableByTurret: true + - type: Gun + fireOnDropChance: 0 + shipWeapon: true + +- type: entity + id: BaseWeaponShipLightEnergy + parent: BaseWeaponShip + abstract: True + components: + - type: ModularTurretWeapon + weaponClass: + - LightEnergy + +- type: entity + id: BaseWeaponShipLightBallistic + parent: BaseWeaponShip + abstract: True + components: + - type: ModularTurretWeapon + weaponClass: + - LightBallistic + + + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightIR + name: IR Pulse Laser + description: A power-efficient, albeit weak infrared pulse laser. Being essentially a scaled-up version of a regular laser carbine, this cannon trades damage for extreme power efficiency. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/IR_laser.rsi + state: icon + - type: Gun + fireRate: 3.5 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/laser.ogg + params: + volume: -5 + - type: ProjectileContainerBatteryAmmoProvider + proto: BulletLaser + fireCost: 75 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/IR_laser.rsi + + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightAnnihilator + name: Annihilator Rocket Launcher + description: Fires a spread of unguided flash-printed microrockets that cover a wide arc. Despite the low damage output, it can still deal a devastating blow in hands of a skilled fighter pilot. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/annihilator.rsi + state: icon + - type: Gun + selectedMode: Burst + availableModes: + - Burst + burstFireRate: 10 + burstCooldown: 3 + shotsPerBurst: 10 + minAngle: 15 + maxAngle: 15 + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/rpgfire.ogg + params: + volume: -5 + - type: ProjectileContainerBatteryAmmoProvider + proto: BulletWeakRocket + fireCost: 1000 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/annihilator.rsi + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightMiningLaser + name: Mining Laser + description: A cheap utility laser, excels at melting loose rock and cutting various salvage into pieces, but performs poorly against softer targets. Has a rather short focus range, making it ill-suited for combat use. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/mining_laser.rsi + state: icon + - type: Gun + fireRate: 5 + angleDecay: -12 + angleIncrease: -6 + maxAngle: 40 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/laser.ogg + params: + volume: -10 + - type: HitscanContainerBatteryAmmoProvider + proto: RedMiningLaser + fireCost: 500 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/mining_laser.rsi + +# I'll put the mining beam prototype right after the mining laser itself to +# make it obvious what it does. +- type: hitscan + id: RedMiningLaser + maxLength: 30 + damage: + types: + Heat: 3 + Structural: 15 + muzzleFlash: + sprite: _White/Objects/Weapons/Guns/Projectiles/projectiles.rsi + state: muzzle_mining_laser + travelFlash: + sprite: _White/Objects/Weapons/Guns/Projectiles/projectiles.rsi + state: mining_laser + impactFlash: + sprite: _White/Objects/Weapons/Guns/Projectiles/projectiles.rsi + state: impact_mining_laser + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightRiftLance + name: Rift lance + description: We commit this body to the holy vaccuum, dust to dust, stars to stars, that the Creator may renew our us in the cycle of eternal life. - Luddic funereal prayer, traditional. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/rift_lance.rsi + state: icon + - type: Gun + fireRate: 0.1 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/mateba.ogg + - type: HitscanContainerBatteryAmmoProvider + proto: RiftLanceBeam + fireCost: 8000 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/rift_lance.rsi + +# I'll put the rift lance beam prototype right after the rift lance itself to +# make it obvious why it should *not* be given to players. +- type: hitscan + id: RiftLanceBeam + maxLength: 800 # fuck it we ballin' + damage: + types: + Blunt: 2000 # oh yeah + spawnAtImpact: OmegaBlastPierce # extra funny + muzzleFlash: + sprite: _White/Objects/Weapons/Guns/Projectiles/projectiles.rsi + state: muzzle_fast + travelFlash: + sprite: _White/Objects/Weapons/Guns/Projectiles/projectiles.rsi + state: fast + impactFlash: + sprite: _White/Objects/Weapons/Guns/Projectiles/projectiles.rsi + state: impact_fast + +- type: entity + id: OmegaBlastPierce + categories: [ HideSpawnMenu ] + components: + - type: TriggerOnSpawn + - type: SpawnOnTrigger + proto: AdminInstantEffectExplosionSmall + offsets: + - 0,0 + - 0,2 + - 0,4 + - 0,6 + - 0,8 + - 0,10 + - type: TimedDespawn + lifetime: 1 + + +#- type: entity +# parent: BaseWeaponShipLightEnergy +# id: WeaponShipLightAutopulse +# name: Autopulse Laser Cannon +# description: Numerous built-in capacitors are at the core of this extremely inefficient, yet potent energy weapon. +# components: +# - type: Sprite +# sprite: Objects/Specific/Mech/mecha_equipment.rsi +# layers: +# - map: [ "icon" ] +# state: mecha_pulse +# - type: Gun +# fireRate: 5 +# selectedMode: FullAuto +# availableModes: +# - FullAuto +# soundGunshot: +# path: /Audio/Weapons/Guns/Gunshots/laser3.ogg +# - type: ProjectileContainerBatteryAmmoProvider +# proto: BulletPulse +# fireCost: 150 + + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightHotspot + name: Hotspot PD + description: A rapid fire ballistic weapon effective against soft targets. A respectable close-in weapon system, it's effectiveness is severely limited by poor accuracy and low damage against any substantial armor. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/hotspot.rsi + state: icon + - type: Gun + fireRate: 20 + angleDecay: 12 + angleIncrease: 3 + maxAngle: 20 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/minigun.ogg + params: + volume: -4 + - type: ProjectileContainerBatteryAmmoProvider + proto: BulletHotspot + fireCost: 250 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/hotspot.rsi + +- type: entity + id: BulletHotspot + name: bullet (.13 point-defense) + parent: BaseBullet + categories: [ HideSpawnMenu ] + components: + - type: Projectile + damage: + types: + Piercing: 4 + Blunt: 2 + Slash: 2 + + +- type: entity + id: BulletHotspotSpread + categories: [ HideSpawnMenu ] + parent: BulletHotspot + components: + - type: ProjectileSpread + proto: BulletHotspot + count: 3 + spread: 4 + + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightHMG + name: Ship HMG + description: A jack of all trades, this weapon is a well-rounded option for any type of job. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/hmg.rsi + state: icon + - type: Gun + fireRate: 5 + angleDecay: 10 + angleIncrease: 5 + maxAngle: 25 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/lmg.ogg + params: + volume: 0 + - type: ProjectileContainerBatteryAmmoProvider + proto: BulletHighCaliberWeak + fireCost: 1000 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/hmg.rsi + + + +- type: entity + categories: [ HideSpawnMenu ] + parent: BaseBullet + id: BulletHighCaliberWeak + name: bullet (.50 flash-printed) + components: + - type: Projectile + damage: + types: + Piercing: 25 + Structural: 25 # weaker compared to other .50 cal bullets + + + + +- type: entity + parent: BaseWeaponShipLightEnergy + id: WeaponShipLightBlaster + name: Mining Blaster + description: Able to carve out chunks of stone and hull alike, this weapon's performance is severely hampered by it's low firerate and projectile speed. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/blaster.rsi + state: icon + - type: Gun + projectileSpeed: 10 + fireRate: 0.333 + angleDecay: 2.5 + angleIncrease: 10 + maxAngle: 25 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/laser.ogg + params: + volume: 0 + - type: ProjectileContainerBatteryAmmoProvider + proto: BulletMiningBlast + fireCost: 4000 + - type: ModularTurretWeapon + dollyMixSprite: _White/Objects/Weapons/Guns/Turrets/blaster.rsi + + +- type: entity + id: BulletMiningBlast + name: unstable energy orb + parent: BaseBulletTrigger + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/projectiles_tg.rsi + color: "#FF00FFFF" #E7C60F? + layers: + - state: impact_laser_greyscale + - type: ExplodeOnTrigger + - type: Explosive + explosionType: DemolitionCharge + maxIntensity: 1 + intensitySlope: 1 + totalIntensity: 21 + maxTileBreak: 0 + - type: PointLight + radius: 1.5 + color: red + energy: 0.25 diff --git a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/ship_turrets.yml b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/ship_turrets.yml new file mode 100644 index 0000000000..c41f91efd9 --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/ship_turrets.yml @@ -0,0 +1,176 @@ +- type: entity + parent: [BaseStructure, ConstructibleMachine] + id: BaseWeaponTurretShip + suffix: Naval, Remote Controlled + abstract: true + name: ship turret + description: A remotely-operated turret designed to accept anti-ship weapons. + components: + - type: Clickable + - type: InteractionOutline + - type: Actions + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.45,-0.45,0.45,0.45" + density: 60 + mask: + - MachineMask + layer: + - MachineLayer + - type: Sprite + sprite: Objects/Weapons/Guns/Turrets/turrets.rsi + drawdepth: Mobs + noRot: true + state: syndie_base + - type: DollyMixture + directionCount: 64 + repeatLayers: 3 + - type: CombatMode + isInCombatMode: true + toggleMouseRotator: false + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 450 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + WeaponTurretSyndicateBroken: + min: 1 + max: 1 + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak + - type: GunFireAngleRestriction + - type: MouseRotator + angleTolerance: 0.05 + rotationSpeed: 90 + simple4DirMode: false + - type: NoRotateOnInteract + - type: NoRotateOnMove + - type: Input + context: "human" + - type: ContainerContainer + containers: + weapon_slot: !type:ContainerSlot + machine_board: !type:Container + machine_parts: !type:Container + - type: GunSlot + slot: weapon_slot + - type: ModularTurret + slot: weapon_slot + - type: ItemSlots + slots: + weapon_slot: + ejectOnInteract: false + ejectOnBreak: true + swap: false + name: Weapon slot + priority: 1 + whitelist: + components: + - Gun + - ModularTurretWeapon + - type: RemoteControllable + - type: RemoteControlOverlay + - type: Lock + locked: false + lockTime: 5 + unlockTime: 20 + - type: ItemSlotsLock + slots: + - weapon_slot + - type: GunSignalControl + - type: DeviceNetwork + deviceNetId: Wireless + receiveFrequencyId: BasicDevice + - type: WiredNetworkConnection + - type: DeviceLinkSink + ports: + - RemoteControlSinkPort + - type: Battery + maxCharge: 2000 + startingCharge: 0 + - type: ApcPowerReceiverBattery + idleLoad: 5 + batteryRechargeRate: 200 + batteryRechargeEfficiency: 1.225 + - type: ApcPowerReceiver + powerLoad: 5 + - type: ExtensionCableReceiver + - type: Alerts + - type: Telescope + lerpAmount: 0.25 + - type: Silicon + entityType: enum.SiliconType.Player + batteryPowered: true + drainPerSecond: 2 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 1 + 1: 1 + 0: 1 + + +- type: entity + parent: [ BaseWeaponTurretShip, InnateMassScanner150 ] + id: WeaponTurretShipLight + suffix: Naval, Remote Controlled + name: small weapon mount + description: A remotely-operated weapon mount designed to accept light anti-ship and anti-infantry weaponry. + components: + - type: Sprite + sprite: _White/Objects/Weapons/Guns/Turrets/mounts.rsi + state: light + - type: Battery + maxCharge: 10000 + startingCharge: 0 + - type: ApcPowerReceiverBattery + idleLoad: 50 + batteryRechargeRate: 1000 + batteryRechargeEfficiency: 2.45 + - type: ApcPowerReceiver + powerLoad: 50 + - type: Machine + board: WeaponTurretShipLightCircuitBoard + - type: UpgradeBattery + maxChargeMultiplier: 3 + baseMaxCharge: 10000 + +- type: entity + id: WeaponTurretShipLightCircuitBoard + parent: BaseMachineCircuitboard + name: modular turret machine board + description: Circuitboard for a light ship weapon mount. + components: + - type: Sprite + state: security + - type: MachineBoard + prototype: WeaponTurretShipLight + requirements: + MatterBin: 1 + Manipulator: 2 + Capacitor: 3 + materialRequirements: + Cable: 5 + Steel: 10 diff --git a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turret_base.yml b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turret_base.yml index 4021de8f63..f4d3b4d7e5 100644 --- a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turret_base.yml +++ b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turret_base.yml @@ -76,6 +76,7 @@ forceShootForward: true - type: GunFireAngleRestriction +# this is dumb - type: entity id: BaseTurret3D abstract: true @@ -87,10 +88,7 @@ layers: - state: syndie_base - type: DollyMixture - states: - - dm1 - - dm2 - - dm3 - - dm4 - - dm5 + sprite: Objects/Weapons/Guns/Turrets/turrets.rsi + statePrefix: dm + repeatLayers: 3 layerOffset: 0,0.75 diff --git a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml index e7af01dae7..e69de29bb2 100644 --- a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml +++ b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml @@ -1,36 +0,0 @@ -- type: entity - parent: BaseWeaponEnergyTurret - id: WeaponEnergyTurretShip - name: ship laser turret - description: A burst fire heavy laser weapon mounted to a simple actuator rig with a camera. Its weapon will recharge while connected to an active power grid. - suffix: Remote Controlled - components: - - type: DeviceLinkSink - ports: - - RemoteControlOutputPort - - type: Gun - shipWeapon: true - burstCooldown: 0.4 - projectileSpeed: 50 - angleIncrease: 1.25 - maxAngle: 5 - selectedMode: Burst - availableModes: - - Burst - - type: HTN # since there is no functionality to discard inherited components, we just disable HTN instead - enabled: false - - type: IntrinsicUI - uis: - enum.RadarConsoleUiKey.Key: - toggleAction: ActionAGhostShowRadar - - type: MouseRotator - angleTolerance: 0.5 - - type: RadarConsole - followEntity: true - fieldOfVision: 90 - - type: RemoteControlTarget - - type: RemoteControlOverlay - - type: UserInterface - interfaces: - enum.RadarConsoleUiKey.Key: - type: RadarConsoleBoundUserInterface diff --git a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/universal_mount.yml similarity index 57% rename from Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml rename to Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/universal_mount.yml index 28590ed083..16c1532861 100644 --- a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml +++ b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Turrets/universal_mount.yml @@ -1,16 +1,18 @@ - type: entity parent: [BaseWeaponTurretNoHTR, ConstructibleMachine] - id: WeaponTurretModular - name: modular turret - description: A remotely-operated turret designed to accept standard hand-held weapons. Being a simple gimbal mount, it is unable to recharge energy weapons. - suffix: Remote controlled + id: WeaponTurretUniversal + suffix: Remote Controlled + name: universal weapon mount + description: A remotely-operated turret designed to accept standard hand-held weapons. Being a simple gimbal mount, it is unable to do much besides aiming a gun and firing it. components: - type: Sprite granularLayersRendering: true + sprite: Objects/Weapons/Guns/Turrets/turrets.rsi + drawdepth: Mobs layers: - state: syndie_base renderingStrategy: NoRotation - - map: [ "weapon" ] + - map: [ "weapon_layer" ] renderingStrategy: Default rotation: -90 - type: ContainerContainer @@ -26,19 +28,19 @@ ejectOnInteract: false ejectOnBreak: true swap: false - name: weapon-slot + name: Weapon slot priority: 1 whitelist: components: - Gun - type: ItemSlotRenderer mapping: - weapon_slot: weapon - - type: RemoteControlTarget - canManually: true + weapon_slot: weapon_layer + - type: RemoteControllable + manualControl: true - type: RemoteControlOverlay - type: Machine - board: WeaponTurretModularCircuitBoard + board: WeaponTurretUniversalCircuitboard - type: Lock locked: false lockTime: 3 @@ -50,7 +52,25 @@ - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice - - type: DeviceLinkSink - ports: - - RemoteControlOutputPort - type: WiredNetworkConnection + - type: Battery + maxCharge: 2000 + startingCharge: 0 + - type: ApcPowerReceiverBattery + idleLoad: 5 + batteryRechargeRate: 200 + batteryRechargeEfficiency: 1.225 + - type: ApcPowerReceiver + powerLoad: 5 + - type: ExtensionCableReceiver + - type: Alerts + - type: Silicon + entityType: enum.SiliconType.Player + batteryPowered: true + drainPerSecond: 2 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 1 + 1: 1 + 0: 0 diff --git a/Resources/Prototypes/_White/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/_White/Entities/Structures/Machines/Computers/remote_control.yml similarity index 96% rename from Resources/Prototypes/_White/Entities/Structures/Machines/Computers/computers.yml rename to Resources/Prototypes/_White/Entities/Structures/Machines/Computers/remote_control.yml index e7c44f32cc..9c2bbc9442 100644 --- a/Resources/Prototypes/_White/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/_White/Entities/Structures/Machines/Computers/remote_control.yml @@ -25,4 +25,4 @@ - type: RemoteControlConsole - type: DeviceLinkSource ports: - - RemoteControlInputPort + - RemoteControlSourcePort diff --git a/Resources/Prototypes/_White/Ghosts/custom_ghosts.yml b/Resources/Prototypes/_White/Ghosts/custom_ghosts.yml index 43bbd0e1d5..70fef228ab 100644 --- a/Resources/Prototypes/_White/Ghosts/custom_ghosts.yml +++ b/Resources/Prototypes/_White/Ghosts/custom_ghosts.yml @@ -188,7 +188,7 @@ #just look at the ckey field you dumbass - type: customGhost id: redfoxiv-ghost - ckey: RedFoxIV + ckey: RedFoxIV@localhost sprite: _White/Ghosts/empty.rsi alpha: 1 ghostName: яицевозка @@ -200,108 +200,10 @@ simple4DirMode: false - type: DollyMixture sprite: _White/Ghosts/redfoxiv-3Dghost.rsi + statePrefix: hqyaitca offset: 0,-16 layerOffset: 0,0.675 - repeatLayers: 1 defaultShader: unshaded - states: - - hqyaitca97 - - hqyaitca96 - - hqyaitca95 - - hqyaitca94 - - hqyaitca93 - - hqyaitca92 - - hqyaitca91 - - hqyaitca90 - - hqyaitca89 - - hqyaitca88 - - hqyaitca87 - - hqyaitca86 - - hqyaitca85 - - hqyaitca84 - - hqyaitca83 - - hqyaitca82 - - hqyaitca81 - - hqyaitca80 - - hqyaitca79 - - hqyaitca78 - - hqyaitca77 - - hqyaitca76 - - hqyaitca75 - - hqyaitca74 - - hqyaitca73 - - hqyaitca72 - - hqyaitca71 - - hqyaitca70 - - hqyaitca69 - - hqyaitca68 - - hqyaitca67 - - hqyaitca66 - - hqyaitca65 - - hqyaitca64 - - hqyaitca63 - - hqyaitca62 - - hqyaitca61 - - hqyaitca60 - - hqyaitca59 - - hqyaitca58 - - hqyaitca57 - - hqyaitca56 - - hqyaitca55 - - hqyaitca54 - - hqyaitca53 - - hqyaitca52 - - hqyaitca51 - - hqyaitca50 - - hqyaitca49 - - hqyaitca48 - - hqyaitca47 - - hqyaitca46 - - hqyaitca45 - - hqyaitca44 - - hqyaitca43 - - hqyaitca42 - - hqyaitca41 - - hqyaitca40 - - hqyaitca39 - - hqyaitca38 - - hqyaitca37 - - hqyaitca36 - - hqyaitca35 - - hqyaitca34 - - hqyaitca33 - - hqyaitca32 - - hqyaitca31 - - hqyaitca30 - - hqyaitca29 - - hqyaitca28 - - hqyaitca27 - - hqyaitca26 - - hqyaitca25 - - hqyaitca24 - - hqyaitca23 - - hqyaitca22 - - hqyaitca21 - - hqyaitca20 - - hqyaitca19 - - hqyaitca18 - - hqyaitca17 - - hqyaitca16 - - hqyaitca15 - - hqyaitca14 - - hqyaitca13 - - hqyaitca12 - - hqyaitca11 - - hqyaitca10 - - hqyaitca9 - - hqyaitca8 - - hqyaitca7 - - hqyaitca6 - - hqyaitca5 - - hqyaitca4 - - hqyaitca3 - - hqyaitca2 - - hqyaitca1 ##xivi diff --git a/Resources/Prototypes/_White/Innate/InnateMassScanner.yml b/Resources/Prototypes/_White/Innate/InnateMassScanner.yml new file mode 100644 index 0000000000..f723d92733 --- /dev/null +++ b/Resources/Prototypes/_White/Innate/InnateMassScanner.yml @@ -0,0 +1,62 @@ +- type: entity + id: InnateMassScanner360 + abstract: true + components: + - type: IntrinsicUI + uis: + enum.RadarConsoleUiKey.Key: + toggleAction: ActionAGhostShowRadar + - type: UserInterface + interfaces: + enum.RadarConsoleUiKey.Key: + type: RadarConsoleBoundUserInterface + - type: RadarConsole + followEntity: true + +- type: entity + parent: InnateMassScanner360 + id: InnateMassScanner30 + abstract: true + components: + - type: RadarConsole + fieldOfVision: 30 + +- type: entity + parent: InnateMassScanner360 + id: InnateMassScanner60 + abstract: true + components: + - type: RadarConsole + fieldOfVision: 60 + +- type: entity + parent: InnateMassScanner360 + id: InnateMassScanner90 + abstract: true + components: + - type: RadarConsole + fieldOfVision: 90 + +- type: entity + parent: InnateMassScanner360 + id: InnateMassScanner120 + abstract: true + components: + - type: RadarConsole + fieldOfVision: 120 + +- type: entity + parent: InnateMassScanner360 + id: InnateMassScanner150 + abstract: true + components: + - type: RadarConsole + fieldOfVision: 150 + +- type: entity + parent: InnateMassScanner360 + id: InnateMassScanner180 + abstract: true + components: + - type: RadarConsole + fieldOfVision: 180 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/fast.png b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/fast.png new file mode 100644 index 0000000000000000000000000000000000000000..c53795c6354e7675391e89fbe5613071c557a469 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGojKx9jP7LeL$-D$|+&x_!Ln`LH zJ;%t)V8C;D!&LhheMi+}%^FicIv5y!#NPT=qHr=*9?Zi<$VEiFV_|aGxrz^@!qe5y JWt~$(69D$#f_RsDOdtL+q~R&`|YBTdXfXje8P&LNKZZERKsf Zz#*-d!^5&|Zrxds5>Hn@mvv4FO#p2pD1iU~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/impact_mining_laser.png b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/impact_mining_laser.png new file mode 100644 index 0000000000000000000000000000000000000000..653466cbce84e499e5399946d3e2b7d50983f201 GIT binary patch literal 1149 zcmV-@1cLjCP)Px(H%UZ6RCt{2oj-2kKorKGS7|8O5`mP~(N^4mh6^A|6fEKlROupjRO}THp|BL? z0yMcnDl2Z0K$M}RoGq+p#uGcX2WDcD?XV>-*bon000000000004fps zLg;RLbIFGMB6#$;| zxFP!|BAxUjN{{3+a0fKq(|dkA=7)xkuB^MFd2I1d0CguY0!kTc?(%MsvA(D?uW00000 z0000000000004mRglf;Qbx%~aqwvjf8`?zieyf(0FTEce`X^7$R|J8z=k8Xh9#0dx ztflIQzA&zzV$@iQQDZ6CBxS=Gm8H!Cz;q_C76r}WtrwHWN^b@M{2_FM)ciH0I0Go1 z0VX{1Mab(3nVz5g_;yKkZWtc`Chj)yRf>@um57FrW z!6fqNm-U*i9sLBH2iVom1!uxvbS8{zK{dG+1ONa4000000000000000000+6z8TH; zV{P7(mG24LxDj6~K63@wawW(?m!DSn?E@iqzU+%pv%#dktif&g4%txXjAPh(CtJlA zgV+tmhFO!Huntbn9s#>6FppB+cc%8Af`^~UZ=L`QaJ!tUBCs@ zsV%xxnu3z4Am~Z2;{pzo{(O18$>UmsQK~**9h~X`xHIG)$;(ZW4qSTUkRKE*8p4#0ssI200000aP|BLdKFY&SQg0J P00000NkvXXu0mjfXg4F! literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json new file mode 100644 index 0000000000..f33e7dba7c --- /dev/null +++ b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/meta.json @@ -0,0 +1,101 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken and modified from cev-eris at https://github.com/discordia-space/CEV-Eris/tree/7ff8f28ea4de734f3cc3cb70f2d4e4b4263a988d", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "muzzle_mining_laser", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "mining_laser", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "impact_mining_laser", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "muzzle_fast", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "fast", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + }, + { + "name": "impact_fast", + "delays": [ + [ + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002, + 0.060000002 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/mining_laser.png b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/mining_laser.png new file mode 100644 index 0000000000000000000000000000000000000000..e1231014db558fc9fce68b9ea7d3c54a579e27a6 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGojKx9jP7LeL$-D$|`aNA7Ln`LH zy}FV2kb?lrfz40MVj5m6F6CNP@I*>L)Aa(QqTj>~GP8v4rRF@C$@VSZfBkAEpgsnR zX1%`+m4CLT{L7VGB>Uy}a#!vf^G<$Q_4-T4x%*qE#U7~lTo!&;Kig!#zxafIjPKuT k&w9_+k`K~~6U;frxM!EF<0R#ye?e+IUHx3vIVCg!00g^91^@s6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/muzzle_fast.png b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/muzzle_fast.png new file mode 100644 index 0000000000000000000000000000000000000000..02756543c58715372bea59fc67234cdaa873ba11 GIT binary patch literal 497 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGojKx9jP7LeL$-D%zS9`iRhE&XX zd&55Hkb}takN1sMtesjScTgx>YEKh;gK*>|W`pEJ-d@uwG6(g<_;l-!r3(rPH5we) zbn)TuOs6!Dd#9^+zhUD9n#<7O{b-fn1N)8tnwQSM`}v6X+bp|0p{RWVj>+3*1+9Mh zb>G)!;ZAEc&vk;KM%9;oTvEw7bNl#{6ssuHgZ_V-(;9TymhGOmDTV1Ym!Lu2!XJ|^ z{SYfZbKK{Sbyw~+30v;TfaU(|L$3C8}r2`|7^7Cex6_qyvMM4vwqpR zopUWySWnnj+}oy9k>j+Gad**=xyKtVr|2L0>=Amd!AUOYgXD&Z&MzbtHnPpB=Do3- z_iTSbG>^~MGNVt-xz3*pb;7nOb8h3E*SGEct}x~YSDwj#k$bRiUQD73+cT+&oB!RY z+0XN~cV>1?*pIGz&Hq|f-D}Z(H)H+Z`d3A}D_V;Gh_iqKju;^RoSl8o1sA#O`$Zt- Mp00i_>zopr0Lcy3BLDyZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/muzzle_mining_laser.png b/Resources/Textures/_White/Objects/Weapons/Guns/Projectiles/projectiles.rsi/muzzle_mining_laser.png new file mode 100644 index 0000000000000000000000000000000000000000..b1aced77080a07bfcc68de19e84468e112c4ae29 GIT binary patch literal 680 zcmV;Z0$2TsP)Px%Vo5|nRCt{2+p%uiP!z`Tld6lybVO8Qb=!$IV95(0qzrDAXXuov5q$tZLu7S` zgz^Ge@&=h`SR*-N3}eUB!9C5zGB(85b{qeHQxw4G+x&SFsm5Wd%em^)y=ok$?Vbe7xvHw_a;~ivj)Fv^AlVxD(|y)M zTMOXUSM^)}sOk+i*@KzLahUyYvl4mt;i&Snbwoj;7u%RzK6|9fP-)s3+}OTs>~>1otHA za%Z@^bl*PM0S)lB1MFZTTmxJ_uK@=a?kXeyTJM5tHNbN~%g+G-00000000000002M ze!L{R+;Gx(G-*FE)^`?A>begA$Z7LuOaOX`yP%ijIRF3v0001>KYjz_r(s!#gWRkD O00009Q7kcv5Pryk@ztRTQ*u9+IW zLoB25Q4F(gKvQO8n4Z4ex5Hx7BQ`#nD=xI_atAvz$H$VmiHei*(lXXEG926a-EMDw zRl^ebyXU=H;usi$yrd^aWoKNs*7~5WqQJ=M@!&nv!uQ6{-zd8<8#`-0{UyQsEwF3K thwN)dYhvGQ=$r0z>HH_17J=>0nZIpR6#lcqdqx<@2=y zpi=qooU{|Iwd1_+oFjyA(@uzpD)*aK06^0;NenSYthI~we2x~i18v(*4u}Xb#>KcX zW)cC=b=`9vm?xYsv=!4X4jB#re4X9+couwIf;#Vej)30ysl6^b=iIEf9J@z#Aj<)G z>_X1&iv+;+m)vq7r}}>-V9$lz-9u&#Bzog_YC!+(6In-bLPS)t!vw64;l0>l0*o=L zn1-Sv1o%9=v6t(jHV#}uS*{`n0J`DF@*&<{PKOH+k(2ix@4fo*@l*k@eJ#IK!1@vL iask%b;_9zd{tVyfF=byFj*zwh00000syM2ied;MAR@CkU86^^vBcL~jDZXwxYi%-`&;7>kK$Zh= z--Vph7YTsND|yR-obLaVfHfC#PY;zopr0I`8K AiU0rr literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix4.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix4.png new file mode 100644 index 0000000000000000000000000000000000000000..e445ed1636bb4c3395b63084df04036b7229ffce GIT binary patch literal 319 zcmV-F0l@x=P)hDQO9Qn^L zM*;?ecW0+rOhnRS?>%a*H!%P(^TT=f8UbrsYapT}wxSXcLI40T^RjuzIk(&^r97Nd zRRRErF-qU?CnW&DA?L+~Qi>|4TEKMla_{-)S5@UypMh_8xL$OtV_dDM(6G4!Y5~CY z9QfIRIy<1PzgfUvE@;30U&I*Y49FRf?udoW9WYy#bC&+^JLiy6GUfWPyc9x^b^C3t zA%tKmgLxLLhY#@Uf(3I4h)8Yfq%XGTmm|n{4!gc}%gTde#Tma8HWyHxg R_;mmP002ovPDHLkV1m}?h>`#R literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix5.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/IR_laser.rsi/dollymix5.png new file mode 100644 index 0000000000000000000000000000000000000000..a72458fdeba7d3b847a723f8a9447c3b715ff119 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ98VX=kcv5PuWsaRFyLWvXr6II zdq(IUCg+V!;RlUdtvcGumjwI?&AivOZ-Z;c3Ww0ytG1o$5#`-gU0q$jb)lo6pz-P> z{}UaXuP4U7{XO%;nw2*gq!XAwte^kdTxmh%2d#5HCRXP0fhdEP)Px$HAzH4R9J=WmECp2APj|Xdb$8B$RnsDWCd18M=&G62+aztzzAUlt-uKM!N!eG z46%Fq^TPKc+X8eEmH;}PPNxD9Wg^PsIOgAsb7~0y0If9uK&Jq&&Wm-L3L*k939{B^B7#y1M1)}&9{!tZ2ACNsB@hwL)=nSC5daWpd!20wKtvD` z82|NNe6?e&3Wza6L?9v$DZU>A03ig3$P!FbTFq^((L4g6q;wl*22xn6C8ad)bP8sS zd0MJZ1$>A1Yuw!0tQc4KbLh*2~7a5OF>!y literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix2.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix2.png new file mode 100644 index 0000000000000000000000000000000000000000..2f00f868db945135e97a59f054b43e4ecdc71c5c GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ4o?@ykcv6U2@Qbr_4O+)Rh!n-TI#g2<%U8?3CgYc$Sdzi(oBJXk(&x2Ms|4+q(M+WGAiv^NGGW!%EBm`}mlZYyuegVu{zxx-JG nr5|ukxWc%Y4{R-u1p~tYVe#fi*BID=Zes9s^>bP0l+XkK=CDXt literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix3.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix3.png new file mode 100644 index 0000000000000000000000000000000000000000..a4c9c3416e56972b70dc46e154cccc6e4fd25950 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJiJmTwAr*6y6C_v{Cy4YkP2`g} zc`-$B#UJ_DH%ET$PMLYsX^m60`_cbAK(NQ@3{U>Q#2fx*3bz=Q=JfE`Th3gOX2=t8 z-zCcO!P)QsdFJ2$yL1N=sCQudd1M$EOoOF@gntR013Heu)78&qol`;+0P>$or2qf` literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix4.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/dollymix4.png new file mode 100644 index 0000000000000000000000000000000000000000..5441cf8e59b9de4bd66fa125e58c630c1a028db1 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ8J;eVAr*6y6C_v{Cy4YkP2`g} zc`-$F(J%SfH#cV8PMLYsX^oS6`qKY3hje)6-}{&N3kcv6U2@8Jir7ryh*X>RfGWncWU*Kz>XB6It^gvAS&7z^S5e%uQ@#)FOpLHcvnNJ7H! z;Cjg99K#l0@!IV3$M~MjWPGsO*6!JVtL?RoFWB0?Gc|bouDDw%T_h+dIPrKC@>4y%+IPVZqh;G3NJ zTrcXBuPDQfxSNOfKS-%kSkKO|lBZusNlEEbw)oR4dWZu@&a2dA&KzaK*Hj$DxR0&!1oYV(;KuxZDnENLVm1 Zthmn3GvmqXZ$NVyJYD@<);T3K0RRKNE13WQ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/icon.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..11a0f33df8455c99e6166aad19df0220a82e5368 GIT binary patch literal 257 zcmV+c0sj7pP)Jt=Xy&UnlbOw% zw=)YEhGG1foF=(HXt-)A0011$#ALix)%yt2UXYf=9dw3uSH6abI&dmTEN4F2sU68{ z3*OOex12A&S}b1*Qwb0uM4sm?NGyOt0HG)LBLTo?2S~l3Oda^L00%}Kpb(V!%x#uy z^%kfKy1kmK6z^+zyb!bLKJ`bWngP;1-k$VsoM9M-VW_zQnO0XEDq3gq00000NkvXX Hu0mjf{}g4J literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/meta.json b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/meta.json new file mode 100644 index 0000000000..8c8a797a7a --- /dev/null +++ b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/annihilator.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "WWDP", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { "name": "dollymix1"}, + { "name": "dollymix2"}, + { "name": "dollymix3"}, + { "name": "dollymix4"}, + { "name": "dollymix5"}, + { "name": "dollymix6"}, + { "name": "dollymix7"}, + { "name": "dollymix8"}, + { "name": "icon"} + ] +} diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix1.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix1.png new file mode 100644 index 0000000000000000000000000000000000000000..b898d00812cb7714366319ecda8aa14128191b2b GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ98VX=kcv6U2@Do zJUq^pToas|0#*dvP0A5_B&5#5X2azsYw+bjhLTL_0SyV(!+Z=3{)g1-_wTyH3AC5N M)78&qol`;+0PN#3qW}N^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix2.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix2.png new file mode 100644 index 0000000000000000000000000000000000000000..988e90030c9f650a8533b5615606dbff7492a83c GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ#Ar*6y6C_xfc_cgoYceNZ zt!D#*y*rY749s{Gx?diZRlXIY79``q?XZRULamSP)|A!*tK58fxHoiOJi~Z}Wig*b zDZ^FSg2(@=CtaBwB4lJBa4s+L>vd0~$!iwP5Lgf$X!CM{*x@D4QBx!wXEA?y)Mxmp z`?2)*`;(tkPm*njxec@;`OlA+%7>5p%Rj71F+IX079_H``ReMh$#Xg`9{ixqp7Dwy zNk}4ANO5V_i82P=11p$4${N}hDMS`6P7vXVVqg&DaXUVraqTIfml!-<{an^LB{Ts5 D=7nL; literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix3.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix3.png new file mode 100644 index 0000000000000000000000000000000000000000..283daf6f62b72d35c5182f4ae7e3d646d7fbbd1b GIT binary patch literal 298 zcmV+_0oDGAP)UcjEphD5I5B`i6M1(hw=U^^2US_-Zpi49kP;R0HiHN+p>Sy)iBuOgFW z=PfhL0*;vxoWZapmVz}2f!pu)uH(z9#%_ON?P)ZMKQY-Tj`IL<9t_!nC*X&L z=&NyA)vVLA1-iFglzO0+KrJCky?bKLJ-`;|A`>a7Ay7k*iDWmkVrlv!0AyKaoLKQ& wgGi^rCTYT7aYIW#eytj)8FZwGTSjoDuBcCNQd^k#79eh%uD$Ia?2AF0a@X{_Eu_A=kDKH z`FsA9s)okKLmCmgQZ$e5likI7vB9EY28&yklFCWOBPs?#!VfQWH3hO87$}^o33}>w eP(xx114BeZbm!4I=aPUPX7F_Nb6Mw<&;$U~s%tX< literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix5.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/dollymix5.png new file mode 100644 index 0000000000000000000000000000000000000000..d249549b5f8fe8312f083b6bd4ca27710e1c3949 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ3{Mxwkcv6U2@&qw2sGeolVxD|w8Q)hkJ5n>pq&h!u6{1- HoD!M<#j-c$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/icon.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d274c6cfda5995e39459421e003cc0092fda9415 GIT binary patch literal 411 zcmV;M0c8G(P)C{{F|HAi;@OgQTzo!=6(wP#n7L*fR`u=wez* zf`lEw&dNl=-uQHe&e4zzWA<_177Z z`TrPL8Lr*`LOlmOfBTc+`P-iiMQhaHVhc}5ljQ-D65-Xm@8N70GYN*ikXsCUPQ5^i z5^=bEpq)4aF@U5*2upy}1St9P!5X{&lEUl+HSIa|f7GzKeIYgau z;1^P=|Mlk|gQ2=Giv0PTZ!yGh0gNbMU?7|wfB*RhSBuQXCXa45I$%OqL<|nAzs`t_ zjZX|0z=)F-je7sJ6nXH5fL`1&s#Qj#U=)mkQ7{Td0RYV_&+UX?{3iea002ovPDHLk FV1hhcx4HlT literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/meta.json b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/meta.json new file mode 100644 index 0000000000..d75991f1a1 --- /dev/null +++ b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/blaster.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "WWDP autogenerated", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { "name": "dollymix1" }, + { "name": "dollymix2" }, + { "name": "dollymix3" }, + { "name": "dollymix4" }, + { "name": "dollymix5" }, + { "name": "icon" } + ] +} \ No newline at end of file diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix1.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix1.png new file mode 100644 index 0000000000000000000000000000000000000000..9fbb64fb0e6fc04a0cc9853970232972be56e57a GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ3Qrfukcv5Pry6oK81T3*u9!II z=z~XVw-@5eess4Nph7aXxuUXUN=B-}!a_>>CfXMG_x4eFB zarUr);90@>-@nBPcO20%n000Hq3=Qs3@i!)y}Ns=ViR;1e_@eRRC0BRQ4R6*XJ8WW c5N9y2^O59z|K;R7pc@!GUHx3vIVCg!0LBAEv;Y7A literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix2.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix2.png new file mode 100644 index 0000000000000000000000000000000000000000..9edcc5aee6e36d3223936d959971c0bc2a792d66 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJDo+>3kcv6U2@!&#OMvl>#^ zAAHudTxjscDd7s^Vm=9=9>$w*8DmNhPRQmDVEOa+@BiPwe@_nOJb0j?{lE%lH(7%R cd=jh-Z2u&uUUiNZ2fBj6)78&qol`;+05{7+3jhEB literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix3.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix3.png new file mode 100644 index 0000000000000000000000000000000000000000..d9a7c527b16dac3142eac0a8f34c576092ed0cb8 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJEKe85kcv6UDGGubT3U~$?yvuE z=lRTV;wy%%=0NrytAs0z%Ns>mLIvbaiUD|2`lHSJ1N>t0`@M8G18rsSboFyt I=akR{0Q|@{QUCw| literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix4.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/dollymix4.png new file mode 100644 index 0000000000000000000000000000000000000000..b72d55f4b70c7bcc64077f3a370020ecebf16ef5 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJI8PVHkcv5PuWaOOFc5IKC~v-V zB8&BNZ*_|xw~JvdBAgoy|4(PPjGM)5y!od0T7D&_hSK}%p8q-H&ZM!_WME|4rJuOgQg0!U#qx)%fLZP&pQbk33}2v444$rjF6*2UngBNPFOvWO literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/icon.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hmg.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c20651fcf467ff32ae4efc6a55a5d45852301bed GIT binary patch literal 244 zcmV1R>ZWA=hQ61_vudVz@z}vF(&Ku%i03XOi#GeM=lY9rJ-#@9z&1S>m gc2EPXoyUTKp(RP6?Thb^KA_nQp00i_>zopr06#b>>;M1& literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix2.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix2.png new file mode 100644 index 0000000000000000000000000000000000000000..bd6f3ace8b9124e980236e9cced8a86e44ebc12d GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJc25__kcv6U2@8oXkdB-^0Be{!%GPX)(@ z39A~rySo!Frt-JR%kMYLxxa1h#Ky+PgO^W#wr95&XBNL6)s}yM-^7%A4ebY3Fhlfv j>jA-@PfMmTFJ@q1YEg(6>zDKeI*Gy4)z4*}Q$iB}07*iy literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix3.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix3.png new file mode 100644 index 0000000000000000000000000000000000000000..0f3af05b37f44f0addbe5aad1fd1bdd4b69ffde0 GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ4o?@ykcv6U2@<~g`?J}qwyLLf)UqP_ynEF64x|fO_9FVdQ&MBb@0M*SvrT_o{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix4.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix4.png new file mode 100644 index 0000000000000000000000000000000000000000..477f8cfcf4dc9db9cdc9d335e1ec0baa00856c14 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzKTj9Okcv6U2@bP0l+XkK$rdc_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix5.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/dollymix5.png new file mode 100644 index 0000000000000000000000000000000000000000..8ece2b9fa277e2d120f70689b92c6c3b7605a621 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzUr!gukcv5PFKpxmO1K1;a%CSY zOgO%=j61gB5J#5JzttS9GA#@Y4UX%Ls-`B+oTzhp>#ryV{bgTe~DWM4fEetGQ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/icon.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/hotspot.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce46002a8d1165bae496d337d09075d081fbc005 GIT binary patch literal 286 zcmV+(0pb3MP)`EPgksSlDN}N=OhFO-R zz-(})RdqPr#&q3UMw=ok05I)r0a)z&8U2w0`JwNW5EVFHW9FL%0BviT>Rog(&ic_; z(6lACLd2Ia2>im;l&}AUq9XuEPKng2D2k#e86NVzJ-I5;rTG8=002ovPDHLkV1l9G BXu<#h literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix2.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix2.png new file mode 100644 index 0000000000000000000000000000000000000000..02934a63827c8ff69d8621c35e0d642f616f56f3 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJJ)SO(Ar*6y6C_v{Cy4MEB&dWh zp0(&-eaXh?@A{K+FSZ_gX@GAN3;IM!TH z;<7GL=hWmlz;4m-NIcx&^1hVGzMMd%AkeVAHg%0h|Eyfu@A!`oT$iVT;?2KiTH2J@kR|+`fYDiqA7VN*T5?o>Xjj zlburVU>%##d!e^74cvQveeBVxRk2RETATMqD5n19V+PJl!$Vzq0{L<$I}46q>lHZ} z{Dy%)zrO3qMMhOs#ZU(2ol+OImD$+X+PKC0Cg;fAy!qj_yV0rGEanW2gpjjK7`nP1 x<;(9kT%q|YSVT%>YD>(TJySB|!CvHJU{Kd|mQ&MQ%L?>AgQu&X%Q~loCIAAmdbt1q literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix4.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix4.png new file mode 100644 index 0000000000000000000000000000000000000000..ec6c027da83cadd3ad59b7cdd0d040b640f2ccc8 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=hEVFj{-MIEGZrNluVpU7R4o6= z@N>RMVNFA42(R3|fB#jN9Nlor)1%w4qT=`DCmdoyvL7D3)RquFtfXRj%d+92v@tUf zG&j!T6|J?gFx`T3t3gp|AA~r6dZ3 zO?JFGqMw61{E_Njb25kK&q|D6xZPt5`91jrW zHdg(Af9L-pgZGDQo1O{JWqTI8<9NmMf8uQ*b9i_r+-d0Z+&ZVRu|=SPG2)TcafLp` z^dldH-bDnRRh5)jar004W$xeS4;(n~V43*0`wnN@o*X-&0Sc=C28L^*5$~RqZR-Js OCWEJ|pUXO@geCwj)toy3 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix5-unshaded.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix5-unshaded.png new file mode 100644 index 0000000000000000000000000000000000000000..21b16235f1de755fd518fb667c80510b036bd813 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^4M42G!3HF6DHW&!DGyH<$B>FSZ_h6jZ7|?*IQXV9 zb;Y{o*B(8G7~V{LHEV|rOZmIg@{B;0Q1Iu9&HOdHZda#<-F^G|f8m`-Q;RqWfH3V(NIV`m>%d(NB=LJhn@4gQpf(^m z1dx52==lWBR#bzq@89~uu{x|5w->D5mm?#tBxcGv<2$@S5)I6tdN0$K~ar|Xh#qo1&V4s43VA37>OzG zBex!BTwZQPT?fFxg$u_SVdcGytSnso$>YZi3=9kmJGO3QB*i?Uqu~CnFAOkW!7O?5 z_%R$Ki!U#?`hWk{7wS5oYW*cfG)JJw!}u`EtJYs4DkMk>E(QifVqADd6hkgv=QRT< pmQw^W9jpK2oOA#H literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix6.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix6.png new file mode 100644 index 0000000000000000000000000000000000000000..8c467d971c69cf944f79a24928454e3e80e64b06 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ_nt0}Ar*6y6C_v{Cy4O4CL|>M zoG(&X)6f~hD|heTf7K;NH=OeH=r*jV_&xavhggv8het29C4>(vsaW2!Jkaq_wZ$yp zkP`RA-45RDD>Oa{gt;_vdz2k$+%3fe0(_^;3r-mt#3ZmGPva!r_v(Mj&{2 zuJ%rmN$CMgwnC+lyNl;C7ffZ;c);}W8E=J@L;-t1kWdh-!KB5Ss>kOW*elF{r5}E)BhHXLs literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix7-unshaded.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix7-unshaded.png new file mode 100644 index 0000000000000000000000000000000000000000..853d3fe8059864d57e6475630c90789f5690bc54 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^4M42G!3HF6DHW&!sTfZe$B>FSZ?A3SZ7>jEKJdoz zbikU)eG?^G8E+`xROtWWqPZhmH?rtCNH-Y#*j~IpTJ3yQmh?CG%4@Iw9xvnly;z3f rf$(O3|CDbpyVu-%|Ai5#@`D$9a*zBjx0~0sLHayh{an^LB{Ts5q~|qq literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix7.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix7.png new file mode 100644 index 0000000000000000000000000000000000000000..9e189fde05ad51c46d91c6f84f83d3f64809257a GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=hEVFmijkIEGZrNluVpU7R4o>vSGLR_n^C==VqNnbl_XgIeT9VeS9`?4%>!E zKTZW(u7Ze~7gLml-b=idDfoX)e9fcs`}fqYYJ8F@crjh6xo3?|+m1OFL3|2|yc6Cq z8 SzW)sj9R^QVKbLh*2~7Y#g@XkE literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix8.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix8.png new file mode 100644 index 0000000000000000000000000000000000000000..91303a24a7345176b1b826d4e260d4e11485508d GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJH=ZtzAr*6y6C_v{Cy4MEB&dWh zZr}dDUNSP$;{VCV$9b%`<*D4X*(5Vz(!|do0f|ROn>O(jr}-$J^qD04;Njc<^Cw6J zIW@J0u>Yw(b8dmono|ne8zi0IePoZ<$X34iY~mY+)WlFW5O6h>^I@N(bk)R2CLw*> z`~`PP?syq62(RQ@V5VTn@+^OPVge8p1ng^6EPt?$?XBzqmEV&af#Bi19kR>r=x1Ep zFSZ_h7eY%maDIry5{ zJ8+AzyXTZiOfMcQZ&=?v({QypBTyj-G^p%69~oO-=^lDL_TRt#eam+-K_qI#ViwBp T;(vN862$j(^>bP0l+XkKre!A5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix9.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/dollymix9.png new file mode 100644 index 0000000000000000000000000000000000000000..9c099943e15b35d2c84d91953a05a70f1c1fc8f1 GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=hEVF!Fi2IEGZrNluVpU7R4&Q*yv# z-LWY>bN&Yf85R87obE62?92?OO_eE@2M*uZfICzdg;m z*J$kc{mrad_IX{K`S*lA%X13a8)nKZK2gjt`Hg?uUin@HnXmm|hkciLv%s=(i;2TD z=9H9F$qA2Ga_k4#OH} R5nuo@c)I$ztaD0e0su-ne;oh- literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/icon.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mining_laser.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..093d9f201b4f20531594dd7e5089b432c9debee9 GIT binary patch literal 620 zcmV-y0+aoTP)|Glaxwl z%*42c{`E2diNy+9txI)JMOG95%B7;KT8HtCO2{oOo8o-+`X=$Y7{9*X0YFw1f(&;jQ6$9i84-t7j%t5hDd` zZ#QV@I&d(#5Fse!S8RD=FJwg_J{NPW@3^_CbjDJ@uOH*)r3L`iwIuc3EquyP+chZve7mG zuV1|!yLW98t=8p})^#cmxOj|G>5M6^ps|16Cg8a?i4+PDY`$kk^`l1o09NxS8=ptk zclClr)U)P=sc(Hdu-ZA!#MA_UwIhJ*<{lm%9v&Y51it~Qr``)Na}Kcp0000VFiB6P|f3fWa!Snlq1*q-V%t7~q$z-Q-r4MqVcj*su- z=4>d=+kfhaL}YcHh5Yw>%1gf(C-*Qm%ng2IE6vhicbYVSg=tB`R^PZS2k)(>Hvt+f}qNPIv9sr`|J) g)81;f2=xDE>f>mdKI;Vst0J(Ws>Hq)$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/light_broken.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/light_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..6c3eb9a654815a1e22db5801d6d91b040254d01f GIT binary patch literal 429 zcmV;e0aE^nP)Px$XGugsR9J=Wl`%`hKorM++K8A8)}ex3r4+S`kxUWn!G_Ow~l-JM_z z80S}>E7dfOt>XseT8ATL*nNVN%(Acn-#q}3&1R`oDz1sIM5EDQ4Je92GMS{+YJFQ= zQIy~e)a!K$g@P}g2)=sYlV-DtuIrxl?di_57e&YbfMr<#lur*C>e|F(vL`Nz(9}w$ zQtl)i8R)XUFh;fU&h34ha;*b^X_~=I!XJ`5@t92Q@fFj&7ApK}=+hHD|A&x}kUz}_ X7L$4|ep5kJ00000NkvXXu0mjf(yYM` literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/meta.json b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/meta.json new file mode 100644 index 0000000000..b44648e414 --- /dev/null +++ b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/mounts.rsi/meta.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/42e0275d860551197687c571c689c270ff423288; edited by WWDP", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { "name": "light" }, + { "name": "light_broken" } + ] +} \ No newline at end of file diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix1-unshaded.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix1-unshaded.png new file mode 100644 index 0000000000000000000000000000000000000000..9113c476edf4ebf981da8686083e8f540a071cb0 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJEKe85kcv5Pry24cP~c%+yXyac zgXZ033q%bSwol6UHxPGVP;3#9Q;~3w}P1bEj*@;tKHGJK&_t`dCi_R5I{%^?8 z^L9;D+#9wxjHmW!hOJwDx52i-#eeIsC%1T29GK>0J)G3<#!$d09_e43uQ25S&{hUd LS3j3^P6#fdb5&P%tQ+H+VIlV7vp_B~c&M#cy z*UcDDIBjY<96Eo#@Qbx-4L1`Q3U>D;e%`gMs`hMP&xu3Vjdma2-n6>xKGV;A*P563 zIK7p#IKYy^uvOXryIw<_l{ipK^!ujrKY0yuR`L$n(n^o{8UI9cPGEQ!%)O`n82{!2 bx*ltb)hy-;y>D6#bTxygtDnm{r-UW|sXboi literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix2-unshaded.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix2-unshaded.png new file mode 100644 index 0000000000000000000000000000000000000000..bb0f858eae8787f5f92940b3351c790b22611069 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz6;Bt(kcv5Pk1gb7VBlaj_*XA! pD0e`?GwP}qQ1*w`%be#~3<8tbKX&c-)&>+|@O1TaS?83{1OVw!8TJ4G literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix2.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix2.png new file mode 100644 index 0000000000000000000000000000000000000000..3d537ed3bcadcbad2f6da87095962bdd66987431 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJc25__kcv5Pr#W&p81S$xwmoHvijDSuw^Ea&a& z#*0VH6C^eKb*DBQXNea6&ylC28L_2ONZ?^v+T7_eoGk_yx^EQ6epVGYbRhW3J$37J rrql=FY+|@O1TaS?83{1OVw!8TJ4G literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix3.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix3.png new file mode 100644 index 0000000000000000000000000000000000000000..7b6f4989b9324c29dc89f55da74591af48c3fbd9 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJc25__kcv5Pr#W&p81S$xwm)&& z<-^RTAN%C4O*UUS+re<+naayK+cQ^s1d7NTM;rQPr&Jr#BpCeC4Gh$1nkif&Tw7Jt`I9m)Zbl)hB{j4f*=s@t5d+OHd rOsNmT+3qm#uHp)1y>RFMu}4gn{3?P=O2l>moy6ej>gTe~DWM4fE5=Hu literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix4-unshaded.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix4-unshaded.png new file mode 100644 index 0000000000000000000000000000000000000000..2034eebe927833b31081ef3d78ad7905ab9a546f GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJMV>B>Ar*7pPT9zJM1jZI_v-Ke z{AnJ`Jp{Qj4c^`@sFZH9+7`;H(Y5GD`K>ojOSl=fe9QbcM@(+t<tJHQ zm(rFe{b5zz-nyf!XRVcwxY06krtFLQ17ZKR{u0es-;jHO*Tz*+gV{d*=uy^F!u?Ha T9VEGdu4V9a^>bP0l+XkKOB`4Y literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix4.png b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/dollymix4.png new file mode 100644 index 0000000000000000000000000000000000000000..916c70614fd4b03bfc5262c3d93e08b443f4ec16 GIT binary patch literal 274 zcmV+t0qy>YP)P^T_PXV+pXkw%rX%QyLfuNaC2nBv%rX%QyLfuNaC2nBvK-GNnbA%dT|;AazpRaX?WLkDrxkd`KW`5*|rqYj#PPH!L$ z(B@yl`G<4<;lAf~Y(#tt1eBL>J?~z(qigbVAt8$Z zaB4&=AXl%Fkwt7|j2g(E_Y%DNY$IbNpc845siu~zwa$>`!FK$ZE4fCQlIcPZQ2097bOIh*jO4!8~^|S07*qoM6N<$g31Jy A8UO$Q literal 0 HcmV?d00001 diff --git a/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/meta.json b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/meta.json new file mode 100644 index 0000000000..7ac543be08 --- /dev/null +++ b/Resources/Textures/_White/Objects/Weapons/Guns/Turrets/rift_lance.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "WWDP", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { "name": "dollymix1"}, + { "name": "dollymix2"}, + { "name": "dollymix3"}, + { "name": "dollymix4"}, + { "name": "dollymix5"}, + { "name": "dollymix1-unshaded"}, + { "name": "dollymix2-unshaded"}, + { "name": "dollymix3-unshaded"}, + { "name": "dollymix4-unshaded"}, + { "name": "dollymix5-unshaded"}, + { "name": "icon"} + ] +} diff --git a/Tools/dollymix/readme.txt b/Tools/dollymix/readme.txt new file mode 100644 index 0000000000..d1c21baa4d --- /dev/null +++ b/Tools/dollymix/readme.txt @@ -0,0 +1,19 @@ +Copy these into the .rsi folder you're working on. + +These require the pillow module ("pip install pillow") + +zslice - splits a vertical slice strip produced by MagicaVoxel into separate files. + Expects the source file to be named "dollymix.png". + Asks for vertical size and then will split the image into that many rows. + If "dollymix-unshaded.png" is present, splits that aswell. + Does not automatically remove empty images. + +zicon - uses the same "dollymix.png" file to produce a default sprite for the model. + +ztest - does the same thing as zicon at a higher resolution and different angles. + For checking how the "model" looks without starting the game. + +All file names start with a "z" so that they appear last in the folder when sorted by name. +Also for the purposes of goida. + +Recommended toolchain - MagicaVoxel for initial modeling -> Aseprite for layer edits and very basic animation -> the shit in this folder. \ No newline at end of file diff --git a/Tools/dollymix/zicon.py b/Tools/dollymix/zicon.py new file mode 100644 index 0000000000..1969e63d81 --- /dev/null +++ b/Tools/dollymix/zicon.py @@ -0,0 +1,25 @@ +from PIL import Image +import os, sys + +path = os.getcwd() +basefile = "dollymix" +ext = ".png" +size = int(input("size: ")) +offset = int(input("downward offset (in pixels): ")) + +base = Image.open(os.path.join(path,basefile+ext)) + +reverse = size > 0 +size = abs(size) + +amount = base.height // size + +out = Image.new("RGBA", (size, size), (0,0,0,0)) + +for i in range(amount): + if(reverse): + out.alpha_composite(base.crop((0,size*(amount-1-i),base.width,size*(amount-i))).rotate(90), (0,-i-offset)) + else: + out.alpha_composite(base.crop((0,size*i,base.width,size*(i+1))).rotate(90), (0,-i-offset)) + +out.save(os.path.join(path,"icon.png")) diff --git a/Tools/dollymix/zslice.py b/Tools/dollymix/zslice.py new file mode 100644 index 0000000000..2a7748d2f5 --- /dev/null +++ b/Tools/dollymix/zslice.py @@ -0,0 +1,64 @@ +from PIL import Image +import os, sys + +path = os.getcwd() +basefile = "dollymix" +ext = ".png" +size = int(input("size: ")) +reverse = size > 0 +size = abs(size) + + +base = Image.open(os.path.join(path,basefile+ext)) +amount = base.height // size + +states = [] + +for i in range(amount): + name = basefile+str(i+1) + filename = name+ext + states.append(name) + print(filename) + if(reverse): + base.crop((0,size*(amount-1-i),base.width,size*(amount-i))).save(os.path.join(path,filename)) + else: + base.crop((0,size*i,base.width,size*(i+1))).save(os.path.join(path,filename)) + +unshadedfile = os.path.join(path,basefile+"-unshaded"+ext) +if os.path.exists(unshadedfile): + base = Image.open(unshadedfile) + amount = base.height // size + + for i in range(amount): + name = basefile+str(i+1)+"-unshaded" + filename = name+ext + states.append(name) + print(filename) + if(reverse): + base.crop((0,size*(amount-1-i),base.width,size*(amount-i))).save(os.path.join(path,filename)) + else: + base.crop((0,size*i,base.width,size*(i+1))).save(os.path.join(path,filename)) + +if(len(states) == 0): + exit(1) + +metaheader = """{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "WWDP autogenerated", + "size": { + "x": 32, + "y": 32 + }, + "states": [ +""" +metaentry = """ {{ "name": "{0}" }}""" +metaterm = """ + ] +}""" + +states.append("icon") +with open(os.path.join(path,"meta.json"), 'w') as metajson: + metajson.write(metaheader) + metajson.write(",\n".join([metaentry.format(state) for state in states])) + metajson.write(metaterm) \ No newline at end of file diff --git a/Tools/dollymix/ztest.py b/Tools/dollymix/ztest.py new file mode 100644 index 0000000000..bbbefb9206 --- /dev/null +++ b/Tools/dollymix/ztest.py @@ -0,0 +1,36 @@ +from PIL import Image +import os, sys + +path = os.getcwd() +basefile = "dollymix" +ext = ".png" +size = int(input("size: ")) +offset = float(input("offset: ")) +repeat = int(input("repeat: ")) + +base = Image.open(os.path.join(path,basefile+ext)) + +reverse = size > 0 +size = abs(size) + +amount = base.height // size + +testfolder = os.path.join(path, "test") +if not os.path.exists(testfolder): + os.makedirs(testfolder) + +copies = 24 +scaleFactor = 5 +for rot in range(copies): + angle = rot*(360/copies) + print(f"{angle:03}.png") + out = Image.new("RGBA", (size*scaleFactor, size*scaleFactor), (0,0,0,0)) + for i in range(amount): + for r in range(repeat): + vertOffset = round(-(i-1+r/repeat)*scaleFactor*offset) + if(reverse): + out.alpha_composite(base.crop((0,size*(amount-1-i),base.width,size*(amount-i))).resize((size*scaleFactor, size*scaleFactor), 0).rotate(angle), (0,vertOffset)) + else: + out.alpha_composite(base.crop((0,size*i,base.width,size*(i+1))).resize((size*scaleFactor, size*scaleFactor), 0).rotate(angle), (0,vertOffset)) + + out.save(os.path.join(path, "test", f"{angle:03}.png"))