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-9uBzog_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-