From c72201e605f0cc5f6757b92dc8a99c1dd3d9d27d Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 5 Mar 2018 14:13:08 -0600 Subject: [PATCH] [MIRROR] Splits projectiles into different files for readability (#5800) * Splits projectiles into different files for readability * Update tgstation.dme * I love how the dme cleans itself up --- .../_ammunition.dm} | 0 .../{firing.dm => ammunition/_firing.dm} | 0 .../projectiles/ammunition/ammo_casings.dm | 314 ----- .../projectiles/ammunition/ballistic/lmg.dm | 23 + .../ammunition/ballistic/pistol.dm | 50 + .../ammunition/ballistic/revolver.dm | 23 + .../projectiles/ammunition/ballistic/rifle.dm | 28 + .../ammunition/ballistic/shotgun.dm | 139 ++ .../projectiles/ammunition/ballistic/smg.dm | 28 + .../ammunition/ballistic/sniper.dm | 19 + .../ammunition/caseless/_caseless.dm | 15 + .../{caseless.dm => caseless/foam.dm} | 178 +-- .../projectiles/ammunition/caseless/misc.dm | 22 + .../projectiles/ammunition/caseless/rocket.dm | 11 + code/modules/projectiles/ammunition/energy.dm | 258 ---- .../projectiles/ammunition/energy/_energy.dm | 10 + .../ammunition/energy/chameleon.dm | 15 + .../projectiles/ammunition/energy/ebow.dm | 12 + .../projectiles/ammunition/energy/gravity.dm | 36 + .../projectiles/ammunition/energy/laser.dm | 66 + .../projectiles/ammunition/energy/lmg.dm | 6 + .../projectiles/ammunition/energy/plasma.dm | 11 + .../{plasma.dm => energy/plasma_cit.dm} | 0 .../projectiles/ammunition/energy/portal.dm | 14 + .../projectiles/ammunition/energy/special.dm | 61 + .../projectiles/ammunition/energy/stun.dm | 24 + .../projectiles/ammunition/special/magic.dm | 42 + .../{special.dm => special/syringe.dm} | 172 +-- .../_box_magazine.dm} | 240 ++-- .../boxes_magazines/external/grenade.dm | 8 + .../boxes_magazines/external/lmg.dm | 22 + .../boxes_magazines/external/pistol.dm | 56 + .../boxes_magazines/external/rechargable.dm | 14 + .../boxes_magazines/external/rifle.dm | 21 + .../boxes_magazines/external/shotgun.dm | 36 + .../boxes_magazines/external/smg.dm | 76 ++ .../boxes_magazines/external/sniper.dm | 26 + .../boxes_magazines/external/toy.dm | 55 + .../boxes_magazines/external_mag.dm | 340 ----- .../boxes_magazines/internal/_cylinder.dm | 47 + .../boxes_magazines/internal/_internal.dm | 7 + .../boxes_magazines/internal/grenade.dm | 17 + .../boxes_magazines/internal/misc.dm | 11 + .../boxes_magazines/internal/revolver.dm | 22 + .../boxes_magazines/internal/rifle.dm | 15 + .../boxes_magazines/internal/shotgun.dm | 48 + .../boxes_magazines/internal/toy.dm | 7 + .../boxes_magazines/internal_mag.dm | 191 --- .../projectiles/guns/{ => energy}/mounted.dm | 52 +- .../guns/energy/{plasma.dm => plasma_cit.dm} | 0 .../projectiles/guns/{ => misc}/beam_rifle.dm | 1180 ++++++++--------- .../projectiles/guns/{ => misc}/chem_gun.dm | 92 +- .../guns/{ => misc}/grenade_launcher.dm | 104 +- .../projectiles/guns/{ => misc}/medbeam.dm | 266 ++-- .../guns/{ => misc}/syringe_gun.dm | 208 +-- .../modules/projectiles/projectile/bullets.dm | 419 ------ .../projectile/bullets/_incendiary.dm | 17 + .../projectile/bullets/dart_syringe.dm | 39 + .../projectile/bullets/dnainjector.dm | 24 + .../projectiles/projectile/bullets/grenade.dm | 12 + .../projectiles/projectile/bullets/lmg.dm | 44 + .../projectiles/projectile/bullets/pistol.dm | 36 + .../projectile/bullets/revolver.dm | 25 + .../projectiles/projectile/bullets/rifle.dm | 16 + .../projectiles/projectile/bullets/shotgun.dm | 95 ++ .../projectiles/projectile/bullets/smg.dm | 26 + .../projectiles/projectile/bullets/sniper.dm | 39 + .../projectiles/projectile/bullets/special.dm | 26 + code/modules/projectiles/projectile/energy.dm | 203 --- .../projectiles/projectile/energy/_energy.dm | 8 + .../projectile/energy/chameleon.dm | 3 + .../projectiles/projectile/energy/ebow.dm | 15 + .../projectiles/projectile/energy/misc.dm | 15 + .../projectile/energy/net_snare.dm | 98 ++ .../projectiles/projectile/energy/stun.dm | 28 + .../projectiles/projectile/energy/tesla.dm | 31 + .../projectile/reusable/_reusable.dm | 20 + .../{reusable.dm => reusable/foam_dart.dm} | 110 +- .../projectile/reusable/magspear.dm | 6 + .../modules/projectiles/projectile/special.dm | 617 --------- .../projectiles/projectile/special/curse.dm | 55 + .../projectiles/projectile/special/floral.dm | 25 + .../projectiles/projectile/special/gravity.dm | 90 ++ .../projectile/special/hallucination.dm | 230 ++++ .../projectiles/projectile/special/ion.dm | 20 + .../projectiles/projectile/special/meteor.dm | 19 + .../projectile/special/mindflayer.dm | 9 + .../projectile/special/neurotoxin.dm | 12 + .../projectiles/projectile/special/plasma.dm | 49 + .../projectiles/projectile/special/rocket.dm | 45 + .../projectile/special/temperature.dm | 19 + .../projectile/special/wormhole.dm | 25 + tgstation.dme | 105 +- 93 files changed, 3683 insertions(+), 3730 deletions(-) rename code/modules/projectiles/{ammunition.dm => ammunition/_ammunition.dm} (100%) rename code/modules/projectiles/{firing.dm => ammunition/_firing.dm} (100%) delete mode 100644 code/modules/projectiles/ammunition/ammo_casings.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/lmg.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/pistol.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/revolver.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/rifle.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/shotgun.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/smg.dm create mode 100644 code/modules/projectiles/ammunition/ballistic/sniper.dm create mode 100644 code/modules/projectiles/ammunition/caseless/_caseless.dm rename code/modules/projectiles/ammunition/{caseless.dm => caseless/foam.dm} (56%) create mode 100644 code/modules/projectiles/ammunition/caseless/misc.dm create mode 100644 code/modules/projectiles/ammunition/caseless/rocket.dm delete mode 100644 code/modules/projectiles/ammunition/energy.dm create mode 100644 code/modules/projectiles/ammunition/energy/_energy.dm create mode 100644 code/modules/projectiles/ammunition/energy/chameleon.dm create mode 100644 code/modules/projectiles/ammunition/energy/ebow.dm create mode 100644 code/modules/projectiles/ammunition/energy/gravity.dm create mode 100644 code/modules/projectiles/ammunition/energy/laser.dm create mode 100644 code/modules/projectiles/ammunition/energy/lmg.dm create mode 100644 code/modules/projectiles/ammunition/energy/plasma.dm rename code/modules/projectiles/ammunition/{plasma.dm => energy/plasma_cit.dm} (100%) create mode 100644 code/modules/projectiles/ammunition/energy/portal.dm create mode 100644 code/modules/projectiles/ammunition/energy/special.dm create mode 100644 code/modules/projectiles/ammunition/energy/stun.dm create mode 100644 code/modules/projectiles/ammunition/special/magic.dm rename code/modules/projectiles/ammunition/{special.dm => special/syringe.dm} (53%) rename code/modules/projectiles/{box_magazine.dm => boxes_magazines/_box_magazine.dm} (96%) create mode 100644 code/modules/projectiles/boxes_magazines/external/grenade.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/lmg.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/pistol.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/rechargable.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/rifle.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/shotgun.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/smg.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/sniper.dm create mode 100644 code/modules/projectiles/boxes_magazines/external/toy.dm delete mode 100644 code/modules/projectiles/boxes_magazines/external_mag.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/_cylinder.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/_internal.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/grenade.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/misc.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/revolver.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/rifle.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/shotgun.dm create mode 100644 code/modules/projectiles/boxes_magazines/internal/toy.dm delete mode 100644 code/modules/projectiles/boxes_magazines/internal_mag.dm rename code/modules/projectiles/guns/{ => energy}/mounted.dm (96%) rename code/modules/projectiles/guns/energy/{plasma.dm => plasma_cit.dm} (100%) rename code/modules/projectiles/guns/{ => misc}/beam_rifle.dm (97%) rename code/modules/projectiles/guns/{ => misc}/chem_gun.dm (95%) rename code/modules/projectiles/guns/{ => misc}/grenade_launcher.dm (97%) rename code/modules/projectiles/guns/{ => misc}/medbeam.dm (96%) rename code/modules/projectiles/guns/{ => misc}/syringe_gun.dm (96%) create mode 100644 code/modules/projectiles/projectile/bullets/_incendiary.dm create mode 100644 code/modules/projectiles/projectile/bullets/dart_syringe.dm create mode 100644 code/modules/projectiles/projectile/bullets/dnainjector.dm create mode 100644 code/modules/projectiles/projectile/bullets/grenade.dm create mode 100644 code/modules/projectiles/projectile/bullets/lmg.dm create mode 100644 code/modules/projectiles/projectile/bullets/pistol.dm create mode 100644 code/modules/projectiles/projectile/bullets/revolver.dm create mode 100644 code/modules/projectiles/projectile/bullets/rifle.dm create mode 100644 code/modules/projectiles/projectile/bullets/shotgun.dm create mode 100644 code/modules/projectiles/projectile/bullets/smg.dm create mode 100644 code/modules/projectiles/projectile/bullets/sniper.dm create mode 100644 code/modules/projectiles/projectile/bullets/special.dm delete mode 100644 code/modules/projectiles/projectile/energy.dm create mode 100644 code/modules/projectiles/projectile/energy/_energy.dm create mode 100644 code/modules/projectiles/projectile/energy/chameleon.dm create mode 100644 code/modules/projectiles/projectile/energy/ebow.dm create mode 100644 code/modules/projectiles/projectile/energy/misc.dm create mode 100644 code/modules/projectiles/projectile/energy/net_snare.dm create mode 100644 code/modules/projectiles/projectile/energy/stun.dm create mode 100644 code/modules/projectiles/projectile/energy/tesla.dm create mode 100644 code/modules/projectiles/projectile/reusable/_reusable.dm rename code/modules/projectiles/projectile/{reusable.dm => reusable/foam_dart.dm} (59%) create mode 100644 code/modules/projectiles/projectile/reusable/magspear.dm delete mode 100644 code/modules/projectiles/projectile/special.dm create mode 100644 code/modules/projectiles/projectile/special/curse.dm create mode 100644 code/modules/projectiles/projectile/special/floral.dm create mode 100644 code/modules/projectiles/projectile/special/gravity.dm create mode 100644 code/modules/projectiles/projectile/special/hallucination.dm create mode 100644 code/modules/projectiles/projectile/special/ion.dm create mode 100644 code/modules/projectiles/projectile/special/meteor.dm create mode 100644 code/modules/projectiles/projectile/special/mindflayer.dm create mode 100644 code/modules/projectiles/projectile/special/neurotoxin.dm create mode 100644 code/modules/projectiles/projectile/special/plasma.dm create mode 100644 code/modules/projectiles/projectile/special/rocket.dm create mode 100644 code/modules/projectiles/projectile/special/temperature.dm create mode 100644 code/modules/projectiles/projectile/special/wormhole.dm diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm similarity index 100% rename from code/modules/projectiles/ammunition.dm rename to code/modules/projectiles/ammunition/_ammunition.dm diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/ammunition/_firing.dm similarity index 100% rename from code/modules/projectiles/firing.dm rename to code/modules/projectiles/ammunition/_firing.dm diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm deleted file mode 100644 index df0fd7278e..0000000000 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ /dev/null @@ -1,314 +0,0 @@ -// .357 (Syndie Revolver) - -/obj/item/ammo_casing/a357 - name = ".357 bullet casing" - desc = "A .357 bullet casing." - caliber = "357" - projectile_type = /obj/item/projectile/bullet/a357 - -// 7.62 (Nagant Rifle) - -/obj/item/ammo_casing/a762 - name = "7.62 bullet casing" - desc = "A 7.62 bullet casing." - icon_state = "762-casing" - caliber = "a762" - projectile_type = /obj/item/projectile/bullet/a762 - -/obj/item/ammo_casing/a762/enchanted - projectile_type = /obj/item/projectile/bullet/a762_enchanted - -// 7.62x38mmR (Nagant Revolver) - -/obj/item/ammo_casing/n762 - name = "7.62x38mmR bullet casing" - desc = "A 7.62x38mmR bullet casing." - caliber = "n762" - projectile_type = /obj/item/projectile/bullet/n762 - -// .50AE (Desert Eagle) - -/obj/item/ammo_casing/a50AE - name = ".50AE bullet casing" - desc = "A .50AE bullet casing." - caliber = ".50" - projectile_type = /obj/item/projectile/bullet/a50AE - -// .38 (Detective's Gun) - -/obj/item/ammo_casing/c38 - name = ".38 bullet casing" - desc = "A .38 bullet casing." - caliber = "38" - projectile_type = /obj/item/projectile/bullet/c38 - -// 10mm (Stechkin) - -/obj/item/ammo_casing/c10mm - name = ".10mm bullet casing" - desc = "A 10mm bullet casing." - caliber = "10mm" - projectile_type = /obj/item/projectile/bullet/c10mm - -/obj/item/ammo_casing/c10mm/ap - name = ".10mm armor-piercing bullet casing" - desc = "A 10mm armor-piercing bullet casing." - projectile_type = /obj/item/projectile/bullet/c10mm_ap - -/obj/item/ammo_casing/c10mm/hp - name = ".10mm hollow-point bullet casing" - desc = "A 10mm hollow-point bullet casing." - projectile_type = /obj/item/projectile/bullet/c10mm_hp - -/obj/item/ammo_casing/c10mm/fire - name = ".10mm incendiary bullet casing" - desc = "A 10mm incendiary bullet casing." - projectile_type = /obj/item/projectile/bullet/incendiary/c10mm - -// 9mm (Stechkin APS) - -/obj/item/ammo_casing/c9mm - name = "9mm bullet casing" - desc = "A 9mm bullet casing." - caliber = "9mm" - projectile_type = /obj/item/projectile/bullet/c9mm - -/obj/item/ammo_casing/c9mm/ap - name = "9mm armor-piercing bullet casing" - desc = "A 9mm armor-piercing bullet casing." - projectile_type =/obj/item/projectile/bullet/c9mm_ap - -/obj/item/ammo_casing/c9mm/inc - name = "9mm incendiary bullet casing" - desc = "A 9mm incendiary bullet casing." - projectile_type = /obj/item/projectile/bullet/incendiary/c9mm - -// 4.6x30mm (Autorifles) - -/obj/item/ammo_casing/c46x30mm - name = "4.6x30mm bullet casing" - desc = "A 4.6x30mm bullet casing." - caliber = "4.6x30mm" - projectile_type = /obj/item/projectile/bullet/c46x30mm - -/obj/item/ammo_casing/c46x30mm/ap - name = "4.6x30mm armor-piercing bullet casing" - desc = "A 4.6x30mm armor-piercing bullet casing." - projectile_type = /obj/item/projectile/bullet/c46x30mm_ap - -/obj/item/ammo_casing/c46x30mm/inc - name = "4.6x30mm incendiary bullet casing" - desc = "A 4.6x30mm incendiary bullet casing." - projectile_type = /obj/item/projectile/bullet/incendiary/c46x30mm - -// .45 (M1911 + C20r) - -/obj/item/ammo_casing/c45 - name = ".45 bullet casing" - desc = "A .45 bullet casing." - caliber = ".45" - projectile_type = /obj/item/projectile/bullet/c45 - -/obj/item/ammo_casing/c45/nostamina - projectile_type = /obj/item/projectile/bullet/c45_nostamina - -// 5.56mm (M-90gl Carbine) - -/obj/item/ammo_casing/a556 - name = "5.56mm bullet casing" - desc = "A 5.56mm bullet casing." - caliber = "a556" - projectile_type = /obj/item/projectile/bullet/a556 - -// 40mm (Grenade Launcher) - -/obj/item/ammo_casing/a40mm - name = "40mm HE shell" - desc = "A cased high explosive grenade that can only be activated once fired out of a grenade launcher." - caliber = "40mm" - icon_state = "40mmHE" - projectile_type = /obj/item/projectile/bullet/a40mm - -// .50 (Sniper) - -/obj/item/ammo_casing/p50 - name = ".50 bullet casing" - desc = "A .50 bullet casing." - caliber = ".50" - projectile_type = /obj/item/projectile/bullet/p50 - icon_state = ".50" - -/obj/item/ammo_casing/p50/soporific - name = ".50 soporific bullet casing" - desc = "A .50 bullet casing, specialised in sending the target to sleep, instead of hell." - projectile_type = /obj/item/projectile/bullet/p50/soporific - icon_state = "sleeper" - -/obj/item/ammo_casing/p50/penetrator - name = ".50 penetrator round bullet casing" - desc = "A .50 caliber penetrator round casing." - projectile_type = /obj/item/projectile/bullet/p50/penetrator - -// 1.95x129mm (SAW) - -/obj/item/ammo_casing/mm195x129 - name = "1.95x129mm bullet casing" - desc = "A 1.95x129mm bullet casing." - icon_state = "762-casing" - caliber = "mm195129" - projectile_type = /obj/item/projectile/bullet/mm195x129 - -/obj/item/ammo_casing/mm195x129/ap - name = "1.95x129mm armor-piercing bullet casing" - desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." - projectile_type = /obj/item/projectile/bullet/mm195x129_ap - -/obj/item/ammo_casing/mm195x129/hollow - name = "1.95x129mm hollow-point bullet casing" - desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets." - projectile_type = /obj/item/projectile/bullet/mm195x129_hp - -/obj/item/ammo_casing/mm195x129/incen - name = "1.95x129mm incendiary bullet casing" - desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames." - projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129 - -// Shotgun - -/obj/item/ammo_casing/shotgun - name = "shotgun slug" - desc = "A 12 gauge lead slug." - icon_state = "blshell" - caliber = "shotgun" - projectile_type = /obj/item/projectile/bullet/shotgun_slug - materials = list(MAT_METAL=4000) - -/obj/item/ammo_casing/shotgun/beanbag - name = "beanbag slug" - desc = "A weak beanbag slug for riot control." - icon_state = "bshell" - projectile_type = /obj/item/projectile/bullet/shotgun_beanbag - materials = list(MAT_METAL=250) - -/obj/item/ammo_casing/shotgun/incendiary - name = "incendiary slug" - desc = "An incendiary-coated shotgun slug." - icon_state = "ishell" - projectile_type = /obj/item/projectile/bullet/incendiary/shotgun - -/obj/item/ammo_casing/shotgun/dragonsbreath - name = "dragonsbreath shell" - desc = "A shotgun shell which fires a spread of incendiary pellets." - icon_state = "ishell2" - projectile_type = /obj/item/projectile/bullet/incendiary/shotgun/dragonsbreath - pellets = 4 - variance = 35 - -/obj/item/ammo_casing/shotgun/stunslug - name = "taser slug" - desc = "A stunning taser slug." - icon_state = "stunshell" - projectile_type = /obj/item/projectile/bullet/shotgun_stunslug - materials = list(MAT_METAL=250) - -/obj/item/ammo_casing/shotgun/meteorslug - name = "meteorslug shell" - desc = "A shotgun shell rigged with CMC technology, which launches a massive slug when fired." - icon_state = "mshell" - projectile_type = /obj/item/projectile/bullet/shotgun_meteorslug - -/obj/item/ammo_casing/shotgun/pulseslug - name = "pulse slug" - desc = "A delicate device which can be loaded into a shotgun. The primer acts as a button which triggers the gain medium and fires a powerful \ - energy blast. While the heat and power drain limit it to one use, it can still allow an operator to engage targets that ballistic ammunition \ - would have difficulty with." - icon_state = "pshell" - projectile_type = /obj/item/projectile/beam/pulse/shotgun - -/obj/item/ammo_casing/shotgun/frag12 - name = "FRAG-12 slug" - desc = "A high explosive breaching round for a 12 gauge shotgun." - icon_state = "heshell" - projectile_type = /obj/item/projectile/bullet/shotgun_frag12 - -/obj/item/ammo_casing/shotgun/buckshot - name = "buckshot shell" - desc = "A 12 gauge buckshot shell." - icon_state = "gshell" - projectile_type = /obj/item/projectile/bullet/pellet/shotgun_buckshot - pellets = 6 - variance = 25 - -/obj/item/ammo_casing/shotgun/rubbershot - name = "rubber shot" - desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance." - icon_state = "bshell" - projectile_type = /obj/item/projectile/bullet/pellet/shotgun_rubbershot - pellets = 6 - variance = 25 - materials = list(MAT_METAL=4000) - -/obj/item/ammo_casing/shotgun/improvised - name = "improvised shell" - desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards." - icon_state = "improvshell" - projectile_type = /obj/item/projectile/bullet/pellet/shotgun_improvised - materials = list(MAT_METAL=250) - pellets = 10 - variance = 25 - -/obj/item/ammo_casing/shotgun/ion - name = "ion shell" - desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \ - The unique properties of the crystal split the pulse into a spread of individually weaker bolts." - icon_state = "ionshell" - projectile_type = /obj/item/projectile/ion/weak - pellets = 4 - variance = 35 - -/obj/item/ammo_casing/shotgun/laserslug - name = "laser slug" - desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package." - icon_state = "lshell" - projectile_type = /obj/item/projectile/beam/laser - -/obj/item/ammo_casing/shotgun/techshell - name = "unloaded technological shell" - desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." - icon_state = "cshell" - projectile_type = null - -/obj/item/ammo_casing/shotgun/dart - name = "shotgun dart" - desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical." - icon_state = "cshell" - projectile_type = /obj/item/projectile/bullet/dart - var/reagent_amount = 30 - var/reagent_react = TRUE - -/obj/item/ammo_casing/shotgun/dart/noreact - name = "cryostasis shotgun dart" - desc = "A dart for use in shotguns, using similar technolgoy as cryostatis beakers to keep internal reagents from reacting. Can be injected with up to 10 units of any chemical." - icon_state = "cnrshell" - reagent_amount = 10 - reagent_react = FALSE - -/obj/item/ammo_casing/shotgun/dart/Initialize() - . = ..() - container_type |= OPENCONTAINER - create_reagents(reagent_amount) - reagents.set_reacting(reagent_react) - -/obj/item/ammo_casing/shotgun/dart/attackby() - return - -/obj/item/ammo_casing/shotgun/dart/bioterror - desc = "A shotgun dart filled with deadly toxins." - -/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize() - . = ..() - reagents.add_reagent("neurotoxin", 6) - reagents.add_reagent("spore", 6) - reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT - reagents.add_reagent("coniine", 6) - reagents.add_reagent("sodium_thiopental", 6) diff --git a/code/modules/projectiles/ammunition/ballistic/lmg.dm b/code/modules/projectiles/ammunition/ballistic/lmg.dm new file mode 100644 index 0000000000..1ce2e0065e --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/lmg.dm @@ -0,0 +1,23 @@ +// 1.95x129mm (SAW) + +/obj/item/ammo_casing/mm195x129 + name = "1.95x129mm bullet casing" + desc = "A 1.95x129mm bullet casing." + icon_state = "762-casing" + caliber = "mm195129" + projectile_type = /obj/item/projectile/bullet/mm195x129 + +/obj/item/ammo_casing/mm195x129/ap + name = "1.95x129mm armor-piercing bullet casing" + desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." + projectile_type = /obj/item/projectile/bullet/mm195x129_ap + +/obj/item/ammo_casing/mm195x129/hollow + name = "1.95x129mm hollow-point bullet casing" + desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets." + projectile_type = /obj/item/projectile/bullet/mm195x129_hp + +/obj/item/ammo_casing/mm195x129/incen + name = "1.95x129mm incendiary bullet casing" + desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames." + projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129 diff --git a/code/modules/projectiles/ammunition/ballistic/pistol.dm b/code/modules/projectiles/ammunition/ballistic/pistol.dm new file mode 100644 index 0000000000..02134e95e1 --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/pistol.dm @@ -0,0 +1,50 @@ +// 10mm (Stechkin) + +/obj/item/ammo_casing/c10mm + name = ".10mm bullet casing" + desc = "A 10mm bullet casing." + caliber = "10mm" + projectile_type = /obj/item/projectile/bullet/c10mm + +/obj/item/ammo_casing/c10mm/ap + name = ".10mm armor-piercing bullet casing" + desc = "A 10mm armor-piercing bullet casing." + projectile_type = /obj/item/projectile/bullet/c10mm_ap + +/obj/item/ammo_casing/c10mm/hp + name = ".10mm hollow-point bullet casing" + desc = "A 10mm hollow-point bullet casing." + projectile_type = /obj/item/projectile/bullet/c10mm_hp + +/obj/item/ammo_casing/c10mm/fire + name = ".10mm incendiary bullet casing" + desc = "A 10mm incendiary bullet casing." + projectile_type = /obj/item/projectile/bullet/incendiary/c10mm + +// 9mm (Stechkin APS) + +/obj/item/ammo_casing/c9mm + name = "9mm bullet casing" + desc = "A 9mm bullet casing." + caliber = "9mm" + projectile_type = /obj/item/projectile/bullet/c9mm + +/obj/item/ammo_casing/c9mm/ap + name = "9mm armor-piercing bullet casing" + desc = "A 9mm armor-piercing bullet casing." + projectile_type =/obj/item/projectile/bullet/c9mm_ap + +/obj/item/ammo_casing/c9mm/inc + name = "9mm incendiary bullet casing" + desc = "A 9mm incendiary bullet casing." + projectile_type = /obj/item/projectile/bullet/incendiary/c9mm + + +// .50AE (Desert Eagle) + +/obj/item/ammo_casing/a50AE + name = ".50AE bullet casing" + desc = "A .50AE bullet casing." + caliber = ".50" + projectile_type = /obj/item/projectile/bullet/a50AE + diff --git a/code/modules/projectiles/ammunition/ballistic/revolver.dm b/code/modules/projectiles/ammunition/ballistic/revolver.dm new file mode 100644 index 0000000000..52a72e0ff7 --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/revolver.dm @@ -0,0 +1,23 @@ +// .357 (Syndie Revolver) + +/obj/item/ammo_casing/a357 + name = ".357 bullet casing" + desc = "A .357 bullet casing." + caliber = "357" + projectile_type = /obj/item/projectile/bullet/a357 + +// 7.62x38mmR (Nagant Revolver) + +/obj/item/ammo_casing/n762 + name = "7.62x38mmR bullet casing" + desc = "A 7.62x38mmR bullet casing." + caliber = "n762" + projectile_type = /obj/item/projectile/bullet/n762 + +// .38 (Detective's Gun) + +/obj/item/ammo_casing/c38 + name = ".38 bullet casing" + desc = "A .38 bullet casing." + caliber = "38" + projectile_type = /obj/item/projectile/bullet/c38 diff --git a/code/modules/projectiles/ammunition/ballistic/rifle.dm b/code/modules/projectiles/ammunition/ballistic/rifle.dm new file mode 100644 index 0000000000..a35cfcba1c --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/rifle.dm @@ -0,0 +1,28 @@ +// 7.62 (Nagant Rifle) + +/obj/item/ammo_casing/a762 + name = "7.62 bullet casing" + desc = "A 7.62 bullet casing." + icon_state = "762-casing" + caliber = "a762" + projectile_type = /obj/item/projectile/bullet/a762 + +/obj/item/ammo_casing/a762/enchanted + projectile_type = /obj/item/projectile/bullet/a762_enchanted + +// 5.56mm (M-90gl Carbine) + +/obj/item/ammo_casing/a556 + name = "5.56mm bullet casing" + desc = "A 5.56mm bullet casing." + caliber = "a556" + projectile_type = /obj/item/projectile/bullet/a556 + +// 40mm (Grenade Launcher) + +/obj/item/ammo_casing/a40mm + name = "40mm HE shell" + desc = "A cased high explosive grenade that can only be activated once fired out of a grenade launcher." + caliber = "40mm" + icon_state = "40mmHE" + projectile_type = /obj/item/projectile/bullet/a40mm diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm new file mode 100644 index 0000000000..b700d092d7 --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -0,0 +1,139 @@ +// Shotgun + +/obj/item/ammo_casing/shotgun + name = "shotgun slug" + desc = "A 12 gauge lead slug." + icon_state = "blshell" + caliber = "shotgun" + projectile_type = /obj/item/projectile/bullet/shotgun_slug + materials = list(MAT_METAL=4000) + +/obj/item/ammo_casing/shotgun/beanbag + name = "beanbag slug" + desc = "A weak beanbag slug for riot control." + icon_state = "bshell" + projectile_type = /obj/item/projectile/bullet/shotgun_beanbag + materials = list(MAT_METAL=250) + +/obj/item/ammo_casing/shotgun/incendiary + name = "incendiary slug" + desc = "An incendiary-coated shotgun slug." + icon_state = "ishell" + projectile_type = /obj/item/projectile/bullet/incendiary/shotgun + +/obj/item/ammo_casing/shotgun/dragonsbreath + name = "dragonsbreath shell" + desc = "A shotgun shell which fires a spread of incendiary pellets." + icon_state = "ishell2" + projectile_type = /obj/item/projectile/bullet/incendiary/shotgun/dragonsbreath + pellets = 4 + variance = 35 + +/obj/item/ammo_casing/shotgun/stunslug + name = "taser slug" + desc = "A stunning taser slug." + icon_state = "stunshell" + projectile_type = /obj/item/projectile/bullet/shotgun_stunslug + materials = list(MAT_METAL=250) + +/obj/item/ammo_casing/shotgun/meteorslug + name = "meteorslug shell" + desc = "A shotgun shell rigged with CMC technology, which launches a massive slug when fired." + icon_state = "mshell" + projectile_type = /obj/item/projectile/bullet/shotgun_meteorslug + +/obj/item/ammo_casing/shotgun/pulseslug + name = "pulse slug" + desc = "A delicate device which can be loaded into a shotgun. The primer acts as a button which triggers the gain medium and fires a powerful \ + energy blast. While the heat and power drain limit it to one use, it can still allow an operator to engage targets that ballistic ammunition \ + would have difficulty with." + icon_state = "pshell" + projectile_type = /obj/item/projectile/beam/pulse/shotgun + +/obj/item/ammo_casing/shotgun/frag12 + name = "FRAG-12 slug" + desc = "A high explosive breaching round for a 12 gauge shotgun." + icon_state = "heshell" + projectile_type = /obj/item/projectile/bullet/shotgun_frag12 + +/obj/item/ammo_casing/shotgun/buckshot + name = "buckshot shell" + desc = "A 12 gauge buckshot shell." + icon_state = "gshell" + projectile_type = /obj/item/projectile/bullet/pellet/shotgun_buckshot + pellets = 6 + variance = 25 + +/obj/item/ammo_casing/shotgun/rubbershot + name = "rubber shot" + desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance." + icon_state = "bshell" + projectile_type = /obj/item/projectile/bullet/pellet/shotgun_rubbershot + pellets = 6 + variance = 25 + materials = list(MAT_METAL=4000) + +/obj/item/ammo_casing/shotgun/improvised + name = "improvised shell" + desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards." + icon_state = "improvshell" + projectile_type = /obj/item/projectile/bullet/pellet/shotgun_improvised + materials = list(MAT_METAL=250) + pellets = 10 + variance = 25 + +/obj/item/ammo_casing/shotgun/ion + name = "ion shell" + desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \ + The unique properties of the crystal split the pulse into a spread of individually weaker bolts." + icon_state = "ionshell" + projectile_type = /obj/item/projectile/ion/weak + pellets = 4 + variance = 35 + +/obj/item/ammo_casing/shotgun/laserslug + name = "laser slug" + desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package." + icon_state = "lshell" + projectile_type = /obj/item/projectile/beam/laser + +/obj/item/ammo_casing/shotgun/techshell + name = "unloaded technological shell" + desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." + icon_state = "cshell" + projectile_type = null + +/obj/item/ammo_casing/shotgun/dart + name = "shotgun dart" + desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical." + icon_state = "cshell" + projectile_type = /obj/item/projectile/bullet/dart + var/reagent_amount = 30 + var/reagent_react = TRUE + +/obj/item/ammo_casing/shotgun/dart/noreact + name = "cryostasis shotgun dart" + desc = "A dart for use in shotguns, using similar technolgoy as cryostatis beakers to keep internal reagents from reacting. Can be injected with up to 10 units of any chemical." + icon_state = "cnrshell" + reagent_amount = 10 + reagent_react = FALSE + +/obj/item/ammo_casing/shotgun/dart/Initialize() + . = ..() + container_type |= OPENCONTAINER + create_reagents(reagent_amount) + reagents.set_reacting(reagent_react) + +/obj/item/ammo_casing/shotgun/dart/attackby() + return + +/obj/item/ammo_casing/shotgun/dart/bioterror + desc = "A shotgun dart filled with deadly toxins." + +/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize() + . = ..() + reagents.add_reagent("neurotoxin", 6) + reagents.add_reagent("spore", 6) + reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT + reagents.add_reagent("coniine", 6) + reagents.add_reagent("sodium_thiopental", 6) diff --git a/code/modules/projectiles/ammunition/ballistic/smg.dm b/code/modules/projectiles/ammunition/ballistic/smg.dm new file mode 100644 index 0000000000..3be419c933 --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/smg.dm @@ -0,0 +1,28 @@ +// 4.6x30mm (Autorifles) + +/obj/item/ammo_casing/c46x30mm + name = "4.6x30mm bullet casing" + desc = "A 4.6x30mm bullet casing." + caliber = "4.6x30mm" + projectile_type = /obj/item/projectile/bullet/c46x30mm + +/obj/item/ammo_casing/c46x30mm/ap + name = "4.6x30mm armor-piercing bullet casing" + desc = "A 4.6x30mm armor-piercing bullet casing." + projectile_type = /obj/item/projectile/bullet/c46x30mm_ap + +/obj/item/ammo_casing/c46x30mm/inc + name = "4.6x30mm incendiary bullet casing" + desc = "A 4.6x30mm incendiary bullet casing." + projectile_type = /obj/item/projectile/bullet/incendiary/c46x30mm + +// .45 (M1911 + C20r) + +/obj/item/ammo_casing/c45 + name = ".45 bullet casing" + desc = "A .45 bullet casing." + caliber = ".45" + projectile_type = /obj/item/projectile/bullet/c45 + +/obj/item/ammo_casing/c45/nostamina + projectile_type = /obj/item/projectile/bullet/c45_nostamina diff --git a/code/modules/projectiles/ammunition/ballistic/sniper.dm b/code/modules/projectiles/ammunition/ballistic/sniper.dm new file mode 100644 index 0000000000..5906fcfaba --- /dev/null +++ b/code/modules/projectiles/ammunition/ballistic/sniper.dm @@ -0,0 +1,19 @@ +// .50 (Sniper) + +/obj/item/ammo_casing/p50 + name = ".50 bullet casing" + desc = "A .50 bullet casing." + caliber = ".50" + projectile_type = /obj/item/projectile/bullet/p50 + icon_state = ".50" + +/obj/item/ammo_casing/p50/soporific + name = ".50 soporific bullet casing" + desc = "A .50 bullet casing, specialised in sending the target to sleep, instead of hell." + projectile_type = /obj/item/projectile/bullet/p50/soporific + icon_state = "sleeper" + +/obj/item/ammo_casing/p50/penetrator + name = ".50 penetrator round bullet casing" + desc = "A .50 caliber penetrator round casing." + projectile_type = /obj/item/projectile/bullet/p50/penetrator diff --git a/code/modules/projectiles/ammunition/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm new file mode 100644 index 0000000000..154d269cd9 --- /dev/null +++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm @@ -0,0 +1,15 @@ +/obj/item/ammo_casing/caseless + desc = "A caseless bullet casing." + firing_effect_type = null + heavy_metal = FALSE + +/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) + if (..()) //successfully firing + moveToNullspace() + return 1 + else + return 0 + +/obj/item/ammo_casing/caseless/update_icon() + ..() + icon_state = "[initial(icon_state)]" diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless/foam.dm similarity index 56% rename from code/modules/projectiles/ammunition/caseless.dm rename to code/modules/projectiles/ammunition/caseless/foam.dm index b3439c86b2..fdf685e001 100644 --- a/code/modules/projectiles/ammunition/caseless.dm +++ b/code/modules/projectiles/ammunition/caseless/foam.dm @@ -1,117 +1,61 @@ - -// Caseless Ammunition - -/obj/item/ammo_casing/caseless - desc = "A caseless bullet casing." - firing_effect_type = null - heavy_metal = FALSE - -/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) - if (..()) //successfully firing - moveToNullspace() - return 1 - else - return 0 - -/obj/item/ammo_casing/caseless/update_icon() - ..() - icon_state = "[initial(icon_state)]" - -/obj/item/ammo_casing/caseless/a75 - desc = "A .75 bullet casing." - caliber = "75" - icon_state = "s-casing-live" - projectile_type = /obj/item/projectile/bullet/gyro - -/obj/item/ammo_casing/caseless/a84mm - desc = "An 84mm anti-armour rocket." - caliber = "84mm" - icon_state = "s-casing-live" - projectile_type = /obj/item/projectile/bullet/a84mm - -/obj/item/ammo_casing/caseless/magspear - name = "magnetic spear" - desc = "A reusable spear that is typically loaded into kinetic spearguns." - projectile_type = /obj/item/projectile/bullet/reusable/magspear - caliber = "speargun" - icon_state = "magspear" - throwforce = 15 //still deadly when thrown - throw_speed = 3 - - -/obj/item/ammo_casing/caseless/laser - name = "laser casing" - desc = "You shouldn't be seeing this." - caliber = "laser" - icon_state = "s-casing-live" - projectile_type = /obj/item/projectile/beam - fire_sound = 'sound/weapons/laser.ogg' - firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy - -/obj/item/ammo_casing/caseless/laser/gatling - projectile_type = /obj/item/projectile/beam/weak - variance = 0.8 - click_cooldown_override = 1 - - -/obj/item/ammo_casing/caseless/foam_dart - name = "foam dart" - desc = "It's nerf or nothing! Ages 8 and up." - projectile_type = /obj/item/projectile/bullet/reusable/foam_dart - caliber = "foam_force" - icon = 'icons/obj/guns/toy.dmi' - icon_state = "foamdart" - var/modified = 0 - -/obj/item/ammo_casing/caseless/foam_dart/update_icon() - ..() - if (modified) - icon_state = "foamdart_empty" - desc = "It's nerf or nothing! ... Although, this one doesn't look too safe." - if(BB) - BB.icon_state = "foamdart_empty" - else - icon_state = initial(icon_state) - desc = "It's nerf or nothing! Ages 8 and up." - if(BB) - BB.icon_state = initial(BB.icon_state) - - -/obj/item/ammo_casing/caseless/foam_dart/attackby(obj/item/A, mob/user, params) - var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB - if (istype(A, /obj/item/screwdriver) && !modified) - modified = 1 - FD.modified = 1 - FD.damage_type = BRUTE - to_chat(user, "You pop the safety cap off [src].") - update_icon() - else if (istype(A, /obj/item/pen)) - if(modified) - if(!FD.pen) - if(!user.transferItemToLoc(A, FD)) - return - FD.pen = A - FD.damage = 5 - FD.nodamage = 0 - to_chat(user, "You insert [A] into [src].") - else - to_chat(user, "There's already something in [src].") - else - to_chat(user, "The safety cap prevents you from inserting [A] into [src].") - else - return ..() - -/obj/item/ammo_casing/caseless/foam_dart/attack_self(mob/living/user) - var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB - if(FD.pen) - FD.damage = initial(FD.damage) - FD.nodamage = initial(FD.nodamage) - user.put_in_hands(FD.pen) - to_chat(user, "You remove [FD.pen] from [src].") - FD.pen = null - -/obj/item/ammo_casing/caseless/foam_dart/riot - name = "riot foam dart" - desc = "Whose smart idea was it to use toys as crowd control? Ages 18 and up." - projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/riot - icon_state = "foamdart_riot" +/obj/item/ammo_casing/caseless/foam_dart + name = "foam dart" + desc = "It's nerf or nothing! Ages 8 and up." + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart + caliber = "foam_force" + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foamdart" + var/modified = 0 + +/obj/item/ammo_casing/caseless/foam_dart/update_icon() + ..() + if (modified) + icon_state = "foamdart_empty" + desc = "It's nerf or nothing! ... Although, this one doesn't look too safe." + if(BB) + BB.icon_state = "foamdart_empty" + else + icon_state = initial(icon_state) + desc = "It's nerf or nothing! Ages 8 and up." + if(BB) + BB.icon_state = initial(BB.icon_state) + + +/obj/item/ammo_casing/caseless/foam_dart/attackby(obj/item/A, mob/user, params) + var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB + if (istype(A, /obj/item/screwdriver) && !modified) + modified = 1 + FD.modified = 1 + FD.damage_type = BRUTE + to_chat(user, "You pop the safety cap off [src].") + update_icon() + else if (istype(A, /obj/item/pen)) + if(modified) + if(!FD.pen) + if(!user.transferItemToLoc(A, FD)) + return + FD.pen = A + FD.damage = 5 + FD.nodamage = 0 + to_chat(user, "You insert [A] into [src].") + else + to_chat(user, "There's already something in [src].") + else + to_chat(user, "The safety cap prevents you from inserting [A] into [src].") + else + return ..() + +/obj/item/ammo_casing/caseless/foam_dart/attack_self(mob/living/user) + var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB + if(FD.pen) + FD.damage = initial(FD.damage) + FD.nodamage = initial(FD.nodamage) + user.put_in_hands(FD.pen) + to_chat(user, "You remove [FD.pen] from [src].") + FD.pen = null + +/obj/item/ammo_casing/caseless/foam_dart/riot + name = "riot foam dart" + desc = "Whose smart idea was it to use toys as crowd control? Ages 18 and up." + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/riot + icon_state = "foamdart_riot" diff --git a/code/modules/projectiles/ammunition/caseless/misc.dm b/code/modules/projectiles/ammunition/caseless/misc.dm new file mode 100644 index 0000000000..fcb491f071 --- /dev/null +++ b/code/modules/projectiles/ammunition/caseless/misc.dm @@ -0,0 +1,22 @@ +/obj/item/ammo_casing/caseless/magspear + name = "magnetic spear" + desc = "A reusable spear that is typically loaded into kinetic spearguns." + projectile_type = /obj/item/projectile/bullet/reusable/magspear + caliber = "speargun" + icon_state = "magspear" + throwforce = 15 //still deadly when thrown + throw_speed = 3 + +/obj/item/ammo_casing/caseless/laser + name = "laser casing" + desc = "You shouldn't be seeing this." + caliber = "laser" + icon_state = "s-casing-live" + projectile_type = /obj/item/projectile/beam + fire_sound = 'sound/weapons/laser.ogg' + firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy + +/obj/item/ammo_casing/caseless/laser/gatling + projectile_type = /obj/item/projectile/beam/weak + variance = 0.8 + click_cooldown_override = 1 diff --git a/code/modules/projectiles/ammunition/caseless/rocket.dm b/code/modules/projectiles/ammunition/caseless/rocket.dm new file mode 100644 index 0000000000..0b74f6ff8c --- /dev/null +++ b/code/modules/projectiles/ammunition/caseless/rocket.dm @@ -0,0 +1,11 @@ +/obj/item/ammo_casing/caseless/a84mm + desc = "An 84mm anti-armour rocket." + caliber = "84mm" + icon_state = "s-casing-live" + projectile_type = /obj/item/projectile/bullet/a84mm + +/obj/item/ammo_casing/caseless/a75 + desc = "A .75 bullet casing." + caliber = "75" + icon_state = "s-casing-live" + projectile_type = /obj/item/projectile/bullet/gyro diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm deleted file mode 100644 index 96d0fd2e29..0000000000 --- a/code/modules/projectiles/ammunition/energy.dm +++ /dev/null @@ -1,258 +0,0 @@ -/obj/item/ammo_casing/energy - name = "energy weapon lens" - desc = "The part of the gun that makes the laser go pew." - caliber = "energy" - projectile_type = /obj/item/projectile/energy - var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot. - var/select_name = "energy" - fire_sound = 'sound/weapons/laser.ogg' - firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy - heavy_metal = FALSE - -/obj/item/ammo_casing/energy/chameleon - projectile_type = /obj/item/projectile/energy/chameleon - e_cost = 0 - var/hitscan_mode = FALSE - var/list/projectile_vars = list() - -/obj/item/ammo_casing/energy/chameleon/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") - . = ..() - if(!BB) - newshot() - for(var/V in projectile_vars) - if(BB.vars.Find(V)) - BB.vars[V] = projectile_vars[V] - if(hitscan_mode) - BB.hitscan = TRUE - -/obj/item/ammo_casing/energy/laser - projectile_type = /obj/item/projectile/beam/laser - select_name = "kill" - -/obj/item/ammo_casing/energy/lasergun - projectile_type = /obj/item/projectile/beam/laser - e_cost = 83 - select_name = "kill" - -/obj/item/ammo_casing/energy/lasergun/old - projectile_type = /obj/item/projectile/beam/laser - e_cost = 200 - select_name = "kill" - -/obj/item/ammo_casing/energy/laser/hos - e_cost = 100 - -/obj/item/ammo_casing/energy/laser/practice - projectile_type = /obj/item/projectile/beam/practice - select_name = "practice" - -/obj/item/ammo_casing/energy/laser/scatter - projectile_type = /obj/item/projectile/beam/scatter - pellets = 5 - variance = 25 - select_name = "scatter" - -/obj/item/ammo_casing/energy/laser/scatter/disabler - projectile_type = /obj/item/projectile/beam/disabler - pellets = 3 - variance = 15 - -/obj/item/ammo_casing/energy/laser/heavy - projectile_type = /obj/item/projectile/beam/laser/heavylaser - select_name = "anti-vehicle" - fire_sound = 'sound/weapons/lasercannonfire.ogg' - -/obj/item/ammo_casing/energy/laser/pulse - projectile_type = /obj/item/projectile/beam/pulse - e_cost = 200 - select_name = "DESTROY" - fire_sound = 'sound/weapons/pulse.ogg' - -/obj/item/ammo_casing/energy/laser/bluetag - projectile_type = /obj/item/projectile/beam/lasertag/bluetag - select_name = "bluetag" - -/obj/item/ammo_casing/energy/laser/bluetag/hitscan - projectile_type = /obj/item/projectile/beam/lasertag/bluetag/hitscan - -/obj/item/ammo_casing/energy/laser/redtag - projectile_type = /obj/item/projectile/beam/lasertag/redtag - select_name = "redtag" - -/obj/item/ammo_casing/energy/laser/redtag/hitscan - projectile_type = /obj/item/projectile/beam/lasertag/redtag/hitscan - -/obj/item/ammo_casing/energy/xray - projectile_type = /obj/item/projectile/beam/xray - e_cost = 50 - fire_sound = 'sound/weapons/laser3.ogg' - -/obj/item/ammo_casing/energy/electrode - projectile_type = /obj/item/projectile/energy/electrode - select_name = "stun" - fire_sound = 'sound/weapons/taser.ogg' - e_cost = 200 - -/obj/item/ammo_casing/energy/electrode/spec - e_cost = 100 - -/obj/item/ammo_casing/energy/electrode/gun - fire_sound = 'sound/weapons/gunshot.ogg' - e_cost = 100 - -/obj/item/ammo_casing/energy/electrode/hos - e_cost = 200 - -/obj/item/ammo_casing/energy/electrode/old - e_cost = 1000 - -/obj/item/ammo_casing/energy/ion - projectile_type = /obj/item/projectile/ion - select_name = "ion" - fire_sound = 'sound/weapons/ionrifle.ogg' - -/obj/item/ammo_casing/energy/declone - projectile_type = /obj/item/projectile/energy/declone - select_name = "declone" - fire_sound = 'sound/weapons/pulse3.ogg' - -/obj/item/ammo_casing/energy/mindflayer - projectile_type = /obj/item/projectile/beam/mindflayer - select_name = "MINDFUCK" - fire_sound = 'sound/weapons/laser.ogg' - -/obj/item/ammo_casing/energy/flora - fire_sound = 'sound/effects/stealthoff.ogg' - -/obj/item/ammo_casing/energy/flora/yield - projectile_type = /obj/item/projectile/energy/florayield - select_name = "yield" - -/obj/item/ammo_casing/energy/flora/mut - projectile_type = /obj/item/projectile/energy/floramut - select_name = "mutation" - -/obj/item/ammo_casing/energy/temp - projectile_type = /obj/item/projectile/temp - select_name = "freeze" - e_cost = 250 - fire_sound = 'sound/weapons/pulse3.ogg' - -/obj/item/ammo_casing/energy/temp/hot - projectile_type = /obj/item/projectile/temp/hot - select_name = "bake" - -/obj/item/ammo_casing/energy/meteor - projectile_type = /obj/item/projectile/meteor - select_name = "goddamn meteor" - -/obj/item/ammo_casing/energy/disabler - projectile_type = /obj/item/projectile/beam/disabler - select_name = "disable" - e_cost = 50 - fire_sound = 'sound/weapons/taser2.ogg' - -/obj/item/ammo_casing/energy/plasma - projectile_type = /obj/item/projectile/plasma - select_name = "plasma burst" - fire_sound = 'sound/weapons/plasma_cutter.ogg' - delay = 15 - e_cost = 25 - -/obj/item/ammo_casing/energy/plasma/adv - projectile_type = /obj/item/projectile/plasma/adv - delay = 10 - e_cost = 10 - -/obj/item/ammo_casing/energy/wormhole - projectile_type = /obj/item/projectile/beam/wormhole - e_cost = 0 - fire_sound = 'sound/weapons/pulse3.ogg' - var/obj/item/gun/energy/wormhole_projector/gun = null - select_name = "blue" - -/obj/item/ammo_casing/energy/wormhole/orange - projectile_type = /obj/item/projectile/beam/wormhole/orange - select_name = "orange" - -/obj/item/ammo_casing/energy/bolt - projectile_type = /obj/item/projectile/energy/bolt - select_name = "bolt" - e_cost = 500 - fire_sound = 'sound/weapons/genhit.ogg' - -/obj/item/ammo_casing/energy/bolt/halloween - projectile_type = /obj/item/projectile/energy/bolt/halloween - -/obj/item/ammo_casing/energy/bolt/large - projectile_type = /obj/item/projectile/energy/bolt/large - select_name = "heavy bolt" - -/obj/item/ammo_casing/energy/net - projectile_type = /obj/item/projectile/energy/net - select_name = "netting" - pellets = 6 - variance = 40 - -/obj/item/ammo_casing/energy/trap - projectile_type = /obj/item/projectile/energy/trap - select_name = "snare" - -/obj/item/ammo_casing/energy/instakill - projectile_type = /obj/item/projectile/beam/instakill - e_cost = 0 - select_name = "DESTROY" - -/obj/item/ammo_casing/energy/instakill/blue - projectile_type = /obj/item/projectile/beam/instakill/blue - -/obj/item/ammo_casing/energy/instakill/red - projectile_type = /obj/item/projectile/beam/instakill/red - -/obj/item/ammo_casing/energy/tesla_revolver - fire_sound = 'sound/magic/lightningbolt.ogg' - e_cost = 200 - select_name = "stun" - projectile_type = /obj/item/projectile/energy/tesla/revolver - -/obj/item/ammo_casing/energy/gravityrepulse - projectile_type = /obj/item/projectile/gravityrepulse - e_cost = 0 - fire_sound = 'sound/weapons/wave.ogg' - select_name = "repulse" - delay = 50 - var/obj/item/gun/energy/gravity_gun/gun = null - -/obj/item/ammo_casing/energy/gravityrepulse/New(var/obj/item/gun/energy/gravity_gun/G) - gun = G - -/obj/item/ammo_casing/energy/gravityattract - projectile_type = /obj/item/projectile/gravityattract - e_cost = 0 - fire_sound = 'sound/weapons/wave.ogg' - select_name = "attract" - delay = 50 - var/obj/item/gun/energy/gravity_gun/gun = null - - -/obj/item/ammo_casing/energy/gravityattract/New(var/obj/item/gun/energy/gravity_gun/G) - gun = G - -/obj/item/ammo_casing/energy/gravitychaos - projectile_type = /obj/item/projectile/gravitychaos - e_cost = 0 - fire_sound = 'sound/weapons/wave.ogg' - select_name = "chaos" - delay = 50 - var/obj/item/gun/energy/gravity_gun/gun = null - -/obj/item/ammo_casing/energy/gravitychaos/New(var/obj/item/gun/energy/gravity_gun/G) - gun = G - -/obj/item/ammo_casing/energy/plasma - projectile_type = /obj/item/projectile/plasma - select_name = "plasma burst" - fire_sound = 'sound/weapons/pulse.ogg' - -/obj/item/ammo_casing/energy/plasma/adv - projectile_type = /obj/item/projectile/plasma/adv diff --git a/code/modules/projectiles/ammunition/energy/_energy.dm b/code/modules/projectiles/ammunition/energy/_energy.dm new file mode 100644 index 0000000000..3a4e457c3d --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/_energy.dm @@ -0,0 +1,10 @@ +/obj/item/ammo_casing/energy + name = "energy weapon lens" + desc = "The part of the gun that makes the laser go pew." + caliber = "energy" + projectile_type = /obj/item/projectile/energy + var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot. + var/select_name = "energy" + fire_sound = 'sound/weapons/laser.ogg' + firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy + heavy_metal = FALSE diff --git a/code/modules/projectiles/ammunition/energy/chameleon.dm b/code/modules/projectiles/ammunition/energy/chameleon.dm new file mode 100644 index 0000000000..4688518d46 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/chameleon.dm @@ -0,0 +1,15 @@ +/obj/item/ammo_casing/energy/chameleon + projectile_type = /obj/item/projectile/energy/chameleon + e_cost = 0 + var/hitscan_mode = FALSE + var/list/projectile_vars = list() + +/obj/item/ammo_casing/energy/chameleon/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + . = ..() + if(!BB) + newshot() + for(var/V in projectile_vars) + if(BB.vars.Find(V)) + BB.vars[V] = projectile_vars[V] + if(hitscan_mode) + BB.hitscan = TRUE diff --git a/code/modules/projectiles/ammunition/energy/ebow.dm b/code/modules/projectiles/ammunition/energy/ebow.dm new file mode 100644 index 0000000000..8d9c72d1ba --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/ebow.dm @@ -0,0 +1,12 @@ +/obj/item/ammo_casing/energy/bolt + projectile_type = /obj/item/projectile/energy/bolt + select_name = "bolt" + e_cost = 500 + fire_sound = 'sound/weapons/genhit.ogg' + +/obj/item/ammo_casing/energy/bolt/halloween + projectile_type = /obj/item/projectile/energy/bolt/halloween + +/obj/item/ammo_casing/energy/bolt/large + projectile_type = /obj/item/projectile/energy/bolt/large + select_name = "heavy bolt" diff --git a/code/modules/projectiles/ammunition/energy/gravity.dm b/code/modules/projectiles/ammunition/energy/gravity.dm new file mode 100644 index 0000000000..f549a5b5e4 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/gravity.dm @@ -0,0 +1,36 @@ +/obj/item/ammo_casing/energy/gravityrepulse + projectile_type = /obj/item/projectile/gravityrepulse + e_cost = 0 + fire_sound = 'sound/weapons/wave.ogg' + select_name = "repulse" + delay = 50 + var/obj/item/gun/energy/gravity_gun/gun + +/obj/item/ammo_casing/energy/gravityrepulse/Initialize(mapload, obj/item/gun/energy/gravity_gun/G) + . = ..() + gun = G + +/obj/item/ammo_casing/energy/gravityattract + projectile_type = /obj/item/projectile/gravityattract + e_cost = 0 + fire_sound = 'sound/weapons/wave.ogg' + select_name = "attract" + delay = 50 + var/obj/item/gun/energy/gravity_gun/gun + + +/obj/item/ammo_casing/energy/gravityattract/Initialize(mapload, obj/item/gun/energy/gravity_gun/G) + . = ..() + gun = G + +/obj/item/ammo_casing/energy/gravitychaos + projectile_type = /obj/item/projectile/gravitychaos + e_cost = 0 + fire_sound = 'sound/weapons/wave.ogg' + select_name = "chaos" + delay = 50 + var/obj/item/gun/energy/gravity_gun/gun + +/obj/item/ammo_casing/energy/gravitychaos/Initialize(mapload, obj/item/gun/energy/gravity_gun/G) + . = ..() + gun = G diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm new file mode 100644 index 0000000000..c87ea2ffbd --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/laser.dm @@ -0,0 +1,66 @@ +/obj/item/ammo_casing/energy/laser + projectile_type = /obj/item/projectile/beam/laser + select_name = "kill" + +/obj/item/ammo_casing/energy/lasergun + projectile_type = /obj/item/projectile/beam/laser + e_cost = 83 + select_name = "kill" + +/obj/item/ammo_casing/energy/lasergun/old + projectile_type = /obj/item/projectile/beam/laser + e_cost = 200 + select_name = "kill" + +/obj/item/ammo_casing/energy/laser/hos + e_cost = 100 + +/obj/item/ammo_casing/energy/laser/practice + projectile_type = /obj/item/projectile/beam/practice + select_name = "practice" + +/obj/item/ammo_casing/energy/laser/scatter + projectile_type = /obj/item/projectile/beam/scatter + pellets = 5 + variance = 25 + select_name = "scatter" + +/obj/item/ammo_casing/energy/laser/scatter/disabler + projectile_type = /obj/item/projectile/beam/disabler + pellets = 3 + variance = 15 + +/obj/item/ammo_casing/energy/laser/heavy + projectile_type = /obj/item/projectile/beam/laser/heavylaser + select_name = "anti-vehicle" + fire_sound = 'sound/weapons/lasercannonfire.ogg' + +/obj/item/ammo_casing/energy/laser/pulse + projectile_type = /obj/item/projectile/beam/pulse + e_cost = 200 + select_name = "DESTROY" + fire_sound = 'sound/weapons/pulse.ogg' + +/obj/item/ammo_casing/energy/laser/bluetag + projectile_type = /obj/item/projectile/beam/lasertag/bluetag + select_name = "bluetag" + +/obj/item/ammo_casing/energy/laser/bluetag/hitscan + projectile_type = /obj/item/projectile/beam/lasertag/bluetag/hitscan + +/obj/item/ammo_casing/energy/laser/redtag + projectile_type = /obj/item/projectile/beam/lasertag/redtag + select_name = "redtag" + +/obj/item/ammo_casing/energy/laser/redtag/hitscan + projectile_type = /obj/item/projectile/beam/lasertag/redtag/hitscan + +/obj/item/ammo_casing/energy/xray + projectile_type = /obj/item/projectile/beam/xray + e_cost = 50 + fire_sound = 'sound/weapons/laser3.ogg' + +/obj/item/ammo_casing/energy/mindflayer + projectile_type = /obj/item/projectile/beam/mindflayer + select_name = "MINDFUCK" + fire_sound = 'sound/weapons/laser.ogg' diff --git a/code/modules/projectiles/ammunition/energy/lmg.dm b/code/modules/projectiles/ammunition/energy/lmg.dm new file mode 100644 index 0000000000..5ebe83f792 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/lmg.dm @@ -0,0 +1,6 @@ +/obj/item/ammo_casing/energy/c3dbullet + projectile_type = /obj/item/projectile/bullet/c3d + select_name = "spraydown" + fire_sound = 'sound/weapons/gunshot_smg.ogg' + e_cost = 20 + firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect diff --git a/code/modules/projectiles/ammunition/energy/plasma.dm b/code/modules/projectiles/ammunition/energy/plasma.dm new file mode 100644 index 0000000000..d02abf9c88 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/plasma.dm @@ -0,0 +1,11 @@ +/obj/item/ammo_casing/energy/plasma + projectile_type = /obj/item/projectile/plasma + select_name = "plasma burst" + fire_sound = 'sound/weapons/plasma_cutter.ogg' + delay = 15 + e_cost = 25 + +/obj/item/ammo_casing/energy/plasma/adv + projectile_type = /obj/item/projectile/plasma/adv + delay = 10 + e_cost = 10 diff --git a/code/modules/projectiles/ammunition/plasma.dm b/code/modules/projectiles/ammunition/energy/plasma_cit.dm similarity index 100% rename from code/modules/projectiles/ammunition/plasma.dm rename to code/modules/projectiles/ammunition/energy/plasma_cit.dm diff --git a/code/modules/projectiles/ammunition/energy/portal.dm b/code/modules/projectiles/ammunition/energy/portal.dm new file mode 100644 index 0000000000..3a6300a2f5 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/portal.dm @@ -0,0 +1,14 @@ +/obj/item/ammo_casing/energy/wormhole + projectile_type = /obj/item/projectile/beam/wormhole + e_cost = 0 + fire_sound = 'sound/weapons/pulse3.ogg' + var/obj/item/gun/energy/wormhole_projector/gun = null + select_name = "blue" + +/obj/item/ammo_casing/energy/wormhole/orange + projectile_type = /obj/item/projectile/beam/wormhole/orange + select_name = "orange" + +/obj/item/ammo_casing/energy/wormhole/Initialize(mapload, obj/item/gun/energy/wormhole_projector/wh) + . = ..() + gun = wh diff --git a/code/modules/projectiles/ammunition/energy/special.dm b/code/modules/projectiles/ammunition/energy/special.dm new file mode 100644 index 0000000000..0438baf490 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/special.dm @@ -0,0 +1,61 @@ +/obj/item/ammo_casing/energy/ion + projectile_type = /obj/item/projectile/ion + select_name = "ion" + fire_sound = 'sound/weapons/ionrifle.ogg' + +/obj/item/ammo_casing/energy/declone + projectile_type = /obj/item/projectile/energy/declone + select_name = "declone" + fire_sound = 'sound/weapons/pulse3.ogg' + +/obj/item/ammo_casing/energy/flora + fire_sound = 'sound/effects/stealthoff.ogg' + +/obj/item/ammo_casing/energy/flora/yield + projectile_type = /obj/item/projectile/energy/florayield + select_name = "yield" + +/obj/item/ammo_casing/energy/flora/mut + projectile_type = /obj/item/projectile/energy/floramut + select_name = "mutation" + +/obj/item/ammo_casing/energy/temp + projectile_type = /obj/item/projectile/temp + select_name = "freeze" + e_cost = 250 + fire_sound = 'sound/weapons/pulse3.ogg' + +/obj/item/ammo_casing/energy/temp/hot + projectile_type = /obj/item/projectile/temp/hot + select_name = "bake" + +/obj/item/ammo_casing/energy/meteor + projectile_type = /obj/item/projectile/meteor + select_name = "goddamn meteor" + +/obj/item/ammo_casing/energy/net + projectile_type = /obj/item/projectile/energy/net + select_name = "netting" + pellets = 6 + variance = 40 + +/obj/item/ammo_casing/energy/trap + projectile_type = /obj/item/projectile/energy/trap + select_name = "snare" + +/obj/item/ammo_casing/energy/instakill + projectile_type = /obj/item/projectile/beam/instakill + e_cost = 0 + select_name = "DESTROY" + +/obj/item/ammo_casing/energy/instakill/blue + projectile_type = /obj/item/projectile/beam/instakill/blue + +/obj/item/ammo_casing/energy/instakill/red + projectile_type = /obj/item/projectile/beam/instakill/red + +/obj/item/ammo_casing/energy/tesla_revolver + fire_sound = 'sound/magic/lightningbolt.ogg' + e_cost = 200 + select_name = "stun" + projectile_type = /obj/item/projectile/energy/tesla/revolver diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm new file mode 100644 index 0000000000..5a88a97b08 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy/stun.dm @@ -0,0 +1,24 @@ +/obj/item/ammo_casing/energy/electrode + projectile_type = /obj/item/projectile/energy/electrode + select_name = "stun" + fire_sound = 'sound/weapons/taser.ogg' + e_cost = 200 + +/obj/item/ammo_casing/energy/electrode/spec + e_cost = 100 + +/obj/item/ammo_casing/energy/electrode/gun + fire_sound = 'sound/weapons/gunshot.ogg' + e_cost = 100 + +/obj/item/ammo_casing/energy/electrode/hos + e_cost = 200 + +/obj/item/ammo_casing/energy/electrode/old + e_cost = 1000 + +/obj/item/ammo_casing/energy/disabler + projectile_type = /obj/item/projectile/beam/disabler + select_name = "disable" + e_cost = 50 + fire_sound = 'sound/weapons/taser2.ogg' diff --git a/code/modules/projectiles/ammunition/special/magic.dm b/code/modules/projectiles/ammunition/special/magic.dm new file mode 100644 index 0000000000..6ebf5739a9 --- /dev/null +++ b/code/modules/projectiles/ammunition/special/magic.dm @@ -0,0 +1,42 @@ +/obj/item/ammo_casing/magic + name = "magic casing" + desc = "I didn't even know magic needed ammo..." + projectile_type = /obj/item/projectile/magic + firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic + heavy_metal = FALSE + +/obj/item/ammo_casing/magic/change + projectile_type = /obj/item/projectile/magic/change + +/obj/item/ammo_casing/magic/animate + projectile_type = /obj/item/projectile/magic/animate + +/obj/item/ammo_casing/magic/heal + projectile_type = /obj/item/projectile/magic/resurrection + +/obj/item/ammo_casing/magic/death + projectile_type = /obj/item/projectile/magic/death + +/obj/item/ammo_casing/magic/teleport + projectile_type = /obj/item/projectile/magic/teleport + +/obj/item/ammo_casing/magic/door + projectile_type = /obj/item/projectile/magic/door + +/obj/item/ammo_casing/magic/fireball + projectile_type = /obj/item/projectile/magic/aoe/fireball + +/obj/item/ammo_casing/magic/chaos + projectile_type = /obj/item/projectile/magic + +/obj/item/ammo_casing/magic/spellblade + projectile_type = /obj/item/projectile/magic/spellblade + +/obj/item/ammo_casing/magic/arcane_barrage + projectile_type = /obj/item/projectile/magic/arcane_barrage + +/obj/item/ammo_casing/magic/chaos/newshot() + ..() + +/obj/item/ammo_casing/magic/honk + projectile_type = /obj/item/projectile/bullet/honker diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special/syringe.dm similarity index 53% rename from code/modules/projectiles/ammunition/special.dm rename to code/modules/projectiles/ammunition/special/syringe.dm index b378d7fa6c..4a2a354ca6 100644 --- a/code/modules/projectiles/ammunition/special.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -1,111 +1,61 @@ -/obj/item/ammo_casing/magic - name = "magic casing" - desc = "I didn't even know magic needed ammo..." - projectile_type = /obj/item/projectile/magic - firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic - heavy_metal = FALSE - -/obj/item/ammo_casing/magic/change - projectile_type = /obj/item/projectile/magic/change - -/obj/item/ammo_casing/magic/animate - projectile_type = /obj/item/projectile/magic/animate - -/obj/item/ammo_casing/magic/heal - projectile_type = /obj/item/projectile/magic/resurrection - -/obj/item/ammo_casing/magic/death - projectile_type = /obj/item/projectile/magic/death - -/obj/item/ammo_casing/magic/teleport - projectile_type = /obj/item/projectile/magic/teleport - -/obj/item/ammo_casing/magic/door - projectile_type = /obj/item/projectile/magic/door - -/obj/item/ammo_casing/magic/fireball - projectile_type = /obj/item/projectile/magic/aoe/fireball - -/obj/item/ammo_casing/magic/chaos - projectile_type = /obj/item/projectile/magic - -/obj/item/ammo_casing/magic/spellblade - projectile_type = /obj/item/projectile/magic/spellblade - -/obj/item/ammo_casing/magic/arcane_barrage - projectile_type = /obj/item/projectile/magic/arcane_barrage - -/obj/item/ammo_casing/magic/chaos/newshot() - ..() - -/obj/item/ammo_casing/magic/honk - projectile_type = /obj/item/projectile/bullet/honker - -/obj/item/ammo_casing/syringegun - name = "syringe gun spring" - desc = "A high-power spring that throws syringes." - projectile_type = /obj/item/projectile/bullet/dart/syringe - firing_effect_type = null - -/obj/item/ammo_casing/syringegun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") - if(!BB) - return - if(istype(loc, /obj/item/gun/syringe)) - var/obj/item/gun/syringe/SG = loc - if(!SG.syringes.len) - return - - var/obj/item/reagent_containers/syringe/S = SG.syringes[1] - - S.reagents.trans_to(BB, S.reagents.total_volume) - BB.name = S.name - var/obj/item/projectile/bullet/dart/D = BB - D.piercing = S.proj_piercing - SG.syringes.Remove(S) - qdel(S) - ..() - -/obj/item/ammo_casing/chemgun - name = "dart synthesiser" - desc = "A high-power spring, linked to an energy-based dart synthesiser." - projectile_type = /obj/item/projectile/bullet/dart - firing_effect_type = null - -/obj/item/ammo_casing/chemgun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") - if(!BB) - return - if(istype(loc, /obj/item/gun/chem)) - var/obj/item/gun/chem/CG = loc - if(CG.syringes_left <= 0) - return - CG.reagents.trans_to(BB, 15) - BB.name = "chemical dart" - CG.syringes_left-- - ..() - -/obj/item/ammo_casing/dnainjector - name = "rigged syringe gun spring" - desc = "A high-power spring that throws DNA injectors." - projectile_type = /obj/item/projectile/bullet/dnainjector - firing_effect_type = null - -/obj/item/ammo_casing/dnainjector/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") - if(!BB) - return - if(istype(loc, /obj/item/gun/syringe/dna)) - var/obj/item/gun/syringe/dna/SG = loc - if(!SG.syringes.len) - return - - var/obj/item/dnainjector/S = popleft(SG.syringes) - var/obj/item/projectile/bullet/dnainjector/D = BB - S.forceMove(D) - D.injector = S - ..() - -/obj/item/ammo_casing/energy/c3dbullet - projectile_type = /obj/item/projectile/bullet/c3d - select_name = "spraydown" - fire_sound = 'sound/weapons/gunshot_smg.ogg' - e_cost = 20 - firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect +/obj/item/ammo_casing/syringegun + name = "syringe gun spring" + desc = "A high-power spring that throws syringes." + projectile_type = /obj/item/projectile/bullet/dart/syringe + firing_effect_type = null + +/obj/item/ammo_casing/syringegun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if(!BB) + return + if(istype(loc, /obj/item/gun/syringe)) + var/obj/item/gun/syringe/SG = loc + if(!SG.syringes.len) + return + + var/obj/item/reagent_containers/syringe/S = SG.syringes[1] + + S.reagents.trans_to(BB, S.reagents.total_volume) + BB.name = S.name + var/obj/item/projectile/bullet/dart/D = BB + D.piercing = S.proj_piercing + SG.syringes.Remove(S) + qdel(S) + ..() + +/obj/item/ammo_casing/chemgun + name = "dart synthesiser" + desc = "A high-power spring, linked to an energy-based dart synthesiser." + projectile_type = /obj/item/projectile/bullet/dart + firing_effect_type = null + +/obj/item/ammo_casing/chemgun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if(!BB) + return + if(istype(loc, /obj/item/gun/chem)) + var/obj/item/gun/chem/CG = loc + if(CG.syringes_left <= 0) + return + CG.reagents.trans_to(BB, 15) + BB.name = "chemical dart" + CG.syringes_left-- + ..() + +/obj/item/ammo_casing/dnainjector + name = "rigged syringe gun spring" + desc = "A high-power spring that throws DNA injectors." + projectile_type = /obj/item/projectile/bullet/dnainjector + firing_effect_type = null + +/obj/item/ammo_casing/dnainjector/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if(!BB) + return + if(istype(loc, /obj/item/gun/syringe/dna)) + var/obj/item/gun/syringe/dna/SG = loc + if(!SG.syringes.len) + return + + var/obj/item/dnainjector/S = popleft(SG.syringes) + var/obj/item/projectile/bullet/dnainjector/D = BB + S.forceMove(D) + D.injector = S + ..() diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/boxes_magazines/_box_magazine.dm similarity index 96% rename from code/modules/projectiles/box_magazine.dm rename to code/modules/projectiles/boxes_magazines/_box_magazine.dm index 57860e7910..1c5a2b1199 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/boxes_magazines/_box_magazine.dm @@ -1,121 +1,121 @@ -//Boxes of ammo -/obj/item/ammo_box - name = "ammo box (null_reference_exception)" - desc = "A box of ammo." - icon_state = "357" - icon = 'icons/obj/ammo.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - item_state = "syringe_kit" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - materials = list(MAT_METAL=30000) - throwforce = 2 - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 7 - var/list/stored_ammo = list() - var/ammo_type = /obj/item/ammo_casing - var/max_ammo = 7 - var/multiple_sprites = 0 - var/caliber - var/multiload = 1 - var/start_empty = 0 - -/obj/item/ammo_box/Initialize() - . = ..() - if(!start_empty) - for(var/i = 1, i <= max_ammo, i++) - stored_ammo += new ammo_type(src) - update_icon() - -/obj/item/ammo_box/proc/get_round(keep = 0) - if (!stored_ammo.len) - return null - else - var/b = stored_ammo[stored_ammo.len] - stored_ammo -= b - if (keep) - stored_ammo.Insert(1,b) - return b - -/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0) - // Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type. - if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) - return 0 - - if (stored_ammo.len < max_ammo) - stored_ammo += R - R.forceMove(src) - return 1 - - //for accessibles magazines (e.g internal ones) when full, start replacing spent ammo - else if(replace_spent) - for(var/obj/item/ammo_casing/AC in stored_ammo) - if(!AC.BB)//found a spent ammo - stored_ammo -= AC - AC.forceMove(get_turf(src.loc)) - - stored_ammo += R - R.forceMove(src) - return 1 - - return 0 - -/obj/item/ammo_box/proc/can_load(mob/user) - return 1 - -/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = FALSE, replace_spent = 0) - var/num_loaded = 0 - if(!can_load(user)) - return - if(istype(A, /obj/item/ammo_box)) - var/obj/item/ammo_box/AM = A - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - var/did_load = give_round(AC, replace_spent) - if(did_load) - AM.stored_ammo -= AC - num_loaded++ - if(!did_load || !multiload) - break - if(istype(A, /obj/item/ammo_casing)) - var/obj/item/ammo_casing/AC = A - if(give_round(AC, replace_spent)) - user.transferItemToLoc(AC, src, TRUE) - num_loaded++ - - if(num_loaded) - if(!silent) - to_chat(user, "You load [num_loaded] shell\s into \the [src]!") - playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) - A.update_icon() - update_icon() - - return num_loaded - -/obj/item/ammo_box/attack_self(mob/user) - var/obj/item/ammo_casing/A = get_round() - if(A) - if(!user.put_in_hands(A)) - A.bounce_away(FALSE, NONE) - playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) - to_chat(user, "You remove a round from \the [src]!") - update_icon() - -/obj/item/ammo_box/update_icon() - switch(multiple_sprites) - if(1) - icon_state = "[initial(icon_state)]-[stored_ammo.len]" - if(2) - icon_state = "[initial(icon_state)]-[stored_ammo.len ? "[max_ammo]" : "0"]" - desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!" - -//Behavior for magazines -/obj/item/ammo_box/magazine/proc/ammo_count() - return stored_ammo.len - -/obj/item/ammo_box/magazine/proc/empty_magazine() - var/turf_mag = get_turf(src) - for(var/obj/item/ammo in stored_ammo) - ammo.forceMove(turf_mag) +//Boxes of ammo +/obj/item/ammo_box + name = "ammo box (null_reference_exception)" + desc = "A box of ammo." + icon_state = "357" + icon = 'icons/obj/ammo.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + item_state = "syringe_kit" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + materials = list(MAT_METAL=30000) + throwforce = 2 + w_class = WEIGHT_CLASS_TINY + throw_speed = 3 + throw_range = 7 + var/list/stored_ammo = list() + var/ammo_type = /obj/item/ammo_casing + var/max_ammo = 7 + var/multiple_sprites = 0 + var/caliber + var/multiload = 1 + var/start_empty = 0 + +/obj/item/ammo_box/Initialize() + . = ..() + if(!start_empty) + for(var/i = 1, i <= max_ammo, i++) + stored_ammo += new ammo_type(src) + update_icon() + +/obj/item/ammo_box/proc/get_round(keep = 0) + if (!stored_ammo.len) + return null + else + var/b = stored_ammo[stored_ammo.len] + stored_ammo -= b + if (keep) + stored_ammo.Insert(1,b) + return b + +/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0) + // Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type. + if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + return 0 + + if (stored_ammo.len < max_ammo) + stored_ammo += R + R.forceMove(src) + return 1 + + //for accessibles magazines (e.g internal ones) when full, start replacing spent ammo + else if(replace_spent) + for(var/obj/item/ammo_casing/AC in stored_ammo) + if(!AC.BB)//found a spent ammo + stored_ammo -= AC + AC.forceMove(get_turf(src.loc)) + + stored_ammo += R + R.forceMove(src) + return 1 + + return 0 + +/obj/item/ammo_box/proc/can_load(mob/user) + return 1 + +/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = FALSE, replace_spent = 0) + var/num_loaded = 0 + if(!can_load(user)) + return + if(istype(A, /obj/item/ammo_box)) + var/obj/item/ammo_box/AM = A + for(var/obj/item/ammo_casing/AC in AM.stored_ammo) + var/did_load = give_round(AC, replace_spent) + if(did_load) + AM.stored_ammo -= AC + num_loaded++ + if(!did_load || !multiload) + break + if(istype(A, /obj/item/ammo_casing)) + var/obj/item/ammo_casing/AC = A + if(give_round(AC, replace_spent)) + user.transferItemToLoc(AC, src, TRUE) + num_loaded++ + + if(num_loaded) + if(!silent) + to_chat(user, "You load [num_loaded] shell\s into \the [src]!") + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) + A.update_icon() + update_icon() + + return num_loaded + +/obj/item/ammo_box/attack_self(mob/user) + var/obj/item/ammo_casing/A = get_round() + if(A) + if(!user.put_in_hands(A)) + A.bounce_away(FALSE, NONE) + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) + to_chat(user, "You remove a round from \the [src]!") + update_icon() + +/obj/item/ammo_box/update_icon() + switch(multiple_sprites) + if(1) + icon_state = "[initial(icon_state)]-[stored_ammo.len]" + if(2) + icon_state = "[initial(icon_state)]-[stored_ammo.len ? "[max_ammo]" : "0"]" + desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!" + +//Behavior for magazines +/obj/item/ammo_box/magazine/proc/ammo_count() + return stored_ammo.len + +/obj/item/ammo_box/magazine/proc/empty_magazine() + var/turf_mag = get_turf(src) + for(var/obj/item/ammo in stored_ammo) + ammo.forceMove(turf_mag) stored_ammo -= ammo \ No newline at end of file diff --git a/code/modules/projectiles/boxes_magazines/external/grenade.dm b/code/modules/projectiles/boxes_magazines/external/grenade.dm new file mode 100644 index 0000000000..2b3c31f81c --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/grenade.dm @@ -0,0 +1,8 @@ +/obj/item/ammo_box/magazine/m75 + name = "specialized magazine (.75)" + icon_state = "75" + ammo_type = /obj/item/ammo_casing/caseless/a75 + caliber = "75" + multiple_sprites = 2 + max_ammo = 8 + diff --git a/code/modules/projectiles/boxes_magazines/external/lmg.dm b/code/modules/projectiles/boxes_magazines/external/lmg.dm new file mode 100644 index 0000000000..cb42989022 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/lmg.dm @@ -0,0 +1,22 @@ +/obj/item/ammo_box/magazine/mm195x129 + name = "box magazine (1.95x129mm)" + icon_state = "a762-50" + ammo_type = /obj/item/ammo_casing/mm195x129 + caliber = "mm195129" + max_ammo = 50 + +/obj/item/ammo_box/magazine/mm195x129/hollow + name = "box magazine (Hollow-Point 1.95x129mm)" + ammo_type = /obj/item/ammo_casing/mm195x129/hollow + +/obj/item/ammo_box/magazine/mm195x129/ap + name = "box magazine (Armor Penetrating 1.95x129mm)" + ammo_type = /obj/item/ammo_casing/mm195x129/ap + +/obj/item/ammo_box/magazine/mm195x129/incen + name = "box magazine (Incendiary 1.95x129mm)" + ammo_type = /obj/item/ammo_casing/mm195x129/incen + +/obj/item/ammo_box/magazine/mm195x129/update_icon() + ..() + icon_state = "a762-[round(ammo_count(),10)]" diff --git a/code/modules/projectiles/boxes_magazines/external/pistol.dm b/code/modules/projectiles/boxes_magazines/external/pistol.dm new file mode 100644 index 0000000000..d70b20c65c --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -0,0 +1,56 @@ +/obj/item/ammo_box/magazine/m10mm + name = "pistol magazine (10mm)" + desc = "A gun magazine." + icon_state = "9x19p" + ammo_type = /obj/item/ammo_casing/c10mm + caliber = "10mm" + max_ammo = 8 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/m10mm/fire + name = "pistol magazine (10mm incendiary)" + icon_state = "9x19pI" + desc = "A gun magazine. Loaded with rounds which ignite the target." + ammo_type = /obj/item/ammo_casing/c10mm/fire + +/obj/item/ammo_box/magazine/m10mm/hp + name = "pistol magazine (10mm HP)" + icon_state = "9x19pH" + desc= "A gun magazine. Loaded with hollow-point rounds, extremely effective against unarmored targets, but nearly useless against protective clothing." + ammo_type = /obj/item/ammo_casing/c10mm/hp + +/obj/item/ammo_box/magazine/m10mm/ap + name = "pistol magazine (10mm AP)" + icon_state = "9x19pA" + desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets." + ammo_type = /obj/item/ammo_casing/c10mm/ap + +/obj/item/ammo_box/magazine/m45 + name = "handgun magazine (.45)" + icon_state = "45-8" + ammo_type = /obj/item/ammo_casing/c45 + caliber = ".45" + max_ammo = 8 + +/obj/item/ammo_box/magazine/m45/update_icon() + ..() + icon_state = "45-[ammo_count() ? "8" : "0"]" + +/obj/item/ammo_box/magazine/pistolm9mm + name = "pistol magazine (9mm)" + icon_state = "9x19p-8" + ammo_type = /obj/item/ammo_casing/c9mm + caliber = "9mm" + max_ammo = 15 + +/obj/item/ammo_box/magazine/pistolm9mm/update_icon() + ..() + icon_state = "9x19p-[ammo_count() ? "8" : "0"]" + +/obj/item/ammo_box/magazine/m50 + name = "handgun magazine (.50ae)" + icon_state = "50ae" + ammo_type = /obj/item/ammo_casing/a50AE + caliber = ".50" + max_ammo = 7 + multiple_sprites = 1 diff --git a/code/modules/projectiles/boxes_magazines/external/rechargable.dm b/code/modules/projectiles/boxes_magazines/external/rechargable.dm new file mode 100644 index 0000000000..c4fb00aa22 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/rechargable.dm @@ -0,0 +1,14 @@ +/obj/item/ammo_box/magazine/recharge + name = "power pack" + desc = "A rechargeable, detachable battery that serves as a magazine for laser rifles." + icon_state = "oldrifle-20" + ammo_type = /obj/item/ammo_casing/caseless/laser + caliber = "laser" + max_ammo = 20 + +/obj/item/ammo_box/magazine/recharge/update_icon() + desc = "[initial(desc)] It has [stored_ammo.len] shot\s left." + icon_state = "oldrifle-[round(ammo_count(),4)]" + +/obj/item/ammo_box/magazine/recharge/attack_self() //No popping out the "bullets" + return diff --git a/code/modules/projectiles/boxes_magazines/external/rifle.dm b/code/modules/projectiles/boxes_magazines/external/rifle.dm new file mode 100644 index 0000000000..96e7d377ea --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/rifle.dm @@ -0,0 +1,21 @@ +/obj/item/ammo_box/magazine/m10mm/rifle + name = "rifle magazine (10mm)" + desc = "A well-worn magazine fitted for the surplus rifle." + icon_state = "75-8" + ammo_type = /obj/item/ammo_casing/c10mm + caliber = "10mm" + max_ammo = 10 + +/obj/item/ammo_box/magazine/m10mm/rifle/update_icon() + if(ammo_count()) + icon_state = "75-8" + else + icon_state = "75-0" + +/obj/item/ammo_box/magazine/m556 + name = "toploader magazine (5.56mm)" + icon_state = "5.56m" + ammo_type = /obj/item/ammo_casing/a556 + caliber = "a556" + max_ammo = 30 + multiple_sprites = 2 diff --git a/code/modules/projectiles/boxes_magazines/external/shotgun.dm b/code/modules/projectiles/boxes_magazines/external/shotgun.dm new file mode 100644 index 0000000000..dc8d0175ba --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/shotgun.dm @@ -0,0 +1,36 @@ +/obj/item/ammo_box/magazine/m12g + name = "shotgun magazine (12g taser slugs)" + desc = "A drum magazine." + icon_state = "m12gs" + ammo_type = /obj/item/ammo_casing/shotgun/stunslug + caliber = "shotgun" + max_ammo = 8 + +/obj/item/ammo_box/magazine/m12g/update_icon() + ..() + icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]" + +/obj/item/ammo_box/magazine/m12g/buckshot + name = "shotgun magazine (12g buckshot slugs)" + icon_state = "m12gb" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + +/obj/item/ammo_box/magazine/m12g/slug + name = "shotgun magazine (12g slugs)" + icon_state = "m12gb" + ammo_type = /obj/item/ammo_casing/shotgun + +/obj/item/ammo_box/magazine/m12g/dragon + name = "shotgun magazine (12g dragon's breath)" + icon_state = "m12gf" + ammo_type = /obj/item/ammo_casing/shotgun/dragonsbreath + +/obj/item/ammo_box/magazine/m12g/bioterror + name = "shotgun magazine (12g bioterror)" + icon_state = "m12gt" + ammo_type = /obj/item/ammo_casing/shotgun/dart/bioterror + +/obj/item/ammo_box/magazine/m12g/meteor + name = "shotgun magazine (12g meteor slugs)" + icon_state = "m12gbc" + ammo_type = /obj/item/ammo_casing/shotgun/meteorslug diff --git a/code/modules/projectiles/boxes_magazines/external/smg.dm b/code/modules/projectiles/boxes_magazines/external/smg.dm new file mode 100644 index 0000000000..c6dc004879 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/smg.dm @@ -0,0 +1,76 @@ +/obj/item/ammo_box/magazine/wt550m9 + name = "wt550 magazine (4.6x30mm)" + icon_state = "46x30mmt-20" + ammo_type = /obj/item/ammo_casing/c46x30mm + caliber = "4.6x30mm" + max_ammo = 20 + +/obj/item/ammo_box/magazine/wt550m9/update_icon() + ..() + icon_state = "46x30mmt-[round(ammo_count(),4)]" + +/obj/item/ammo_box/magazine/wt550m9/wtap + name = "wt550 magazine (Armour Piercing 4.6x30mm)" + icon_state = "46x30mmtA-20" + ammo_type = /obj/item/ammo_casing/c46x30mm/ap + +/obj/item/ammo_box/magazine/wt550m9/wtap/update_icon() + ..() + icon_state = "46x30mmtA-[round(ammo_count(),4)]" + +/obj/item/ammo_box/magazine/wt550m9/wtic + name = "wt550 magazine (Incindiary 4.6x30mm)" + icon_state = "46x30mmtI-20" + ammo_type = /obj/item/ammo_casing/c46x30mm/inc + +/obj/item/ammo_box/magazine/wt550m9/wtic/update_icon() + ..() + icon_state = "46x30mmtI-[round(ammo_count(),4)]" + +/obj/item/ammo_box/magazine/uzim9mm + name = "uzi magazine (9mm)" + icon_state = "uzi9mm-32" + ammo_type = /obj/item/ammo_casing/c9mm + caliber = "9mm" + max_ammo = 32 + +/obj/item/ammo_box/magazine/uzim9mm/update_icon() + ..() + icon_state = "uzi9mm-[round(ammo_count(),4)]" + +/obj/item/ammo_box/magazine/smgm9mm + name = "SMG magazine (9mm)" + icon_state = "smg9mm-42" + ammo_type = /obj/item/ammo_casing/c9mm + caliber = "9mm" + max_ammo = 21 + +/obj/item/ammo_box/magazine/smgm9mm/update_icon() + ..() + icon_state = "smg9mm-[ammo_count() ? "42" : "0"]" + +/obj/item/ammo_box/magazine/smgm9mm/ap + name = "SMG magazine (Armour Piercing 9mm)" + ammo_type = /obj/item/ammo_casing/c9mm/ap + +/obj/item/ammo_box/magazine/smgm9mm/fire + name = "SMG Magazine (Incindiary 9mm)" + ammo_type = /obj/item/ammo_casing/c9mm/inc + +/obj/item/ammo_box/magazine/smgm45 + name = "SMG magazine (.45)" + icon_state = "c20r45-24" + ammo_type = /obj/item/ammo_casing/c45/nostamina + caliber = ".45" + max_ammo = 24 + +/obj/item/ammo_box/magazine/smgm45/update_icon() + ..() + icon_state = "c20r45-[round(ammo_count(),2)]" + +/obj/item/ammo_box/magazine/tommygunm45 + name = "drum magazine (.45)" + icon_state = "drum45" + ammo_type = /obj/item/ammo_casing/c45 + caliber = ".45" + max_ammo = 50 diff --git a/code/modules/projectiles/boxes_magazines/external/sniper.dm b/code/modules/projectiles/boxes_magazines/external/sniper.dm new file mode 100644 index 0000000000..67c6257bac --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/sniper.dm @@ -0,0 +1,26 @@ +/obj/item/ammo_box/magazine/sniper_rounds + name = "sniper rounds (.50)" + icon_state = ".50mag" + ammo_type = /obj/item/ammo_casing/p50 + max_ammo = 6 + caliber = ".50" + +/obj/item/ammo_box/magazine/sniper_rounds/update_icon() + if(ammo_count()) + icon_state = "[initial(icon_state)]-ammo" + else + icon_state = "[initial(icon_state)]" + +/obj/item/ammo_box/magazine/sniper_rounds/soporific + name = "sniper rounds (Zzzzz)" + desc = "Soporific sniper rounds, designed for happy days and dead quiet nights..." + icon_state = "soporific" + ammo_type = /obj/item/ammo_casing/p50/soporific + max_ammo = 3 + caliber = ".50" + +/obj/item/ammo_box/magazine/sniper_rounds/penetrator + name = "sniper rounds (penetrator)" + desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it." + ammo_type = /obj/item/ammo_casing/p50/penetrator + max_ammo = 5 diff --git a/code/modules/projectiles/boxes_magazines/external/toy.dm b/code/modules/projectiles/boxes_magazines/external/toy.dm new file mode 100644 index 0000000000..cb66391c02 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/external/toy.dm @@ -0,0 +1,55 @@ +/obj/item/ammo_box/magazine/toy + name = "foam force META magazine" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + caliber = "foam_force" + +/obj/item/ammo_box/magazine/toy/smg + name = "foam force SMG magazine" + icon_state = "smg9mm-42" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + max_ammo = 20 + +/obj/item/ammo_box/magazine/toy/smg/update_icon() + ..() + if(ammo_count()) + icon_state = "smg9mm-42" + else + icon_state = "smg9mm-0" + +/obj/item/ammo_box/magazine/toy/smg/riot + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/magazine/toy/pistol + name = "foam force pistol magazine" + icon_state = "9x19p" + max_ammo = 8 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/toy/pistol/riot + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/magazine/toy/smgm45 + name = "donksoft SMG magazine" + caliber = "foam_force" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + max_ammo = 20 + +/obj/item/ammo_box/magazine/toy/smgm45/update_icon() + ..() + icon_state = "c20r45-[round(ammo_count(),2)]" + +/obj/item/ammo_box/magazine/toy/smgm45/riot + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/magazine/toy/m762 + name = "donksoft box magazine" + caliber = "foam_force" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + max_ammo = 50 + +/obj/item/ammo_box/magazine/toy/m762/update_icon() + ..() + icon_state = "a762-[round(ammo_count(),10)]" + +/obj/item/ammo_box/magazine/toy/m762/riot + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot diff --git a/code/modules/projectiles/boxes_magazines/external_mag.dm b/code/modules/projectiles/boxes_magazines/external_mag.dm deleted file mode 100644 index b7b3a3e286..0000000000 --- a/code/modules/projectiles/boxes_magazines/external_mag.dm +++ /dev/null @@ -1,340 +0,0 @@ - -///////////EXTERNAL MAGAZINES//////////////// - -/obj/item/ammo_box/magazine/m10mm - name = "pistol magazine (10mm)" - desc = "A gun magazine." - icon_state = "9x19p" - ammo_type = /obj/item/ammo_casing/c10mm - caliber = "10mm" - max_ammo = 8 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/m10mm/rifle - name = "rifle magazine (10mm)" - desc = "A well-worn magazine fitted for the surplus rifle." - icon_state = "75-8" - ammo_type = /obj/item/ammo_casing/c10mm - caliber = "10mm" - max_ammo = 10 - -/obj/item/ammo_box/magazine/m10mm/rifle/update_icon() - if(ammo_count()) - icon_state = "75-8" - else - icon_state = "75-0" - - -/obj/item/ammo_box/magazine/m10mm/fire - name = "pistol magazine (10mm incendiary)" - icon_state = "9x19pI" - desc = "A gun magazine. Loaded with rounds which ignite the target." - ammo_type = /obj/item/ammo_casing/c10mm/fire - -/obj/item/ammo_box/magazine/m10mm/hp - name = "pistol magazine (10mm HP)" - icon_state = "9x19pH" - desc= "A gun magazine. Loaded with hollow-point rounds, extremely effective against unarmored targets, but nearly useless against protective clothing." - ammo_type = /obj/item/ammo_casing/c10mm/hp - -/obj/item/ammo_box/magazine/m10mm/ap - name = "pistol magazine (10mm AP)" - icon_state = "9x19pA" - desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets." - ammo_type = /obj/item/ammo_casing/c10mm/ap - -/obj/item/ammo_box/magazine/m45 - name = "handgun magazine (.45)" - icon_state = "45-8" - ammo_type = /obj/item/ammo_casing/c45 - caliber = ".45" - max_ammo = 8 - -/obj/item/ammo_box/magazine/m45/update_icon() - ..() - icon_state = "45-[ammo_count() ? "8" : "0"]" - -/obj/item/ammo_box/magazine/wt550m9 - name = "wt550 magazine (4.6x30mm)" - icon_state = "46x30mmt-20" - ammo_type = /obj/item/ammo_casing/c46x30mm - caliber = "4.6x30mm" - max_ammo = 20 - -/obj/item/ammo_box/magazine/wt550m9/update_icon() - ..() - icon_state = "46x30mmt-[round(ammo_count(),4)]" - -/obj/item/ammo_box/magazine/wt550m9/wtap - name = "wt550 magazine (Armour Piercing 4.6x30mm)" - icon_state = "46x30mmtA-20" - ammo_type = /obj/item/ammo_casing/c46x30mm/ap - -/obj/item/ammo_box/magazine/wt550m9/wtap/update_icon() - ..() - icon_state = "46x30mmtA-[round(ammo_count(),4)]" - -/obj/item/ammo_box/magazine/wt550m9/wtic - name = "wt550 magazine (Incindiary 4.6x30mm)" - icon_state = "46x30mmtI-20" - ammo_type = /obj/item/ammo_casing/c46x30mm/inc - -/obj/item/ammo_box/magazine/wt550m9/wtic/update_icon() - ..() - icon_state = "46x30mmtI-[round(ammo_count(),4)]" - -/obj/item/ammo_box/magazine/uzim9mm - name = "uzi magazine (9mm)" - icon_state = "uzi9mm-32" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = "9mm" - max_ammo = 32 - -/obj/item/ammo_box/magazine/uzim9mm/update_icon() - ..() - icon_state = "uzi9mm-[round(ammo_count(),4)]" - -/obj/item/ammo_box/magazine/smgm9mm - name = "SMG magazine (9mm)" - icon_state = "smg9mm-42" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = "9mm" - max_ammo = 21 - -/obj/item/ammo_box/magazine/smgm9mm/update_icon() - ..() - icon_state = "smg9mm-[ammo_count() ? "42" : "0"]" - -/obj/item/ammo_box/magazine/smgm9mm/ap - name = "SMG magazine (Armour Piercing 9mm)" - ammo_type = /obj/item/ammo_casing/c9mm/ap - -/obj/item/ammo_box/magazine/smgm9mm/fire - name = "SMG Magazine (Incindiary 9mm)" - ammo_type = /obj/item/ammo_casing/c9mm/inc - -/obj/item/ammo_box/magazine/pistolm9mm - name = "pistol magazine (9mm)" - icon_state = "9x19p-8" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = "9mm" - max_ammo = 15 - -/obj/item/ammo_box/magazine/pistolm9mm/update_icon() - ..() - icon_state = "9x19p-[ammo_count() ? "8" : "0"]" - -/obj/item/ammo_box/magazine/smgm45 - name = "SMG magazine (.45)" - icon_state = "c20r45-24" - ammo_type = /obj/item/ammo_casing/c45/nostamina - caliber = ".45" - max_ammo = 24 - -/obj/item/ammo_box/magazine/smgm45/update_icon() - ..() - icon_state = "c20r45-[round(ammo_count(),2)]" - -/obj/item/ammo_box/magazine/tommygunm45 - name = "drum magazine (.45)" - icon_state = "drum45" - ammo_type = /obj/item/ammo_casing/c45 - caliber = ".45" - max_ammo = 50 - -/obj/item/ammo_box/magazine/m50 - name = "handgun magazine (.50ae)" - icon_state = "50ae" - ammo_type = /obj/item/ammo_casing/a50AE - caliber = ".50" - max_ammo = 7 - multiple_sprites = 1 - -/obj/item/ammo_box/magazine/m75 - name = "specialized magazine (.75)" - icon_state = "75" - ammo_type = /obj/item/ammo_casing/caseless/a75 - caliber = "75" - multiple_sprites = 2 - max_ammo = 8 - -/obj/item/ammo_box/magazine/m556 - name = "toploader magazine (5.56mm)" - icon_state = "5.56m" - ammo_type = /obj/item/ammo_casing/a556 - caliber = "a556" - max_ammo = 30 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/m12g - name = "shotgun magazine (12g taser slugs)" - desc = "A drum magazine." - icon_state = "m12gs" - ammo_type = /obj/item/ammo_casing/shotgun/stunslug - caliber = "shotgun" - max_ammo = 8 - -/obj/item/ammo_box/magazine/m12g/update_icon() - ..() - icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]" - -/obj/item/ammo_box/magazine/m12g/buckshot - name = "shotgun magazine (12g buckshot slugs)" - icon_state = "m12gb" - ammo_type = /obj/item/ammo_casing/shotgun/buckshot - -/obj/item/ammo_box/magazine/m12g/slug - name = "shotgun magazine (12g slugs)" - icon_state = "m12gb" - ammo_type = /obj/item/ammo_casing/shotgun - -/obj/item/ammo_box/magazine/m12g/dragon - name = "shotgun magazine (12g dragon's breath)" - icon_state = "m12gf" - ammo_type = /obj/item/ammo_casing/shotgun/dragonsbreath - -/obj/item/ammo_box/magazine/m12g/bioterror - name = "shotgun magazine (12g bioterror)" - icon_state = "m12gt" - ammo_type = /obj/item/ammo_casing/shotgun/dart/bioterror - -/obj/item/ammo_box/magazine/m12g/meteor - name = "shotgun magazine (12g meteor slugs)" - icon_state = "m12gbc" - ammo_type = /obj/item/ammo_casing/shotgun/meteorslug - - -//// SNIPER MAGAZINES - -/obj/item/ammo_box/magazine/sniper_rounds - name = "sniper rounds (.50)" - icon_state = ".50mag" - ammo_type = /obj/item/ammo_casing/p50 - max_ammo = 6 - caliber = ".50" - -/obj/item/ammo_box/magazine/sniper_rounds/update_icon() - if(ammo_count()) - icon_state = "[initial(icon_state)]-ammo" - else - icon_state = "[initial(icon_state)]" - -/obj/item/ammo_box/magazine/sniper_rounds/soporific - name = "sniper rounds (Zzzzz)" - desc = "Soporific sniper rounds, designed for happy days and dead quiet nights..." - icon_state = "soporific" - ammo_type = /obj/item/ammo_casing/p50/soporific - max_ammo = 3 - caliber = ".50" - -/obj/item/ammo_box/magazine/sniper_rounds/penetrator - name = "sniper rounds (penetrator)" - desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it." - ammo_type = /obj/item/ammo_casing/p50/penetrator - max_ammo = 5 - -//// SAW MAGAZINES - -/obj/item/ammo_box/magazine/mm195x129 - name = "box magazine (1.95x129mm)" - icon_state = "a762-50" - ammo_type = /obj/item/ammo_casing/mm195x129 - caliber = "mm195129" - max_ammo = 50 - -/obj/item/ammo_box/magazine/mm195x129/hollow - name = "box magazine (Hollow-Point 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/hollow - -/obj/item/ammo_box/magazine/mm195x129/ap - name = "box magazine (Armor Penetrating 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/ap - -/obj/item/ammo_box/magazine/mm195x129/incen - name = "box magazine (Incendiary 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/incen - -/obj/item/ammo_box/magazine/mm195x129/update_icon() - ..() - icon_state = "a762-[round(ammo_count(),10)]" - - - - -////TOY GUN MAGAZINES - -/obj/item/ammo_box/magazine/toy - name = "foam force META magazine" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart - caliber = "foam_force" - -/obj/item/ammo_box/magazine/toy/smg - name = "foam force SMG magazine" - icon_state = "smg9mm-42" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart - max_ammo = 20 - -/obj/item/ammo_box/magazine/toy/smg/update_icon() - ..() - if(ammo_count()) - icon_state = "smg9mm-42" - else - icon_state = "smg9mm-0" - -/obj/item/ammo_box/magazine/toy/smg/riot - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot - -/obj/item/ammo_box/magazine/toy/pistol - name = "foam force pistol magazine" - icon_state = "9x19p" - max_ammo = 8 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/toy/pistol/riot - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot - -/obj/item/ammo_box/magazine/toy/smgm45 - name = "donksoft SMG magazine" - caliber = "foam_force" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart - max_ammo = 20 - -/obj/item/ammo_box/magazine/toy/smgm45/update_icon() - ..() - icon_state = "c20r45-[round(ammo_count(),2)]" - -/obj/item/ammo_box/magazine/toy/smgm45/riot - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot - -/obj/item/ammo_box/magazine/toy/m762 - name = "donksoft box magazine" - caliber = "foam_force" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart - max_ammo = 50 - -/obj/item/ammo_box/magazine/toy/m762/update_icon() - ..() - icon_state = "a762-[round(ammo_count(),10)]" - -/obj/item/ammo_box/magazine/toy/m762/riot - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot - - - - -//// RECHARGEABLE MAGAZINES - -/obj/item/ammo_box/magazine/recharge - name = "power pack" - desc = "A rechargeable, detachable battery that serves as a magazine for laser rifles." - icon_state = "oldrifle-20" - ammo_type = /obj/item/ammo_casing/caseless/laser - caliber = "laser" - max_ammo = 20 - -/obj/item/ammo_box/magazine/recharge/update_icon() - desc = "[initial(desc)] It has [stored_ammo.len] shot\s left." - icon_state = "oldrifle-[round(ammo_count(),4)]" - -/obj/item/ammo_box/magazine/recharge/attack_self() //No popping out the "bullets" - return diff --git a/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm b/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm new file mode 100644 index 0000000000..bbfc79471c --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm @@ -0,0 +1,47 @@ +/obj/item/ammo_box/magazine/internal/cylinder + name = "revolver cylinder" + ammo_type = /obj/item/ammo_casing/a357 + caliber = "357" + max_ammo = 7 + +/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = 1) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in stored_ammo) + if(bullet && (bullet.BB || countempties)) + boolets++ + + return boolets + +/obj/item/ammo_box/magazine/internal/cylinder/get_round(keep = 0) + rotate() + + var/b = stored_ammo[1] + if(!keep) + stored_ammo[1] = null + + return b + +/obj/item/ammo_box/magazine/internal/cylinder/proc/rotate() + var/b = stored_ammo[1] + stored_ammo.Cut(1,2) + stored_ammo.Insert(0, b) + +/obj/item/ammo_box/magazine/internal/cylinder/proc/spin() + for(var/i in 1 to rand(0, max_ammo*2)) + rotate() + +/obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = 0) + if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + return FALSE + + for(var/i in 1 to stored_ammo.len) + var/obj/item/ammo_casing/bullet = stored_ammo[i] + if(!bullet || !bullet.BB) // found a spent ammo + stored_ammo[i] = R + R.forceMove(src) + + if(bullet) + bullet.forceMove(drop_location()) + return TRUE + + return FALSE diff --git a/code/modules/projectiles/boxes_magazines/internal/_internal.dm b/code/modules/projectiles/boxes_magazines/internal/_internal.dm new file mode 100644 index 0000000000..e21cb5ce61 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/_internal.dm @@ -0,0 +1,7 @@ +/obj/item/ammo_box/magazine/internal + desc = "Oh god, this shouldn't be here" + flags_1 = CONDUCT_1|ABSTRACT_1 + +//internals magazines are accessible, so replace spent ammo if full when trying to put a live one in +/obj/item/ammo_box/magazine/internal/give_round(obj/item/ammo_casing/R) + return ..(R,1) diff --git a/code/modules/projectiles/boxes_magazines/internal/grenade.dm b/code/modules/projectiles/boxes_magazines/internal/grenade.dm new file mode 100644 index 0000000000..12325a0299 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/grenade.dm @@ -0,0 +1,17 @@ +/obj/item/ammo_box/magazine/internal/cylinder/grenademulti + name = "grenade launcher internal magazine" + ammo_type = /obj/item/ammo_casing/a40mm + caliber = "40mm" + max_ammo = 6 + +/obj/item/ammo_box/magazine/internal/grenadelauncher + name = "grenade launcher internal magazine" + ammo_type = /obj/item/ammo_casing/a40mm + caliber = "40mm" + max_ammo = 1 + +/obj/item/ammo_box/magazine/internal/rocketlauncher + name = "grenade launcher internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/a84mm + caliber = "84mm" + max_ammo = 1 diff --git a/code/modules/projectiles/boxes_magazines/internal/misc.dm b/code/modules/projectiles/boxes_magazines/internal/misc.dm new file mode 100644 index 0000000000..aab0643cbc --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/misc.dm @@ -0,0 +1,11 @@ +/obj/item/ammo_box/magazine/internal/speargun + name = "speargun internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/magspear + caliber = "speargun" + max_ammo = 1 + +/obj/item/ammo_box/magazine/internal/minigun + name = "gatling gun fusion core" + ammo_type = /obj/item/ammo_casing/caseless/laser/gatling + caliber = "gatling" + max_ammo = 5000 diff --git a/code/modules/projectiles/boxes_magazines/internal/revolver.dm b/code/modules/projectiles/boxes_magazines/internal/revolver.dm new file mode 100644 index 0000000000..976f80f437 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/revolver.dm @@ -0,0 +1,22 @@ +/obj/item/ammo_box/magazine/internal/cylinder/rev38 + name = "detective revolver cylinder" + ammo_type = /obj/item/ammo_casing/c38 + caliber = "38" + max_ammo = 6 + +/obj/item/ammo_box/magazine/internal/cylinder/rev762 + name = "nagant revolver cylinder" + ammo_type = /obj/item/ammo_casing/n762 + caliber = "n762" + max_ammo = 7 + +/obj/item/ammo_box/magazine/internal/cylinder/rus357 + name = "russian revolver cylinder" + ammo_type = /obj/item/ammo_casing/a357 + caliber = "357" + max_ammo = 6 + multiload = 0 + +/obj/item/ammo_box/magazine/internal/rus357/Initialize() + stored_ammo += new ammo_type(src) + . = ..() diff --git a/code/modules/projectiles/boxes_magazines/internal/rifle.dm b/code/modules/projectiles/boxes_magazines/internal/rifle.dm new file mode 100644 index 0000000000..ef83e96b1c --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/rifle.dm @@ -0,0 +1,15 @@ +/obj/item/ammo_box/magazine/internal/boltaction + name = "bolt action rifle internal magazine" + desc = "Oh god, this shouldn't be here" + ammo_type = /obj/item/ammo_casing/a762 + caliber = "a762" + max_ammo = 5 + multiload = 1 + +/obj/item/ammo_box/magazine/internal/boltaction/enchanted + max_ammo = 1 + ammo_type = /obj/item/ammo_casing/a762/enchanted + +/obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage + ammo_type = /obj/item/ammo_casing/magic/arcane_barrage + diff --git a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm new file mode 100644 index 0000000000..3bd277da31 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm @@ -0,0 +1,48 @@ +/obj/item/ammo_box/magazine/internal/shot + name = "shotgun internal magazine" + ammo_type = /obj/item/ammo_casing/shotgun/beanbag + caliber = "shotgun" + max_ammo = 4 + multiload = 0 + +/obj/item/ammo_box/magazine/internal/shot/ammo_count(countempties = 1) + if (!countempties) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in stored_ammo) + if(bullet.BB) + boolets++ + return boolets + else + return ..() + +/obj/item/ammo_box/magazine/internal/shot/tube + name = "dual feed shotgun internal tube" + ammo_type = /obj/item/ammo_casing/shotgun/rubbershot + max_ammo = 4 + +/obj/item/ammo_box/magazine/internal/shot/lethal + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + +/obj/item/ammo_box/magazine/internal/shot/com + name = "combat shotgun internal magazine" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + max_ammo = 6 + +/obj/item/ammo_box/magazine/internal/shot/com/compact + name = "compact combat shotgun internal magazine" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + max_ammo = 4 + +/obj/item/ammo_box/magazine/internal/shot/dual + name = "double-barrel shotgun internal magazine" + max_ammo = 2 + +/obj/item/ammo_box/magazine/internal/shot/improvised + name = "improvised shotgun internal magazine" + ammo_type = /obj/item/ammo_casing/shotgun/improvised + max_ammo = 1 + +/obj/item/ammo_box/magazine/internal/shot/riot + name = "riot shotgun internal magazine" + ammo_type = /obj/item/ammo_casing/shotgun/rubbershot + max_ammo = 6 diff --git a/code/modules/projectiles/boxes_magazines/internal/toy.dm b/code/modules/projectiles/boxes_magazines/internal/toy.dm new file mode 100644 index 0000000000..f2bb0dbf08 --- /dev/null +++ b/code/modules/projectiles/boxes_magazines/internal/toy.dm @@ -0,0 +1,7 @@ +/obj/item/ammo_box/magazine/internal/shot/toy + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + caliber = "foam_force" + max_ammo = 4 + +/obj/item/ammo_box/magazine/internal/shot/toy/crossbow + max_ammo = 5 diff --git a/code/modules/projectiles/boxes_magazines/internal_mag.dm b/code/modules/projectiles/boxes_magazines/internal_mag.dm deleted file mode 100644 index b26d30c389..0000000000 --- a/code/modules/projectiles/boxes_magazines/internal_mag.dm +++ /dev/null @@ -1,191 +0,0 @@ -////////////////INTERNAL MAGAZINES////////////////////// - -/obj/item/ammo_box/magazine/internal - desc = "Oh god, this shouldn't be here" - flags_1 = CONDUCT_1|ABSTRACT_1 - -//internals magazines are accessible, so replace spent ammo if full when trying to put a live one in -/obj/item/ammo_box/magazine/internal/give_round(obj/item/ammo_casing/R) - return ..(R,1) - - - -// Revolver internal mags -/obj/item/ammo_box/magazine/internal/cylinder - name = "revolver cylinder" - ammo_type = /obj/item/ammo_casing/a357 - caliber = "357" - max_ammo = 7 - -/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = 1) - var/boolets = 0 - for(var/obj/item/ammo_casing/bullet in stored_ammo) - if(bullet && (bullet.BB || countempties)) - boolets++ - - return boolets - -/obj/item/ammo_box/magazine/internal/cylinder/get_round(keep = 0) - rotate() - - var/b = stored_ammo[1] - if(!keep) - stored_ammo[1] = null - - return b - -/obj/item/ammo_box/magazine/internal/cylinder/proc/rotate() - var/b = stored_ammo[1] - stored_ammo.Cut(1,2) - stored_ammo.Insert(0, b) - -/obj/item/ammo_box/magazine/internal/cylinder/proc/spin() - for(var/i in 1 to rand(0, max_ammo*2)) - rotate() - - -/obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = 0) - if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) - return 0 - - for(var/i in 1 to stored_ammo.len) - var/obj/item/ammo_casing/bullet = stored_ammo[i] - if(!bullet || !bullet.BB) // found a spent ammo - stored_ammo[i] = R - R.forceMove(src) - - if(bullet) - bullet.forceMove(drop_location()) - return 1 - - return 0 - -/obj/item/ammo_box/magazine/internal/cylinder/rev38 - name = "detective revolver cylinder" - ammo_type = /obj/item/ammo_casing/c38 - caliber = "38" - max_ammo = 6 - -/obj/item/ammo_box/magazine/internal/cylinder/grenademulti - name = "grenade launcher internal magazine" - ammo_type = /obj/item/ammo_casing/a40mm - caliber = "40mm" - max_ammo = 6 - -/obj/item/ammo_box/magazine/internal/cylinder/rev762 - name = "nagant revolver cylinder" - ammo_type = /obj/item/ammo_casing/n762 - caliber = "n762" - max_ammo = 7 - -// Shotgun internal mags -/obj/item/ammo_box/magazine/internal/shot - name = "shotgun internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/beanbag - caliber = "shotgun" - max_ammo = 4 - multiload = 0 - -/obj/item/ammo_box/magazine/internal/shot/ammo_count(countempties = 1) - if (!countempties) - var/boolets = 0 - for(var/obj/item/ammo_casing/bullet in stored_ammo) - if(bullet.BB) - boolets++ - return boolets - else - return ..() - - -/obj/item/ammo_box/magazine/internal/shot/tube - name = "dual feed shotgun internal tube" - ammo_type = /obj/item/ammo_casing/shotgun/rubbershot - max_ammo = 4 - -/obj/item/ammo_box/magazine/internal/shot/lethal - ammo_type = /obj/item/ammo_casing/shotgun/buckshot - -/obj/item/ammo_box/magazine/internal/shot/com - name = "combat shotgun internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/buckshot - max_ammo = 6 - -/obj/item/ammo_box/magazine/internal/shot/com/compact - name = "compact combat shotgun internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/buckshot - max_ammo = 4 - -/obj/item/ammo_box/magazine/internal/shot/dual - name = "double-barrel shotgun internal magazine" - max_ammo = 2 - -/obj/item/ammo_box/magazine/internal/shot/improvised - name = "improvised shotgun internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/improvised - max_ammo = 1 - -/obj/item/ammo_box/magazine/internal/shot/riot - name = "riot shotgun internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/rubbershot - max_ammo = 6 - - - - -/obj/item/ammo_box/magazine/internal/grenadelauncher - name = "grenade launcher internal magazine" - ammo_type = /obj/item/ammo_casing/a40mm - caliber = "40mm" - max_ammo = 1 - -/obj/item/ammo_box/magazine/internal/rocketlauncher - name = "grenade launcher internal magazine" - ammo_type = /obj/item/ammo_casing/caseless/a84mm - caliber = "84mm" - max_ammo = 1 - -/obj/item/ammo_box/magazine/internal/speargun - name = "speargun internal magazine" - ammo_type = /obj/item/ammo_casing/caseless/magspear - caliber = "speargun" - max_ammo = 1 - -/obj/item/ammo_box/magazine/internal/cylinder/rus357 - name = "russian revolver cylinder" - ammo_type = /obj/item/ammo_casing/a357 - caliber = "357" - max_ammo = 6 - multiload = 0 - -/obj/item/ammo_box/magazine/internal/rus357/Initialize() - stored_ammo += new ammo_type(src) - . = ..() - -/obj/item/ammo_box/magazine/internal/boltaction - name = "bolt action rifle internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = /obj/item/ammo_casing/a762 - caliber = "a762" - max_ammo = 5 - multiload = 1 - -/obj/item/ammo_box/magazine/internal/boltaction/enchanted - max_ammo = 1 - ammo_type = /obj/item/ammo_casing/a762/enchanted - -/obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage - ammo_type = /obj/item/ammo_casing/magic/arcane_barrage - -/obj/item/ammo_box/magazine/internal/shot/toy - ammo_type = /obj/item/ammo_casing/caseless/foam_dart - caliber = "foam_force" - max_ammo = 4 - -/obj/item/ammo_box/magazine/internal/shot/toy/crossbow - max_ammo = 5 - -/obj/item/ammo_box/magazine/internal/minigun - name = "gatling gun fusion core" - ammo_type = /obj/item/ammo_casing/caseless/laser/gatling - caliber = "gatling" - max_ammo = 5000 diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/energy/mounted.dm similarity index 96% rename from code/modules/projectiles/guns/mounted.dm rename to code/modules/projectiles/guns/energy/mounted.dm index 5893c2a107..79226689de 100644 --- a/code/modules/projectiles/guns/mounted.dm +++ b/code/modules/projectiles/guns/energy/mounted.dm @@ -1,26 +1,26 @@ -/obj/item/gun/energy/e_gun/advtaser/mounted - name = "mounted taser" - desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots." - icon = 'icons/obj/items_cyborg.dmi' - icon_state = "taser" - item_state = "armcannonstun4" - force = 5 - selfcharge = 1 - can_flashlight = 0 - trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead - -/obj/item/gun/energy/e_gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow... - ..() - -/obj/item/gun/energy/laser/mounted - name = "mounted laser" - desc = "An arm mounted cannon that fires lethal lasers." - icon = 'icons/obj/items_cyborg.dmi' - icon_state = "laser" - item_state = "armcannonlase" - force = 5 - selfcharge = 1 - trigger_guard = TRIGGER_GUARD_ALLOW_ALL - -/obj/item/gun/energy/laser/mounted/dropped() - ..() +/obj/item/gun/energy/e_gun/advtaser/mounted + name = "mounted taser" + desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots." + icon = 'icons/obj/items_cyborg.dmi' + icon_state = "taser" + item_state = "armcannonstun4" + force = 5 + selfcharge = 1 + can_flashlight = 0 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead + +/obj/item/gun/energy/e_gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow... + ..() + +/obj/item/gun/energy/laser/mounted + name = "mounted laser" + desc = "An arm mounted cannon that fires lethal lasers." + icon = 'icons/obj/items_cyborg.dmi' + icon_state = "laser" + item_state = "armcannonlase" + force = 5 + selfcharge = 1 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL + +/obj/item/gun/energy/laser/mounted/dropped() + ..() diff --git a/code/modules/projectiles/guns/energy/plasma.dm b/code/modules/projectiles/guns/energy/plasma_cit.dm similarity index 100% rename from code/modules/projectiles/guns/energy/plasma.dm rename to code/modules/projectiles/guns/energy/plasma_cit.dm diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm similarity index 97% rename from code/modules/projectiles/guns/beam_rifle.dm rename to code/modules/projectiles/guns/misc/beam_rifle.dm index a2365dfc13..59465eb989 100644 --- a/code/modules/projectiles/guns/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -1,590 +1,590 @@ - -#define ZOOM_LOCK_AUTOZOOM_FREEMOVE 0 -#define ZOOM_LOCK_AUTOZOOM_ANGLELOCK 1 -#define ZOOM_LOCK_CENTER_VIEW 2 -#define ZOOM_LOCK_OFF 3 - -#define AUTOZOOM_PIXEL_STEP_FACTOR 48 - -#define AIMING_BEAM_ANGLE_CHANGE_THRESHOLD 0.1 - -/obj/item/gun/energy/beam_rifle - name = "particle acceleration rifle" - desc = "An energy-based anti material marksman rifle that uses highly charged particle beams moving at extreme velocities to decimate whatever is unfortunate enough to be targetted by one. \ - Hold down left click while scoped to aim, when weapon is fully aimed (Tracer goes from red to green as it charges), release to fire. Moving while aiming or \ - changing where you're pointing at while aiming will delay the aiming process depending on how much you changed." - icon = 'icons/obj/guns/energy.dmi' - icon_state = "esniper" - item_state = "esniper" - fire_sound = 'sound/weapons/beam_sniper.ogg' - slot_flags = SLOT_BACK - force = 15 - materials = list() - recoil = 4 - ammo_x_offset = 3 - ammo_y_offset = 3 - modifystate = FALSE - weapon_weight = WEAPON_HEAVY - w_class = WEIGHT_CLASS_BULKY - ammo_type = list(/obj/item/ammo_casing/energy/beam_rifle/hitscan) - cell_type = /obj/item/stock_parts/cell/beam_rifle - canMouseDown = TRUE - pin = null - var/aiming = FALSE - var/aiming_time = 12 - var/aiming_time_fire_threshold = 5 - var/aiming_time_left = 12 - var/aiming_time_increase_user_movement = 3 - var/scoped_slow = 1 - var/aiming_time_increase_angle_multiplier = 0.3 - var/last_process = 0 - - var/lastangle = 0 - var/aiming_lastangle = 0 - var/mob/current_user = null - var/list/obj/effect/projectile/tracer/current_tracers - - var/structure_piercing = 2 //Amount * 2. For some reason structures aren't respecting this unless you have it doubled. Probably with the objects in question's Bump() code instead of this but I'll deal with this later. - var/structure_bleed_coeff = 0.7 - var/wall_pierce_amount = 0 - var/wall_devastate = 0 - var/aoe_structure_range = 1 - var/aoe_structure_damage = 50 - var/aoe_fire_range = 2 - var/aoe_fire_chance = 40 - var/aoe_mob_range = 1 - var/aoe_mob_damage = 30 - var/impact_structure_damage = 60 - var/projectile_damage = 30 - var/projectile_stun = 0 - var/projectile_setting_pierce = TRUE - var/delay = 65 - var/lastfire = 0 - - //ZOOMING - var/zoom_current_view_increase = 0 - var/zoom_target_view_increase = 10 - var/zooming = FALSE - var/zoom_lock = ZOOM_LOCK_OFF - var/zooming_angle - var/current_zoom_x = 0 - var/current_zoom_y = 0 - var/zoom_animating = 0 - - var/static/image/charged_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_charged") - var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty") - - var/datum/action/item_action/zoom_lock_action/zoom_lock_action - var/datum/component/mobhook - -/obj/item/gun/energy/beam_rifle/debug - delay = 0 - cell_type = /obj/item/stock_parts/cell/infinite - aiming_time = 0 - recoil = 0 - pin = /obj/item/device/firing_pin - -/obj/item/gun/energy/beam_rifle/equipped(mob/user) - set_user(user) - . = ..() - -/obj/item/gun/energy/beam_rifle/pickup(mob/user) - set_user(user) - . = ..() - -/obj/item/gun/energy/beam_rifle/dropped(mob/user) - set_user() - . = ..() - -/obj/item/gun/energy/beam_rifle/ui_action_click(owner, action) - if(istype(action, /datum/action/item_action/zoom_lock_action)) - zoom_lock++ - if(zoom_lock > 3) - zoom_lock = 0 - switch(zoom_lock) - if(ZOOM_LOCK_AUTOZOOM_FREEMOVE) - to_chat(owner, "You switch [src]'s zooming processor to free directional.") - if(ZOOM_LOCK_AUTOZOOM_ANGLELOCK) - to_chat(owner, "You switch [src]'s zooming processor to locked directional.") - if(ZOOM_LOCK_CENTER_VIEW) - to_chat(owner, "You switch [src]'s zooming processor to center mode.") - if(ZOOM_LOCK_OFF) - to_chat(owner, "You disable [src]'s zooming system.") - reset_zooming() - -/obj/item/gun/energy/beam_rifle/proc/smooth_zooming(delay_override = null) - if(!check_user() || !zooming || zoom_lock == ZOOM_LOCK_OFF || zoom_lock == ZOOM_LOCK_CENTER_VIEW) - return - if(zoom_animating && delay_override != 0) - return smooth_zooming(zoom_animating + delay_override) //Automatically compensate for ongoing zooming actions. - var/total_time = SSfastprocess.wait - if(delay_override) - total_time = delay_override - zoom_animating = total_time - animate(current_user.client, pixel_x = current_zoom_x, pixel_y = current_zoom_y , total_time, SINE_EASING, ANIMATION_PARALLEL) - zoom_animating = 0 - -/obj/item/gun/energy/beam_rifle/proc/set_autozoom_pixel_offsets_immediate(current_angle) - if(zoom_lock == ZOOM_LOCK_CENTER_VIEW || zoom_lock == ZOOM_LOCK_OFF) - return - current_zoom_x = sin(current_angle) + sin(current_angle) * AUTOZOOM_PIXEL_STEP_FACTOR * zoom_current_view_increase - current_zoom_y = cos(current_angle) + cos(current_angle) * AUTOZOOM_PIXEL_STEP_FACTOR * zoom_current_view_increase - -/obj/item/gun/energy/beam_rifle/proc/handle_zooming() - if(!zooming || !check_user()) - return - current_user.client.change_view(world.view + zoom_target_view_increase) - zoom_current_view_increase = zoom_target_view_increase - set_autozoom_pixel_offsets_immediate(zooming_angle) - smooth_zooming() - -/obj/item/gun/energy/beam_rifle/proc/start_zooming() - if(zoom_lock == ZOOM_LOCK_OFF) - return - zooming = TRUE - -/obj/item/gun/energy/beam_rifle/proc/stop_zooming(mob/user) - if(zooming) - zooming = FALSE - reset_zooming(user) - -/obj/item/gun/energy/beam_rifle/proc/reset_zooming(mob/user) - if(!user) - user = current_user - if(!user || !user.client) - return FALSE - zoom_animating = 0 - animate(user.client, pixel_x = 0, pixel_y = 0, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) - zoom_current_view_increase = 0 - user.client.change_view(CONFIG_GET(string/default_view)) - zooming_angle = 0 - current_zoom_x = 0 - current_zoom_y = 0 - -/obj/item/gun/energy/beam_rifle/update_icon() - cut_overlays() - var/obj/item/ammo_casing/energy/primary_ammo = ammo_type[1] - if(cell.charge > primary_ammo.e_cost) - add_overlay(charged_overlay) - else - add_overlay(drained_overlay) - -/obj/item/gun/energy/beam_rifle/attack_self(mob/user) - projectile_setting_pierce = !projectile_setting_pierce - to_chat(user, "You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.") - aiming_beam() - -/obj/item/gun/energy/beam_rifle/proc/update_slowdown() - if(aiming) - slowdown = scoped_slow - else - slowdown = initial(slowdown) - -/obj/item/gun/energy/beam_rifle/Initialize() - . = ..() - current_tracers = list() - START_PROCESSING(SSprojectiles, src) - zoom_lock_action = new(src) - -/obj/item/gun/energy/beam_rifle/Destroy() - STOP_PROCESSING(SSfastprocess, src) - set_user(null) - QDEL_LIST(current_tracers) - QDEL_NULL(mobhook) - return ..() - -/obj/item/gun/energy/beam_rifle/emp_act(severity) - chambered = null - recharge_newshot() - -/obj/item/gun/energy/beam_rifle/proc/aiming_beam(force_update = FALSE) - var/diff = abs(aiming_lastangle - lastangle) - check_user() - if(diff < AIMING_BEAM_ANGLE_CHANGE_THRESHOLD && !force_update) - return - aiming_lastangle = lastangle - var/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/P = new - P.gun = src - P.wall_pierce_amount = wall_pierce_amount - P.structure_pierce_amount = structure_piercing - P.do_pierce = projectile_setting_pierce - if(aiming_time) - var/percent = ((100/aiming_time)*aiming_time_left) - P.color = rgb(255 * percent,255 * ((100 - percent) / 100),0) - else - P.color = rgb(0, 255, 0) - var/turf/curloc = get_turf(src) - var/turf/targloc = get_turf(current_user.client.mouseObject) - if(!istype(targloc)) - if(!istype(curloc)) - return - targloc = get_turf_in_angle(lastangle, curloc, 10) - P.preparePixelProjectile(targloc, current_user, current_user.client.mouseParams, 0) - P.fire(lastangle) - -/obj/item/gun/energy/beam_rifle/process() - if(!aiming) - last_process = world.time - return - check_user() - handle_zooming() - aiming_time_left = max(0, aiming_time_left - (world.time - last_process)) - aiming_beam(TRUE) - last_process = world.time - -/obj/item/gun/energy/beam_rifle/proc/check_user(automatic_cleanup = TRUE) - if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it! - if(automatic_cleanup) - stop_aiming() - set_user(null) - return FALSE - return TRUE - -/obj/item/gun/energy/beam_rifle/proc/process_aim() - if(istype(current_user) && current_user.client && current_user.client.mouseParams) - var/angle = mouse_angle_from_client(current_user.client) - switch(angle) - if(316 to 360) - current_user.setDir(NORTH) - if(0 to 45) - current_user.setDir(NORTH) - if(46 to 135) - current_user.setDir(EAST) - if(136 to 225) - current_user.setDir(SOUTH) - if(226 to 315) - current_user.setDir(WEST) - var/difference = abs(lastangle - angle) - if(difference > 350) //Too lazy to properly math, detects 360 --> 0 changes. - difference = (lastangle > 350? ((360 - lastangle) + angle) : ((360 - angle) + lastangle)) - delay_penalty(difference * aiming_time_increase_angle_multiplier) - lastangle = angle - -/obj/item/gun/energy/beam_rifle/proc/on_mob_move() - check_user() - if(aiming) - delay_penalty(aiming_time_increase_user_movement) - process_aim() - aiming_beam(TRUE) - -/obj/item/gun/energy/beam_rifle/proc/start_aiming() - aiming_time_left = aiming_time - aiming = TRUE - process_aim() - aiming_beam(TRUE) - zooming_angle = lastangle - start_zooming() - -/obj/item/gun/energy/beam_rifle/proc/stop_aiming(mob/user) - set waitfor = FALSE - aiming_time_left = aiming_time - aiming = FALSE - QDEL_LIST(current_tracers) - stop_zooming(user) - -/obj/item/gun/energy/beam_rifle/proc/set_user(mob/user) - if(user == current_user) - return - stop_aiming(current_user) - QDEL_NULL(mobhook) - if(istype(current_user)) - LAZYREMOVE(current_user.mousemove_intercept_objects, src) - current_user = null - if(istype(user)) - current_user = user - LAZYADD(current_user.mousemove_intercept_objects, src) - mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED), CALLBACK(src, .proc/on_mob_move)) - -/obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) - if(aiming) - process_aim() - aiming_beam() - if(zoom_lock == ZOOM_LOCK_AUTOZOOM_FREEMOVE) - zooming_angle = lastangle - set_autozoom_pixel_offsets_immediate(zooming_angle) - smooth_zooming(2) - return ..() - -/obj/item/gun/energy/beam_rifle/onMouseDown(object, location, params, mob/mob) - if(istype(mob)) - set_user(mob) - if(istype(object, /obj/screen) && !istype(object, /obj/screen/click_catcher)) - return - if((object in mob.contents) || (object == mob)) - return - start_aiming() - return ..() - -/obj/item/gun/energy/beam_rifle/onMouseUp(object, location, params, mob/M) - if(istype(object, /obj/screen) && !istype(object, /obj/screen/click_catcher)) - return - process_aim() - if(aiming_time_left <= aiming_time_fire_threshold && check_user()) - sync_ammo() - afterattack(M.client.mouseObject, M, FALSE, M.client.mouseParams, passthrough = TRUE) - stop_aiming() - QDEL_LIST(current_tracers) - return ..() - -/obj/item/gun/energy/beam_rifle/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE) - if(flag) //It's adjacent, is the user, or is on the user's person - if(target in user.contents) //can't shoot stuff inside us. - return - if(!ismob(target) || user.a_intent == INTENT_HARM) //melee attack - return - if(target == user && user.zone_selected != "mouth") //so we can't shoot ourselves (unless mouth selected) - return - if(!passthrough && (aiming_time > aiming_time_fire_threshold)) - return - if(lastfire > world.time + delay) - return - lastfire = world.time - . = ..() - stop_aiming() - -/obj/item/gun/energy/beam_rifle/proc/sync_ammo() - for(var/obj/item/ammo_casing/energy/beam_rifle/AC in contents) - AC.sync_stats() - -/obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount) - aiming_time_left = CLAMP(aiming_time_left + amount, 0, aiming_time) - -/obj/item/ammo_casing/energy/beam_rifle - name = "particle acceleration lens" - desc = "Don't look into barrel!" - var/wall_pierce_amount = 0 - var/wall_devastate = 0 - var/aoe_structure_range = 1 - var/aoe_structure_damage = 30 - var/aoe_fire_range = 2 - var/aoe_fire_chance = 66 - var/aoe_mob_range = 1 - var/aoe_mob_damage = 20 - var/impact_structure_damage = 50 - var/projectile_damage = 40 - var/projectile_stun = 0 - var/structure_piercing = 2 - var/structure_bleed_coeff = 0.7 - var/do_pierce = TRUE - var/obj/item/gun/energy/beam_rifle/host - -/obj/item/ammo_casing/energy/beam_rifle/proc/sync_stats() - var/obj/item/gun/energy/beam_rifle/BR = loc - if(!istype(BR)) - stack_trace("Beam rifle syncing error") - host = BR - do_pierce = BR.projectile_setting_pierce - wall_pierce_amount = BR.wall_pierce_amount - wall_devastate = BR.wall_devastate - aoe_structure_range = BR.aoe_structure_range - aoe_structure_damage = BR.aoe_structure_damage - aoe_fire_range = BR.aoe_fire_range - aoe_fire_chance = BR.aoe_fire_chance - aoe_mob_range = BR.aoe_mob_range - aoe_mob_damage = BR.aoe_mob_damage - impact_structure_damage = BR.impact_structure_damage - projectile_damage = BR.projectile_damage - projectile_stun = BR.projectile_stun - delay = BR.delay - structure_piercing = BR.structure_piercing - structure_bleed_coeff = BR.structure_bleed_coeff - -/obj/item/ammo_casing/energy/beam_rifle/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") - . = ..() - var/obj/item/projectile/beam/beam_rifle/hitscan/HS_BB = BB - if(!istype(HS_BB)) - return - HS_BB.impact_direct_damage = projectile_damage - HS_BB.stun = projectile_stun - HS_BB.impact_structure_damage = impact_structure_damage - HS_BB.aoe_mob_damage = aoe_mob_damage - HS_BB.aoe_mob_range = CLAMP(aoe_mob_range, 0, 15) //Badmin safety lock - HS_BB.aoe_fire_chance = aoe_fire_chance - HS_BB.aoe_fire_range = aoe_fire_range - HS_BB.aoe_structure_damage = aoe_structure_damage - HS_BB.aoe_structure_range = CLAMP(aoe_structure_range, 0, 15) //Badmin safety lock - HS_BB.wall_devastate = wall_devastate - HS_BB.wall_pierce_amount = wall_pierce_amount - HS_BB.structure_pierce_amount = structure_piercing - HS_BB.structure_bleed_coeff = structure_bleed_coeff - HS_BB.do_pierce = do_pierce - HS_BB.gun = host - -/obj/item/ammo_casing/energy/beam_rifle/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread) - var/turf/curloc = get_turf(user) - if(!istype(curloc) || !BB) - return FALSE - var/obj/item/gun/energy/beam_rifle/gun = loc - if(!targloc && gun) - targloc = get_turf_in_angle(gun.lastangle, curloc, 10) - else if(!targloc) - return FALSE - var/firing_dir - if(BB.firer) - firing_dir = BB.firer.dir - if(!BB.suppressed && firing_effect_type) - new firing_effect_type(get_turf(src), firing_dir) - BB.preparePixelProjectile(target, user, params, spread) - BB.fire(gun? gun.lastangle : null, null) - BB = null - return TRUE - -/obj/item/ammo_casing/energy/beam_rifle/hitscan - projectile_type = /obj/item/projectile/beam/beam_rifle/hitscan - select_name = "beam" - e_cost = 5000 - fire_sound = 'sound/weapons/beam_sniper.ogg' - -/obj/item/projectile/beam/beam_rifle - name = "particle beam" - icon = "" - hitsound = 'sound/effects/explosion3.ogg' - damage = 0 //Handled manually. - damage_type = BURN - flag = "energy" - range = 150 - jitter = 10 - var/obj/item/gun/energy/beam_rifle/gun - var/structure_pierce_amount = 0 //All set to 0 so the gun can manually set them during firing. - var/structure_bleed_coeff = 0 - var/structure_pierce = 0 - var/do_pierce = TRUE - var/wall_pierce_amount = 0 - var/wall_pierce = 0 - var/wall_devastate = 0 - var/aoe_structure_range = 0 - var/aoe_structure_damage = 0 - var/aoe_fire_range = 0 - var/aoe_fire_chance = 0 - var/aoe_mob_range = 0 - var/aoe_mob_damage = 0 - var/impact_structure_damage = 0 - var/impact_direct_damage = 0 - var/turf/cached - var/list/pierced = list() - -/obj/item/projectile/beam/beam_rifle/proc/AOE(turf/epicenter) - set waitfor = FALSE - if(!epicenter) - return - new /obj/effect/temp_visual/explosion/fast(epicenter) - for(var/mob/living/L in range(aoe_mob_range, epicenter)) //handle aoe mob damage - L.adjustFireLoss(aoe_mob_damage) - to_chat(L, "\The [src] sears you!") - for(var/turf/T in range(aoe_fire_range, epicenter)) //handle aoe fire - if(prob(aoe_fire_chance)) - new /obj/effect/hotspot(T) - for(var/obj/O in range(aoe_structure_range, epicenter)) - if(!isitem(O)) - if(O.level == 1) //Please don't break underfloor items! - continue - O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, "laser", FALSE) - -/obj/item/projectile/beam/beam_rifle/proc/check_pierce(atom/target) - if(!do_pierce) - return FALSE - if(pierced[target]) //we already pierced them go away - return TRUE - if(isclosedturf(target)) - if(wall_pierce++ < wall_pierce_amount) - if(prob(wall_devastate)) - if(iswallturf(target)) - var/turf/closed/wall/W = target - W.dismantle_wall(TRUE, TRUE) - else - target.ex_act(EXPLODE_HEAVY) - return TRUE - if(ismovableatom(target)) - var/atom/movable/AM = target - if(AM.density && !AM.CanPass(src, get_turf(target)) && !ismob(AM)) - if(structure_pierce < structure_pierce_amount) - if(isobj(AM)) - var/obj/O = AM - O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) - pierced[AM] = TRUE - structure_pierce++ - return TRUE - return FALSE - -/obj/item/projectile/beam/beam_rifle/proc/get_damage_coeff(atom/target) - if(istype(target, /obj/machinery/door)) - return 0.4 - if(istype(target, /obj/structure/window)) - return 0.5 - return 1 - -/obj/item/projectile/beam/beam_rifle/proc/handle_impact(atom/target) - if(isobj(target)) - var/obj/O = target - O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, "laser", FALSE) - if(isliving(target)) - var/mob/living/L = target - L.adjustFireLoss(impact_direct_damage) - L.emote("scream") - -/obj/item/projectile/beam/beam_rifle/proc/handle_hit(atom/target) - set waitfor = FALSE - if(!cached && !QDELETED(target)) - cached = get_turf(target) - if(nodamage) - return FALSE - playsound(cached, 'sound/effects/explosion3.ogg', 100, 1) - AOE(cached) - if(!QDELETED(target)) - handle_impact(target) - -/obj/item/projectile/beam/beam_rifle/Collide(atom/target) - if(check_pierce(target)) - permutated += target - trajectory_ignore_forcemove = TRUE - forceMove(target) - trajectory_ignore_forcemove = FALSE - return FALSE - if(!QDELETED(target)) - cached = get_turf(target) - . = ..() - -/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE) - if(!QDELETED(target)) - cached = get_turf(target) - handle_hit(target) - . = ..() - -/obj/item/projectile/beam/beam_rifle/hitscan - icon_state = "" - hitscan = TRUE - tracer_type = /obj/effect/projectile/tracer/tracer/beam_rifle - var/constant_tracer = FALSE - -/obj/item/projectile/beam/beam_rifle/hitscan/generate_hitscan_tracers(cleanup = TRUE, duration = 5, impacting = TRUE, highlander) - set waitfor = FALSE - if(isnull(highlander)) - highlander = constant_tracer - if(highlander && istype(gun)) - QDEL_LIST(gun.current_tracers) - for(var/datum/point/p in beam_segments) - gun.current_tracers += generate_tracer_between_points(p, beam_segments[p], tracer_type, color, 0) - else - for(var/datum/point/p in beam_segments) - generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration) - if(cleanup) - QDEL_LIST(beam_segments) - beam_segments = null - QDEL_NULL(beam_index) - -/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam - tracer_type = /obj/effect/projectile/tracer/tracer/aiming - name = "aiming beam" - hitsound = null - hitsound_wall = null - nodamage = TRUE - damage = 0 - constant_tracer = TRUE - -/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target) - qdel(src) - return FALSE - -/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit() - qdel(src) - return FALSE + +#define ZOOM_LOCK_AUTOZOOM_FREEMOVE 0 +#define ZOOM_LOCK_AUTOZOOM_ANGLELOCK 1 +#define ZOOM_LOCK_CENTER_VIEW 2 +#define ZOOM_LOCK_OFF 3 + +#define AUTOZOOM_PIXEL_STEP_FACTOR 48 + +#define AIMING_BEAM_ANGLE_CHANGE_THRESHOLD 0.1 + +/obj/item/gun/energy/beam_rifle + name = "particle acceleration rifle" + desc = "An energy-based anti material marksman rifle that uses highly charged particle beams moving at extreme velocities to decimate whatever is unfortunate enough to be targetted by one. \ + Hold down left click while scoped to aim, when weapon is fully aimed (Tracer goes from red to green as it charges), release to fire. Moving while aiming or \ + changing where you're pointing at while aiming will delay the aiming process depending on how much you changed." + icon = 'icons/obj/guns/energy.dmi' + icon_state = "esniper" + item_state = "esniper" + fire_sound = 'sound/weapons/beam_sniper.ogg' + slot_flags = SLOT_BACK + force = 15 + materials = list() + recoil = 4 + ammo_x_offset = 3 + ammo_y_offset = 3 + modifystate = FALSE + weapon_weight = WEAPON_HEAVY + w_class = WEIGHT_CLASS_BULKY + ammo_type = list(/obj/item/ammo_casing/energy/beam_rifle/hitscan) + cell_type = /obj/item/stock_parts/cell/beam_rifle + canMouseDown = TRUE + pin = null + var/aiming = FALSE + var/aiming_time = 12 + var/aiming_time_fire_threshold = 5 + var/aiming_time_left = 12 + var/aiming_time_increase_user_movement = 3 + var/scoped_slow = 1 + var/aiming_time_increase_angle_multiplier = 0.3 + var/last_process = 0 + + var/lastangle = 0 + var/aiming_lastangle = 0 + var/mob/current_user = null + var/list/obj/effect/projectile/tracer/current_tracers + + var/structure_piercing = 2 //Amount * 2. For some reason structures aren't respecting this unless you have it doubled. Probably with the objects in question's Bump() code instead of this but I'll deal with this later. + var/structure_bleed_coeff = 0.7 + var/wall_pierce_amount = 0 + var/wall_devastate = 0 + var/aoe_structure_range = 1 + var/aoe_structure_damage = 50 + var/aoe_fire_range = 2 + var/aoe_fire_chance = 40 + var/aoe_mob_range = 1 + var/aoe_mob_damage = 30 + var/impact_structure_damage = 60 + var/projectile_damage = 30 + var/projectile_stun = 0 + var/projectile_setting_pierce = TRUE + var/delay = 65 + var/lastfire = 0 + + //ZOOMING + var/zoom_current_view_increase = 0 + var/zoom_target_view_increase = 10 + var/zooming = FALSE + var/zoom_lock = ZOOM_LOCK_OFF + var/zooming_angle + var/current_zoom_x = 0 + var/current_zoom_y = 0 + var/zoom_animating = 0 + + var/static/image/charged_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_charged") + var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty") + + var/datum/action/item_action/zoom_lock_action/zoom_lock_action + var/datum/component/mobhook + +/obj/item/gun/energy/beam_rifle/debug + delay = 0 + cell_type = /obj/item/stock_parts/cell/infinite + aiming_time = 0 + recoil = 0 + pin = /obj/item/device/firing_pin + +/obj/item/gun/energy/beam_rifle/equipped(mob/user) + set_user(user) + . = ..() + +/obj/item/gun/energy/beam_rifle/pickup(mob/user) + set_user(user) + . = ..() + +/obj/item/gun/energy/beam_rifle/dropped(mob/user) + set_user() + . = ..() + +/obj/item/gun/energy/beam_rifle/ui_action_click(owner, action) + if(istype(action, /datum/action/item_action/zoom_lock_action)) + zoom_lock++ + if(zoom_lock > 3) + zoom_lock = 0 + switch(zoom_lock) + if(ZOOM_LOCK_AUTOZOOM_FREEMOVE) + to_chat(owner, "You switch [src]'s zooming processor to free directional.") + if(ZOOM_LOCK_AUTOZOOM_ANGLELOCK) + to_chat(owner, "You switch [src]'s zooming processor to locked directional.") + if(ZOOM_LOCK_CENTER_VIEW) + to_chat(owner, "You switch [src]'s zooming processor to center mode.") + if(ZOOM_LOCK_OFF) + to_chat(owner, "You disable [src]'s zooming system.") + reset_zooming() + +/obj/item/gun/energy/beam_rifle/proc/smooth_zooming(delay_override = null) + if(!check_user() || !zooming || zoom_lock == ZOOM_LOCK_OFF || zoom_lock == ZOOM_LOCK_CENTER_VIEW) + return + if(zoom_animating && delay_override != 0) + return smooth_zooming(zoom_animating + delay_override) //Automatically compensate for ongoing zooming actions. + var/total_time = SSfastprocess.wait + if(delay_override) + total_time = delay_override + zoom_animating = total_time + animate(current_user.client, pixel_x = current_zoom_x, pixel_y = current_zoom_y , total_time, SINE_EASING, ANIMATION_PARALLEL) + zoom_animating = 0 + +/obj/item/gun/energy/beam_rifle/proc/set_autozoom_pixel_offsets_immediate(current_angle) + if(zoom_lock == ZOOM_LOCK_CENTER_VIEW || zoom_lock == ZOOM_LOCK_OFF) + return + current_zoom_x = sin(current_angle) + sin(current_angle) * AUTOZOOM_PIXEL_STEP_FACTOR * zoom_current_view_increase + current_zoom_y = cos(current_angle) + cos(current_angle) * AUTOZOOM_PIXEL_STEP_FACTOR * zoom_current_view_increase + +/obj/item/gun/energy/beam_rifle/proc/handle_zooming() + if(!zooming || !check_user()) + return + current_user.client.change_view(world.view + zoom_target_view_increase) + zoom_current_view_increase = zoom_target_view_increase + set_autozoom_pixel_offsets_immediate(zooming_angle) + smooth_zooming() + +/obj/item/gun/energy/beam_rifle/proc/start_zooming() + if(zoom_lock == ZOOM_LOCK_OFF) + return + zooming = TRUE + +/obj/item/gun/energy/beam_rifle/proc/stop_zooming(mob/user) + if(zooming) + zooming = FALSE + reset_zooming(user) + +/obj/item/gun/energy/beam_rifle/proc/reset_zooming(mob/user) + if(!user) + user = current_user + if(!user || !user.client) + return FALSE + zoom_animating = 0 + animate(user.client, pixel_x = 0, pixel_y = 0, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) + zoom_current_view_increase = 0 + user.client.change_view(CONFIG_GET(string/default_view)) + zooming_angle = 0 + current_zoom_x = 0 + current_zoom_y = 0 + +/obj/item/gun/energy/beam_rifle/update_icon() + cut_overlays() + var/obj/item/ammo_casing/energy/primary_ammo = ammo_type[1] + if(cell.charge > primary_ammo.e_cost) + add_overlay(charged_overlay) + else + add_overlay(drained_overlay) + +/obj/item/gun/energy/beam_rifle/attack_self(mob/user) + projectile_setting_pierce = !projectile_setting_pierce + to_chat(user, "You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.") + aiming_beam() + +/obj/item/gun/energy/beam_rifle/proc/update_slowdown() + if(aiming) + slowdown = scoped_slow + else + slowdown = initial(slowdown) + +/obj/item/gun/energy/beam_rifle/Initialize() + . = ..() + current_tracers = list() + START_PROCESSING(SSprojectiles, src) + zoom_lock_action = new(src) + +/obj/item/gun/energy/beam_rifle/Destroy() + STOP_PROCESSING(SSfastprocess, src) + set_user(null) + QDEL_LIST(current_tracers) + QDEL_NULL(mobhook) + return ..() + +/obj/item/gun/energy/beam_rifle/emp_act(severity) + chambered = null + recharge_newshot() + +/obj/item/gun/energy/beam_rifle/proc/aiming_beam(force_update = FALSE) + var/diff = abs(aiming_lastangle - lastangle) + check_user() + if(diff < AIMING_BEAM_ANGLE_CHANGE_THRESHOLD && !force_update) + return + aiming_lastangle = lastangle + var/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/P = new + P.gun = src + P.wall_pierce_amount = wall_pierce_amount + P.structure_pierce_amount = structure_piercing + P.do_pierce = projectile_setting_pierce + if(aiming_time) + var/percent = ((100/aiming_time)*aiming_time_left) + P.color = rgb(255 * percent,255 * ((100 - percent) / 100),0) + else + P.color = rgb(0, 255, 0) + var/turf/curloc = get_turf(src) + var/turf/targloc = get_turf(current_user.client.mouseObject) + if(!istype(targloc)) + if(!istype(curloc)) + return + targloc = get_turf_in_angle(lastangle, curloc, 10) + P.preparePixelProjectile(targloc, current_user, current_user.client.mouseParams, 0) + P.fire(lastangle) + +/obj/item/gun/energy/beam_rifle/process() + if(!aiming) + last_process = world.time + return + check_user() + handle_zooming() + aiming_time_left = max(0, aiming_time_left - (world.time - last_process)) + aiming_beam(TRUE) + last_process = world.time + +/obj/item/gun/energy/beam_rifle/proc/check_user(automatic_cleanup = TRUE) + if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it! + if(automatic_cleanup) + stop_aiming() + set_user(null) + return FALSE + return TRUE + +/obj/item/gun/energy/beam_rifle/proc/process_aim() + if(istype(current_user) && current_user.client && current_user.client.mouseParams) + var/angle = mouse_angle_from_client(current_user.client) + switch(angle) + if(316 to 360) + current_user.setDir(NORTH) + if(0 to 45) + current_user.setDir(NORTH) + if(46 to 135) + current_user.setDir(EAST) + if(136 to 225) + current_user.setDir(SOUTH) + if(226 to 315) + current_user.setDir(WEST) + var/difference = abs(lastangle - angle) + if(difference > 350) //Too lazy to properly math, detects 360 --> 0 changes. + difference = (lastangle > 350? ((360 - lastangle) + angle) : ((360 - angle) + lastangle)) + delay_penalty(difference * aiming_time_increase_angle_multiplier) + lastangle = angle + +/obj/item/gun/energy/beam_rifle/proc/on_mob_move() + check_user() + if(aiming) + delay_penalty(aiming_time_increase_user_movement) + process_aim() + aiming_beam(TRUE) + +/obj/item/gun/energy/beam_rifle/proc/start_aiming() + aiming_time_left = aiming_time + aiming = TRUE + process_aim() + aiming_beam(TRUE) + zooming_angle = lastangle + start_zooming() + +/obj/item/gun/energy/beam_rifle/proc/stop_aiming(mob/user) + set waitfor = FALSE + aiming_time_left = aiming_time + aiming = FALSE + QDEL_LIST(current_tracers) + stop_zooming(user) + +/obj/item/gun/energy/beam_rifle/proc/set_user(mob/user) + if(user == current_user) + return + stop_aiming(current_user) + QDEL_NULL(mobhook) + if(istype(current_user)) + LAZYREMOVE(current_user.mousemove_intercept_objects, src) + current_user = null + if(istype(user)) + current_user = user + LAZYADD(current_user.mousemove_intercept_objects, src) + mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED), CALLBACK(src, .proc/on_mob_move)) + +/obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) + if(aiming) + process_aim() + aiming_beam() + if(zoom_lock == ZOOM_LOCK_AUTOZOOM_FREEMOVE) + zooming_angle = lastangle + set_autozoom_pixel_offsets_immediate(zooming_angle) + smooth_zooming(2) + return ..() + +/obj/item/gun/energy/beam_rifle/onMouseDown(object, location, params, mob/mob) + if(istype(mob)) + set_user(mob) + if(istype(object, /obj/screen) && !istype(object, /obj/screen/click_catcher)) + return + if((object in mob.contents) || (object == mob)) + return + start_aiming() + return ..() + +/obj/item/gun/energy/beam_rifle/onMouseUp(object, location, params, mob/M) + if(istype(object, /obj/screen) && !istype(object, /obj/screen/click_catcher)) + return + process_aim() + if(aiming_time_left <= aiming_time_fire_threshold && check_user()) + sync_ammo() + afterattack(M.client.mouseObject, M, FALSE, M.client.mouseParams, passthrough = TRUE) + stop_aiming() + QDEL_LIST(current_tracers) + return ..() + +/obj/item/gun/energy/beam_rifle/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE) + if(flag) //It's adjacent, is the user, or is on the user's person + if(target in user.contents) //can't shoot stuff inside us. + return + if(!ismob(target) || user.a_intent == INTENT_HARM) //melee attack + return + if(target == user && user.zone_selected != "mouth") //so we can't shoot ourselves (unless mouth selected) + return + if(!passthrough && (aiming_time > aiming_time_fire_threshold)) + return + if(lastfire > world.time + delay) + return + lastfire = world.time + . = ..() + stop_aiming() + +/obj/item/gun/energy/beam_rifle/proc/sync_ammo() + for(var/obj/item/ammo_casing/energy/beam_rifle/AC in contents) + AC.sync_stats() + +/obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount) + aiming_time_left = CLAMP(aiming_time_left + amount, 0, aiming_time) + +/obj/item/ammo_casing/energy/beam_rifle + name = "particle acceleration lens" + desc = "Don't look into barrel!" + var/wall_pierce_amount = 0 + var/wall_devastate = 0 + var/aoe_structure_range = 1 + var/aoe_structure_damage = 30 + var/aoe_fire_range = 2 + var/aoe_fire_chance = 66 + var/aoe_mob_range = 1 + var/aoe_mob_damage = 20 + var/impact_structure_damage = 50 + var/projectile_damage = 40 + var/projectile_stun = 0 + var/structure_piercing = 2 + var/structure_bleed_coeff = 0.7 + var/do_pierce = TRUE + var/obj/item/gun/energy/beam_rifle/host + +/obj/item/ammo_casing/energy/beam_rifle/proc/sync_stats() + var/obj/item/gun/energy/beam_rifle/BR = loc + if(!istype(BR)) + stack_trace("Beam rifle syncing error") + host = BR + do_pierce = BR.projectile_setting_pierce + wall_pierce_amount = BR.wall_pierce_amount + wall_devastate = BR.wall_devastate + aoe_structure_range = BR.aoe_structure_range + aoe_structure_damage = BR.aoe_structure_damage + aoe_fire_range = BR.aoe_fire_range + aoe_fire_chance = BR.aoe_fire_chance + aoe_mob_range = BR.aoe_mob_range + aoe_mob_damage = BR.aoe_mob_damage + impact_structure_damage = BR.impact_structure_damage + projectile_damage = BR.projectile_damage + projectile_stun = BR.projectile_stun + delay = BR.delay + structure_piercing = BR.structure_piercing + structure_bleed_coeff = BR.structure_bleed_coeff + +/obj/item/ammo_casing/energy/beam_rifle/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + . = ..() + var/obj/item/projectile/beam/beam_rifle/hitscan/HS_BB = BB + if(!istype(HS_BB)) + return + HS_BB.impact_direct_damage = projectile_damage + HS_BB.stun = projectile_stun + HS_BB.impact_structure_damage = impact_structure_damage + HS_BB.aoe_mob_damage = aoe_mob_damage + HS_BB.aoe_mob_range = CLAMP(aoe_mob_range, 0, 15) //Badmin safety lock + HS_BB.aoe_fire_chance = aoe_fire_chance + HS_BB.aoe_fire_range = aoe_fire_range + HS_BB.aoe_structure_damage = aoe_structure_damage + HS_BB.aoe_structure_range = CLAMP(aoe_structure_range, 0, 15) //Badmin safety lock + HS_BB.wall_devastate = wall_devastate + HS_BB.wall_pierce_amount = wall_pierce_amount + HS_BB.structure_pierce_amount = structure_piercing + HS_BB.structure_bleed_coeff = structure_bleed_coeff + HS_BB.do_pierce = do_pierce + HS_BB.gun = host + +/obj/item/ammo_casing/energy/beam_rifle/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread) + var/turf/curloc = get_turf(user) + if(!istype(curloc) || !BB) + return FALSE + var/obj/item/gun/energy/beam_rifle/gun = loc + if(!targloc && gun) + targloc = get_turf_in_angle(gun.lastangle, curloc, 10) + else if(!targloc) + return FALSE + var/firing_dir + if(BB.firer) + firing_dir = BB.firer.dir + if(!BB.suppressed && firing_effect_type) + new firing_effect_type(get_turf(src), firing_dir) + BB.preparePixelProjectile(target, user, params, spread) + BB.fire(gun? gun.lastangle : null, null) + BB = null + return TRUE + +/obj/item/ammo_casing/energy/beam_rifle/hitscan + projectile_type = /obj/item/projectile/beam/beam_rifle/hitscan + select_name = "beam" + e_cost = 5000 + fire_sound = 'sound/weapons/beam_sniper.ogg' + +/obj/item/projectile/beam/beam_rifle + name = "particle beam" + icon = "" + hitsound = 'sound/effects/explosion3.ogg' + damage = 0 //Handled manually. + damage_type = BURN + flag = "energy" + range = 150 + jitter = 10 + var/obj/item/gun/energy/beam_rifle/gun + var/structure_pierce_amount = 0 //All set to 0 so the gun can manually set them during firing. + var/structure_bleed_coeff = 0 + var/structure_pierce = 0 + var/do_pierce = TRUE + var/wall_pierce_amount = 0 + var/wall_pierce = 0 + var/wall_devastate = 0 + var/aoe_structure_range = 0 + var/aoe_structure_damage = 0 + var/aoe_fire_range = 0 + var/aoe_fire_chance = 0 + var/aoe_mob_range = 0 + var/aoe_mob_damage = 0 + var/impact_structure_damage = 0 + var/impact_direct_damage = 0 + var/turf/cached + var/list/pierced = list() + +/obj/item/projectile/beam/beam_rifle/proc/AOE(turf/epicenter) + set waitfor = FALSE + if(!epicenter) + return + new /obj/effect/temp_visual/explosion/fast(epicenter) + for(var/mob/living/L in range(aoe_mob_range, epicenter)) //handle aoe mob damage + L.adjustFireLoss(aoe_mob_damage) + to_chat(L, "\The [src] sears you!") + for(var/turf/T in range(aoe_fire_range, epicenter)) //handle aoe fire + if(prob(aoe_fire_chance)) + new /obj/effect/hotspot(T) + for(var/obj/O in range(aoe_structure_range, epicenter)) + if(!isitem(O)) + if(O.level == 1) //Please don't break underfloor items! + continue + O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, "laser", FALSE) + +/obj/item/projectile/beam/beam_rifle/proc/check_pierce(atom/target) + if(!do_pierce) + return FALSE + if(pierced[target]) //we already pierced them go away + return TRUE + if(isclosedturf(target)) + if(wall_pierce++ < wall_pierce_amount) + if(prob(wall_devastate)) + if(iswallturf(target)) + var/turf/closed/wall/W = target + W.dismantle_wall(TRUE, TRUE) + else + target.ex_act(EXPLODE_HEAVY) + return TRUE + if(ismovableatom(target)) + var/atom/movable/AM = target + if(AM.density && !AM.CanPass(src, get_turf(target)) && !ismob(AM)) + if(structure_pierce < structure_pierce_amount) + if(isobj(AM)) + var/obj/O = AM + O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) + pierced[AM] = TRUE + structure_pierce++ + return TRUE + return FALSE + +/obj/item/projectile/beam/beam_rifle/proc/get_damage_coeff(atom/target) + if(istype(target, /obj/machinery/door)) + return 0.4 + if(istype(target, /obj/structure/window)) + return 0.5 + return 1 + +/obj/item/projectile/beam/beam_rifle/proc/handle_impact(atom/target) + if(isobj(target)) + var/obj/O = target + O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, "laser", FALSE) + if(isliving(target)) + var/mob/living/L = target + L.adjustFireLoss(impact_direct_damage) + L.emote("scream") + +/obj/item/projectile/beam/beam_rifle/proc/handle_hit(atom/target) + set waitfor = FALSE + if(!cached && !QDELETED(target)) + cached = get_turf(target) + if(nodamage) + return FALSE + playsound(cached, 'sound/effects/explosion3.ogg', 100, 1) + AOE(cached) + if(!QDELETED(target)) + handle_impact(target) + +/obj/item/projectile/beam/beam_rifle/Collide(atom/target) + if(check_pierce(target)) + permutated += target + trajectory_ignore_forcemove = TRUE + forceMove(target) + trajectory_ignore_forcemove = FALSE + return FALSE + if(!QDELETED(target)) + cached = get_turf(target) + . = ..() + +/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE) + if(!QDELETED(target)) + cached = get_turf(target) + handle_hit(target) + . = ..() + +/obj/item/projectile/beam/beam_rifle/hitscan + icon_state = "" + hitscan = TRUE + tracer_type = /obj/effect/projectile/tracer/tracer/beam_rifle + var/constant_tracer = FALSE + +/obj/item/projectile/beam/beam_rifle/hitscan/generate_hitscan_tracers(cleanup = TRUE, duration = 5, impacting = TRUE, highlander) + set waitfor = FALSE + if(isnull(highlander)) + highlander = constant_tracer + if(highlander && istype(gun)) + QDEL_LIST(gun.current_tracers) + for(var/datum/point/p in beam_segments) + gun.current_tracers += generate_tracer_between_points(p, beam_segments[p], tracer_type, color, 0) + else + for(var/datum/point/p in beam_segments) + generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration) + if(cleanup) + QDEL_LIST(beam_segments) + beam_segments = null + QDEL_NULL(beam_index) + +/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam + tracer_type = /obj/effect/projectile/tracer/tracer/aiming + name = "aiming beam" + hitsound = null + hitsound_wall = null + nodamage = TRUE + damage = 0 + constant_tracer = TRUE + +/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target) + qdel(src) + return FALSE + +/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit() + qdel(src) + return FALSE diff --git a/code/modules/projectiles/guns/chem_gun.dm b/code/modules/projectiles/guns/misc/chem_gun.dm similarity index 95% rename from code/modules/projectiles/guns/chem_gun.dm rename to code/modules/projectiles/guns/misc/chem_gun.dm index b928abafef..17e3bd1876 100644 --- a/code/modules/projectiles/guns/chem_gun.dm +++ b/code/modules/projectiles/guns/misc/chem_gun.dm @@ -1,47 +1,47 @@ -//his isn't a subtype of the syringe gun because the syringegun subtype is made to hold syringes -//this is meant to hold reagents/obj/item/gun/syringe -/obj/item/gun/chem - name = "reagent gun" - desc = "A Nanotrasen syringe gun, modified to automatically synthesise chemical darts, and instead hold reagents." - icon_state = "chemgun" - item_state = "chemgun" - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 3 - throw_range = 7 - force = 4 - materials = list(MAT_METAL=2000) - clumsy_check = FALSE - fire_sound = 'sound/items/syringeproj.ogg' - container_type = OPENCONTAINER - var/time_per_syringe = 250 - var/syringes_left = 4 - var/max_syringes = 4 - var/last_synth = 0 - -/obj/item/gun/chem/Initialize() - . = ..() - chambered = new /obj/item/ammo_casing/chemgun(src) - START_PROCESSING(SSobj, src) - create_reagents(100) - -/obj/item/gun/chem/Destroy() - . = ..() - STOP_PROCESSING(SSobj, src) - -/obj/item/gun/chem/can_shoot() - return syringes_left - -/obj/item/gun/chem/process_chamber() - if(chambered && !chambered.BB && syringes_left) - chambered.newshot() - -/obj/item/gun/chem/process() - if(syringes_left >= max_syringes) - return - if(world.time < last_synth+time_per_syringe) - return - to_chat(loc, "You hear a click as [src] synthesizes a new dart.") - syringes_left++ - if(chambered && !chambered.BB) - chambered.newshot() +//his isn't a subtype of the syringe gun because the syringegun subtype is made to hold syringes +//this is meant to hold reagents/obj/item/gun/syringe +/obj/item/gun/chem + name = "reagent gun" + desc = "A Nanotrasen syringe gun, modified to automatically synthesise chemical darts, and instead hold reagents." + icon_state = "chemgun" + item_state = "chemgun" + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 3 + throw_range = 7 + force = 4 + materials = list(MAT_METAL=2000) + clumsy_check = FALSE + fire_sound = 'sound/items/syringeproj.ogg' + container_type = OPENCONTAINER + var/time_per_syringe = 250 + var/syringes_left = 4 + var/max_syringes = 4 + var/last_synth = 0 + +/obj/item/gun/chem/Initialize() + . = ..() + chambered = new /obj/item/ammo_casing/chemgun(src) + START_PROCESSING(SSobj, src) + create_reagents(100) + +/obj/item/gun/chem/Destroy() + . = ..() + STOP_PROCESSING(SSobj, src) + +/obj/item/gun/chem/can_shoot() + return syringes_left + +/obj/item/gun/chem/process_chamber() + if(chambered && !chambered.BB && syringes_left) + chambered.newshot() + +/obj/item/gun/chem/process() + if(syringes_left >= max_syringes) + return + if(world.time < last_synth+time_per_syringe) + return + to_chat(loc, "You hear a click as [src] synthesizes a new dart.") + syringes_left++ + if(chambered && !chambered.BB) + chambered.newshot() last_synth = world.time \ No newline at end of file diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/misc/grenade_launcher.dm similarity index 97% rename from code/modules/projectiles/guns/grenade_launcher.dm rename to code/modules/projectiles/guns/misc/grenade_launcher.dm index 771c0091e3..e57d77bdf9 100644 --- a/code/modules/projectiles/guns/grenade_launcher.dm +++ b/code/modules/projectiles/guns/misc/grenade_launcher.dm @@ -1,52 +1,52 @@ -/obj/item/gun/grenadelauncher - name = "grenade launcher" - desc = "A terrible, terrible thing. It's really awful!" - icon = 'icons/obj/guns/projectile.dmi' - icon_state = "riotgun" - item_state = "riotgun" - w_class = WEIGHT_CLASS_BULKY - throw_speed = 2 - throw_range = 7 - force = 5 - var/list/grenades = new/list() - var/max_grenades = 3 - materials = list(MAT_METAL=2000) - -/obj/item/gun/grenadelauncher/examine(mob/user) - ..() - to_chat(user, "[grenades.len] / [max_grenades] grenades loaded.") - -/obj/item/gun/grenadelauncher/attackby(obj/item/I, mob/user, params) - - if((istype(I, /obj/item/grenade))) - if(grenades.len < max_grenades) - if(!user.transferItemToLoc(I, src)) - return - grenades += I - to_chat(user, "You put the grenade in the grenade launcher.") - to_chat(user, "[grenades.len] / [max_grenades] Grenades.") - else - to_chat(usr, "The grenade launcher cannot hold more grenades.") - -/obj/item/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) - if(target == user) - return - - if(grenades.len) - fire_grenade(target,user) - else - to_chat(user, "The grenade launcher is empty.") - -/obj/item/gun/grenadelauncher/proc/fire_grenade(atom/target, mob/user) - user.visible_message("[user] fired a grenade!", \ - "You fire the grenade launcher!") - var/obj/item/grenade/F = grenades[1] //Now with less copypasta! - grenades -= F - F.forceMove(user.loc) - F.throw_at(target, 30, 2, user) - message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") - log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") - F.active = 1 - F.icon_state = initial(F.icon_state) + "_active" - playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - addtimer(CALLBACK(F, /obj/item/grenade.proc/prime), 15) +/obj/item/gun/grenadelauncher + name = "grenade launcher" + desc = "A terrible, terrible thing. It's really awful!" + icon = 'icons/obj/guns/projectile.dmi' + icon_state = "riotgun" + item_state = "riotgun" + w_class = WEIGHT_CLASS_BULKY + throw_speed = 2 + throw_range = 7 + force = 5 + var/list/grenades = new/list() + var/max_grenades = 3 + materials = list(MAT_METAL=2000) + +/obj/item/gun/grenadelauncher/examine(mob/user) + ..() + to_chat(user, "[grenades.len] / [max_grenades] grenades loaded.") + +/obj/item/gun/grenadelauncher/attackby(obj/item/I, mob/user, params) + + if((istype(I, /obj/item/grenade))) + if(grenades.len < max_grenades) + if(!user.transferItemToLoc(I, src)) + return + grenades += I + to_chat(user, "You put the grenade in the grenade launcher.") + to_chat(user, "[grenades.len] / [max_grenades] Grenades.") + else + to_chat(usr, "The grenade launcher cannot hold more grenades.") + +/obj/item/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) + if(target == user) + return + + if(grenades.len) + fire_grenade(target,user) + else + to_chat(user, "The grenade launcher is empty.") + +/obj/item/gun/grenadelauncher/proc/fire_grenade(atom/target, mob/user) + user.visible_message("[user] fired a grenade!", \ + "You fire the grenade launcher!") + var/obj/item/grenade/F = grenades[1] //Now with less copypasta! + grenades -= F + F.forceMove(user.loc) + F.throw_at(target, 30, 2, user) + message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") + log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") + F.active = 1 + F.icon_state = initial(F.icon_state) + "_active" + playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) + addtimer(CALLBACK(F, /obj/item/grenade.proc/prime), 15) diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/misc/medbeam.dm similarity index 96% rename from code/modules/projectiles/guns/medbeam.dm rename to code/modules/projectiles/guns/misc/medbeam.dm index 79cafe0dd6..8fb07c32e3 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/misc/medbeam.dm @@ -1,133 +1,133 @@ -/obj/item/gun/medbeam - name = "Medical Beamgun" - desc = "Don't cross the streams!" - icon = 'icons/obj/chronos.dmi' - icon_state = "chronogun" - item_state = "chronogun" - w_class = WEIGHT_CLASS_NORMAL - - var/mob/living/current_target - var/last_check = 0 - var/check_delay = 10 //Check los as often as possible, max resolution is SSobj tick though - var/max_range = 8 - var/active = 0 - var/datum/beam/current_beam = null - var/mounted = 0 //Denotes if this is a handheld or mounted version - - weapon_weight = WEAPON_MEDIUM - -/obj/item/gun/medbeam/Initialize() - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/gun/medbeam/Destroy(mob/user) - STOP_PROCESSING(SSobj, src) - LoseTarget() - return ..() - -/obj/item/gun/medbeam/dropped(mob/user) - ..() - LoseTarget() - -/obj/item/gun/medbeam/equipped(mob/user) - ..() - LoseTarget() - -/obj/item/gun/medbeam/proc/LoseTarget() - if(active) - qdel(current_beam) - current_beam = null - active = 0 - on_beam_release(current_target) - current_target = null - -/obj/item/gun/medbeam/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) - if(isliving(user)) - add_fingerprint(user) - - if(current_target) - LoseTarget() - if(!isliving(target)) - return - - current_target = target - active = TRUE - current_beam = new(user,current_target,time=6000,beam_icon_state="medbeam",btype=/obj/effect/ebeam/medical) - INVOKE_ASYNC(current_beam, /datum/beam.proc/Start) - - SSblackbox.record_feedback("tally", "gun_fired", 1, type) - -/obj/item/gun/medbeam/process() - - var/source = loc - if(!mounted && !isliving(source)) - LoseTarget() - return - - if(!current_target) - LoseTarget() - return - - if(world.time <= last_check+check_delay) - return - - last_check = world.time - - if(get_dist(source, current_target)>max_range || !los_check(source, current_target)) - LoseTarget() - if(isliving(source)) - to_chat(source, "You lose control of the beam!") - return - - if(current_target) - on_beam_tick(current_target) - -/obj/item/gun/medbeam/proc/los_check(atom/movable/user, mob/target) - var/turf/user_turf = user.loc - if(mounted) - user_turf = get_turf(user) - else if(!istype(user_turf)) - return 0 - var/obj/dummy = new(user_turf) - dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows - for(var/turf/turf in getline(user_turf,target)) - if(mounted && turf == user_turf) - continue //Mechs are dense and thus fail the check - if(turf.density) - qdel(dummy) - return 0 - for(var/atom/movable/AM in turf) - if(!AM.CanPass(dummy,turf,1)) - qdel(dummy) - return 0 - for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams! - if(B.owner.origin != current_beam.origin) - explosion(B.loc,0,3,5,8) - qdel(dummy) - return 0 - qdel(dummy) - return 1 - -/obj/item/gun/medbeam/proc/on_beam_hit(var/mob/living/target) - return - -/obj/item/gun/medbeam/proc/on_beam_tick(var/mob/living/target) - if(target.health != target.maxHealth) - new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") - target.adjustBruteLoss(-4) - target.adjustFireLoss(-4) - return - -/obj/item/gun/medbeam/proc/on_beam_release(var/mob/living/target) - return - -/obj/effect/ebeam/medical - name = "medical beam" - -//////////////////////////////Mech Version/////////////////////////////// -/obj/item/gun/medbeam/mech - mounted = 1 - -/obj/item/gun/medbeam/mech/Initialize() - . = ..() - STOP_PROCESSING(SSobj, src) //Mech mediguns do not process until installed, and are controlled by the holder obj +/obj/item/gun/medbeam + name = "Medical Beamgun" + desc = "Don't cross the streams!" + icon = 'icons/obj/chronos.dmi' + icon_state = "chronogun" + item_state = "chronogun" + w_class = WEIGHT_CLASS_NORMAL + + var/mob/living/current_target + var/last_check = 0 + var/check_delay = 10 //Check los as often as possible, max resolution is SSobj tick though + var/max_range = 8 + var/active = 0 + var/datum/beam/current_beam = null + var/mounted = 0 //Denotes if this is a handheld or mounted version + + weapon_weight = WEAPON_MEDIUM + +/obj/item/gun/medbeam/Initialize() + . = ..() + START_PROCESSING(SSobj, src) + +/obj/item/gun/medbeam/Destroy(mob/user) + STOP_PROCESSING(SSobj, src) + LoseTarget() + return ..() + +/obj/item/gun/medbeam/dropped(mob/user) + ..() + LoseTarget() + +/obj/item/gun/medbeam/equipped(mob/user) + ..() + LoseTarget() + +/obj/item/gun/medbeam/proc/LoseTarget() + if(active) + qdel(current_beam) + current_beam = null + active = 0 + on_beam_release(current_target) + current_target = null + +/obj/item/gun/medbeam/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) + if(isliving(user)) + add_fingerprint(user) + + if(current_target) + LoseTarget() + if(!isliving(target)) + return + + current_target = target + active = TRUE + current_beam = new(user,current_target,time=6000,beam_icon_state="medbeam",btype=/obj/effect/ebeam/medical) + INVOKE_ASYNC(current_beam, /datum/beam.proc/Start) + + SSblackbox.record_feedback("tally", "gun_fired", 1, type) + +/obj/item/gun/medbeam/process() + + var/source = loc + if(!mounted && !isliving(source)) + LoseTarget() + return + + if(!current_target) + LoseTarget() + return + + if(world.time <= last_check+check_delay) + return + + last_check = world.time + + if(get_dist(source, current_target)>max_range || !los_check(source, current_target)) + LoseTarget() + if(isliving(source)) + to_chat(source, "You lose control of the beam!") + return + + if(current_target) + on_beam_tick(current_target) + +/obj/item/gun/medbeam/proc/los_check(atom/movable/user, mob/target) + var/turf/user_turf = user.loc + if(mounted) + user_turf = get_turf(user) + else if(!istype(user_turf)) + return 0 + var/obj/dummy = new(user_turf) + dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows + for(var/turf/turf in getline(user_turf,target)) + if(mounted && turf == user_turf) + continue //Mechs are dense and thus fail the check + if(turf.density) + qdel(dummy) + return 0 + for(var/atom/movable/AM in turf) + if(!AM.CanPass(dummy,turf,1)) + qdel(dummy) + return 0 + for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams! + if(B.owner.origin != current_beam.origin) + explosion(B.loc,0,3,5,8) + qdel(dummy) + return 0 + qdel(dummy) + return 1 + +/obj/item/gun/medbeam/proc/on_beam_hit(var/mob/living/target) + return + +/obj/item/gun/medbeam/proc/on_beam_tick(var/mob/living/target) + if(target.health != target.maxHealth) + new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") + target.adjustBruteLoss(-4) + target.adjustFireLoss(-4) + return + +/obj/item/gun/medbeam/proc/on_beam_release(var/mob/living/target) + return + +/obj/effect/ebeam/medical + name = "medical beam" + +//////////////////////////////Mech Version/////////////////////////////// +/obj/item/gun/medbeam/mech + mounted = 1 + +/obj/item/gun/medbeam/mech/Initialize() + . = ..() + STOP_PROCESSING(SSobj, src) //Mech mediguns do not process until installed, and are controlled by the holder obj diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm similarity index 96% rename from code/modules/projectiles/guns/syringe_gun.dm rename to code/modules/projectiles/guns/misc/syringe_gun.dm index ac9f7daedf..cc1b321e3a 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -1,104 +1,104 @@ -/obj/item/gun/syringe - name = "syringe gun" - desc = "A spring loaded rifle designed to fit syringes, used to incapacitate unruly patients from a distance." - icon_state = "syringegun" - item_state = "syringegun" - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 3 - throw_range = 7 - force = 4 - materials = list(MAT_METAL=2000) - clumsy_check = 0 - fire_sound = 'sound/items/syringeproj.ogg' - var/list/syringes = list() - var/max_syringes = 1 - -/obj/item/gun/syringe/Initialize() - . = ..() - chambered = new /obj/item/ammo_casing/syringegun(src) - -/obj/item/gun/syringe/recharge_newshot() - if(!syringes.len) - return - chambered.newshot() - -/obj/item/gun/syringe/can_shoot() - return syringes.len - -/obj/item/gun/syringe/process_chamber() - if(chambered && !chambered.BB) //we just fired - recharge_newshot() - -/obj/item/gun/syringe/examine(mob/user) - ..() - to_chat(user, "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining.") - -/obj/item/gun/syringe/attack_self(mob/living/user) - if(!syringes.len) - to_chat(user, "[src] is empty!") - return 0 - - var/obj/item/reagent_containers/syringe/S = syringes[syringes.len] - - if(!S) - return 0 - S.forceMove(user.loc) - - syringes.Remove(S) - to_chat(user, "You unload [S] from \the [src].") - - return 1 - -/obj/item/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = TRUE) - if(istype(A, /obj/item/reagent_containers/syringe)) - if(syringes.len < max_syringes) - if(!user.transferItemToLoc(A, src)) - return FALSE - to_chat(user, "You load [A] into \the [src].") - syringes += A - recharge_newshot() - return TRUE - else - to_chat(user, "[src] cannot hold more syringes!") - return FALSE - -/obj/item/gun/syringe/rapidsyringe - name = "rapid syringe gun" - desc = "A modification of the syringe gun design, using a rotating cylinder to store up to six syringes." - icon_state = "rapidsyringegun" - max_syringes = 6 - -/obj/item/gun/syringe/syndicate - name = "dart pistol" - desc = "A small spring-loaded sidearm that functions identically to a syringe gun." - icon_state = "syringe_pistol" - item_state = "gun" //Smaller inhand - w_class = WEIGHT_CLASS_SMALL - force = 2 //Also very weak because it's smaller - suppressed = TRUE //Softer fire sound - can_unsuppress = FALSE //Permanently silenced - -/obj/item/gun/syringe/dna - name = "modified syringe gun" - desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes." - -/obj/item/gun/syringe/dna/Initialize() - . = ..() - chambered = new /obj/item/ammo_casing/dnainjector(src) - -/obj/item/gun/syringe/dna/attackby(obj/item/A, mob/user, params, show_msg = TRUE) - if(istype(A, /obj/item/dnainjector)) - var/obj/item/dnainjector/D = A - if(D.used) - to_chat(user, "This injector is used up!") - return - if(syringes.len < max_syringes) - if(!user.transferItemToLoc(D, src)) - return FALSE - to_chat(user, "You load \the [D] into \the [src].") - syringes += D - recharge_newshot() - return TRUE - else - to_chat(user, "[src] cannot hold more syringes!") - return FALSE +/obj/item/gun/syringe + name = "syringe gun" + desc = "A spring loaded rifle designed to fit syringes, used to incapacitate unruly patients from a distance." + icon_state = "syringegun" + item_state = "syringegun" + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 3 + throw_range = 7 + force = 4 + materials = list(MAT_METAL=2000) + clumsy_check = 0 + fire_sound = 'sound/items/syringeproj.ogg' + var/list/syringes = list() + var/max_syringes = 1 + +/obj/item/gun/syringe/Initialize() + . = ..() + chambered = new /obj/item/ammo_casing/syringegun(src) + +/obj/item/gun/syringe/recharge_newshot() + if(!syringes.len) + return + chambered.newshot() + +/obj/item/gun/syringe/can_shoot() + return syringes.len + +/obj/item/gun/syringe/process_chamber() + if(chambered && !chambered.BB) //we just fired + recharge_newshot() + +/obj/item/gun/syringe/examine(mob/user) + ..() + to_chat(user, "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining.") + +/obj/item/gun/syringe/attack_self(mob/living/user) + if(!syringes.len) + to_chat(user, "[src] is empty!") + return 0 + + var/obj/item/reagent_containers/syringe/S = syringes[syringes.len] + + if(!S) + return 0 + S.forceMove(user.loc) + + syringes.Remove(S) + to_chat(user, "You unload [S] from \the [src].") + + return 1 + +/obj/item/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = TRUE) + if(istype(A, /obj/item/reagent_containers/syringe)) + if(syringes.len < max_syringes) + if(!user.transferItemToLoc(A, src)) + return FALSE + to_chat(user, "You load [A] into \the [src].") + syringes += A + recharge_newshot() + return TRUE + else + to_chat(user, "[src] cannot hold more syringes!") + return FALSE + +/obj/item/gun/syringe/rapidsyringe + name = "rapid syringe gun" + desc = "A modification of the syringe gun design, using a rotating cylinder to store up to six syringes." + icon_state = "rapidsyringegun" + max_syringes = 6 + +/obj/item/gun/syringe/syndicate + name = "dart pistol" + desc = "A small spring-loaded sidearm that functions identically to a syringe gun." + icon_state = "syringe_pistol" + item_state = "gun" //Smaller inhand + w_class = WEIGHT_CLASS_SMALL + force = 2 //Also very weak because it's smaller + suppressed = TRUE //Softer fire sound + can_unsuppress = FALSE //Permanently silenced + +/obj/item/gun/syringe/dna + name = "modified syringe gun" + desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes." + +/obj/item/gun/syringe/dna/Initialize() + . = ..() + chambered = new /obj/item/ammo_casing/dnainjector(src) + +/obj/item/gun/syringe/dna/attackby(obj/item/A, mob/user, params, show_msg = TRUE) + if(istype(A, /obj/item/dnainjector)) + var/obj/item/dnainjector/D = A + if(D.used) + to_chat(user, "This injector is used up!") + return + if(syringes.len < max_syringes) + if(!user.transferItemToLoc(D, src)) + return FALSE + to_chat(user, "You load \the [D] into \the [src].") + syringes += D + recharge_newshot() + return TRUE + else + to_chat(user, "[src] cannot hold more syringes!") + return FALSE diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 235f27e9e5..725ef9baa6 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -7,422 +7,3 @@ flag = "bullet" hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect - -/obj/item/projectile/bullet/incendiary - damage = 20 - var/fire_stacks = 4 - -/obj/item/projectile/bullet/incendiary/on_hit(atom/target, blocked = FALSE) - . = ..() - if(iscarbon(target)) - var/mob/living/carbon/M = target - M.adjust_fire_stacks(fire_stacks) - M.IgniteMob() - -/obj/item/projectile/bullet/incendiary/Move() - . = ..() - var/turf/location = get_turf(src) - if(location) - new /obj/effect/hotspot(location) - location.hotspot_expose(700, 50, 1) - -// .357 (Syndie Revolver) - -/obj/item/projectile/bullet/a357 - name = ".357 bullet" - damage = 60 - -// 7.62 (Nagant Rifle) - -/obj/item/projectile/bullet/a762 - name = "7.62 bullet" - damage = 60 - -/obj/item/projectile/bullet/a762_enchanted - name = "enchanted 7.62 bullet" - damage = 5 - stamina = 80 - -// 7.62x38mmR (Nagant Revolver) - -/obj/item/projectile/bullet/n762 - name = "7.62x38mmR bullet" - damage = 60 - -// .50AE (Desert Eagle) - -/obj/item/projectile/bullet/a50AE - name = ".50AE bullet" - damage = 60 - -// .38 (Detective's Gun) - -/obj/item/projectile/bullet/c38 - name = ".38 bullet" - damage = 15 - knockdown = 60 - stamina = 50 - -// 10mm (Stechkin) - -/obj/item/projectile/bullet/c10mm - name = "10mm bullet" - damage = 30 - -/obj/item/projectile/bullet/c10mm_ap - name = "10mm armor-piercing bullet" - damage = 27 - armour_penetration = 40 - -/obj/item/projectile/bullet/c10mm_hp - name = "10mm hollow-point bullet" - damage = 40 - armour_penetration = -50 - -/obj/item/projectile/bullet/incendiary/c10mm - name = "10mm incendiary bullet" - damage = 15 - fire_stacks = 2 - -// 9mm (Stechkin APS) - -/obj/item/projectile/bullet/c9mm - name = "9mm bullet" - damage = 20 - -/obj/item/projectile/bullet/c9mm_ap - name = "9mm armor-piercing bullet" - damage = 15 - armour_penetration = 40 - -/obj/item/projectile/bullet/incendiary/c9mm - name = "9mm incendiary bullet" - damage = 10 - fire_stacks = 1 - -// 4.6x30mm (Autorifles) - -/obj/item/projectile/bullet/c46x30mm - name = "4.6x30mm bullet" - damage = 20 - -/obj/item/projectile/bullet/c46x30mm_ap - name = "4.6x30mm armor-piercing bullet" - damage = 15 - armour_penetration = 40 - -/obj/item/projectile/bullet/incendiary/c46x30mm - name = "4.6x30mm incendiary bullet" - damage = 10 - fire_stacks = 1 - -// .45 (M1911 & C20r) - -/obj/item/projectile/bullet/c45 - name = ".45 bullet" - damage = 20 - stamina = 65 - -/obj/item/projectile/bullet/c45_nostamina - name = ".45 bullet" - damage = 30 - -// 5.56mm (M-90gl Carbine) - -/obj/item/projectile/bullet/a556 - name = "5.56mm bullet" - damage = 35 - -// 40mm (Grenade Launcher - -/obj/item/projectile/bullet/a40mm - name ="40mm grenade" - desc = "USE A WEEL GUN" - icon_state= "bolter" - damage = 60 - -/obj/item/projectile/bullet/a40mm/on_hit(atom/target, blocked = FALSE) - ..() - explosion(target, -1, 0, 2, 1, 0, flame_range = 3) - return TRUE - -// .50 (Sniper) - -/obj/item/projectile/bullet/p50 - name =".50 bullet" - speed = 0.4 - damage = 70 - knockdown = 100 - dismemberment = 50 - armour_penetration = 50 - var/breakthings = TRUE - -/obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0) - if((blocked != 100) && (!ismob(target) && breakthings)) - target.ex_act(rand(1,2)) - return ..() - -/obj/item/projectile/bullet/p50/soporific - name =".50 soporific bullet" - armour_penetration = 0 - nodamage = TRUE - dismemberment = 0 - knockdown = 0 - breakthings = FALSE - -/obj/item/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE) - if((blocked != 100) && isliving(target)) - var/mob/living/L = target - L.Sleeping(400) - return ..() - -/obj/item/projectile/bullet/p50/penetrator - name =".50 penetrator bullet" - icon_state = "gauss" - name = "penetrator round" - damage = 60 - forcedodge = TRUE - dismemberment = 0 //It goes through you cleanly. - knockdown = 0 - breakthings = FALSE - -// 1.95x129mm (SAW) - -/obj/item/projectile/bullet/mm195x129 - name = "1.95x129mm bullet" - damage = 45 - armour_penetration = 5 - -/obj/item/projectile/bullet/mm195x129_ap - name = "1.95x129mm armor-piercing bullet" - damage = 40 - armour_penetration = 75 - -/obj/item/projectile/bullet/mm195x129_hp - name = "1.95x129mm hollow-point bullet" - damage = 60 - armour_penetration = -60 - -/obj/item/projectile/bullet/incendiary/mm195x129 - name = "1.95x129mm incendiary bullet" - damage = 15 - fire_stacks = 3 - -// Shotgun - -/obj/item/projectile/bullet/shotgun_slug - name = "12g shotgun slug" - damage = 60 - -/obj/item/projectile/bullet/shotgun_beanbag - name = "beanbag slug" - damage = 5 - stamina = 80 - -/obj/item/projectile/bullet/incendiary/shotgun - name = "incendiary slug" - damage = 20 - -/obj/item/projectile/bullet/incendiary/shotgun/dragonsbreath - name = "dragonsbreath pellet" - damage = 5 - -/obj/item/projectile/bullet/shotgun_stunslug - name = "stunslug" - damage = 5 - knockdown = 100 - stutter = 5 - jitter = 20 - range = 7 - icon_state = "spark" - color = "#FFFF00" - -/obj/item/projectile/bullet/shotgun_meteorslug - name = "meteorslug" - icon = 'icons/obj/meteor.dmi' - icon_state = "dust" - damage = 20 - knockdown = 80 - hitsound = 'sound/effects/meteorimpact.ogg' - -/obj/item/projectile/bullet/shotgun_meteorslug/on_hit(atom/target, blocked = FALSE) - . = ..() - if(ismovableatom(target)) - var/atom/movable/M = target - var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src))) - M.throw_at(throw_target, 3, 2) - -/obj/item/projectile/bullet/shotgun_meteorslug/Initialize() - . = ..() - SpinAnimation() - -/obj/item/projectile/bullet/shotgun_frag12 - name ="frag12 slug" - damage = 25 - knockdown = 50 - -/obj/item/projectile/bullet/shotgun_frag12/on_hit(atom/target, blocked = FALSE) - ..() - explosion(target, -1, 0, 1) - return TRUE - -/obj/item/projectile/bullet/pellet - var/tile_dropoff = 0.75 - var/tile_dropoff_s = 1.25 - -/obj/item/projectile/bullet/pellet/shotgun_buckshot - name = "buckshot pellet" - damage = 12.5 - -/obj/item/projectile/bullet/pellet/shotgun_rubbershot - name = "rubbershot pellet" - damage = 3 - stamina = 25 - -/obj/item/projectile/bullet/pellet/Range() - ..() - if(damage > 0) - damage -= tile_dropoff - if(stamina > 0) - stamina -= tile_dropoff_s - if(damage < 0 && stamina < 0) - qdel(src) - -/obj/item/projectile/bullet/pellet/shotgun_improvised - tile_dropoff = 0.55 //Come on it does 6 damage don't be like that. - damage = 6 - -/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize() - . = ..() - range = rand(1, 8) - -/obj/item/projectile/bullet/pellet/shotgun_improvised/on_range() - do_sparks(1, TRUE, src) - ..() - -// Scattershot - -/obj/item/projectile/bullet/scattershot - damage = 20 - stamina = 65 - -// LMD (exosuits) - -/obj/item/projectile/bullet/lmg - damage = 20 - -// Turrets - -/obj/item/projectile/bullet/manned_turret - damage = 20 - -/obj/item/projectile/bullet/syndicate_turret - damage = 20 - -// FNX-99 (Mechs) - -/obj/item/projectile/bullet/incendiary/fnx99 - damage = 20 - -// C3D (Borgs) - -/obj/item/projectile/bullet/c3d - damage = 20 - -// Honker - -/obj/item/projectile/bullet/honker - damage = 0 - knockdown = 60 - forcedodge = TRUE - nodamage = TRUE - hitsound = 'sound/items/bikehorn.ogg' - icon = 'icons/obj/hydroponics/harvest.dmi' - icon_state = "banana" - range = 200 - -/obj/item/projectile/bullet/honker/Initialize() - . = ..() - SpinAnimation() - -// Mime - -/obj/item/projectile/bullet/mime - damage = 20 - -/obj/item/projectile/bullet/mime/on_hit(atom/target, blocked = FALSE) - . = ..() - if(iscarbon(target)) - var/mob/living/carbon/M = target - M.silent = max(M.silent, 10) - -// Darts - -/obj/item/projectile/bullet/dart - name = "dart" - icon_state = "cbbolt" - damage = 6 - var/piercing = FALSE - -/obj/item/projectile/bullet/dart/Initialize() - . = ..() - create_reagents(50) - reagents.set_reacting(FALSE) - -/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) - if(iscarbon(target)) - var/mob/living/carbon/M = target - if(blocked != 100) // not completely blocked - if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. - ..() - reagents.reaction(M, INJECT) - reagents.trans_to(M, reagents.total_volume) - return TRUE - else - blocked = 100 - target.visible_message("\The [src] was deflected!", \ - "You were protected against \the [src]!") - - ..(target, blocked) - reagents.set_reacting(TRUE) - reagents.handle_reactions() - return TRUE - -/obj/item/projectile/bullet/dart/metalfoam/Initialize() - . = ..() - reagents.add_reagent("aluminium", 15) - reagents.add_reagent("foaming_agent", 5) - reagents.add_reagent("facid", 5) - -//This one is for future syringe guns update -/obj/item/projectile/bullet/dart/syringe - name = "syringe" - icon_state = "syringeproj" - -// DNA injector - -/obj/item/projectile/bullet/dnainjector - name = "\improper DNA injector" - icon_state = "syringeproj" - var/obj/item/dnainjector/injector - damage = 5 - hitsound_wall = "shatter" - -/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = FALSE) - if(iscarbon(target)) - var/mob/living/carbon/M = target - if(blocked != 100) - if(M.can_inject(null, FALSE, def_zone, FALSE)) - if(injector.inject(M, firer)) - QDEL_NULL(injector) - return TRUE - else - blocked = 100 - target.visible_message("\The [src] was deflected!", \ - "You were protected against \the [src]!") - return ..() - -/obj/item/projectile/bullet/dnainjector/Destroy() - QDEL_NULL(injector) - return ..() - diff --git a/code/modules/projectiles/projectile/bullets/_incendiary.dm b/code/modules/projectiles/projectile/bullets/_incendiary.dm new file mode 100644 index 0000000000..d0cf74421c --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/_incendiary.dm @@ -0,0 +1,17 @@ +/obj/item/projectile/bullet/incendiary + damage = 20 + var/fire_stacks = 4 + +/obj/item/projectile/bullet/incendiary/on_hit(atom/target, blocked = FALSE) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(fire_stacks) + M.IgniteMob() + +/obj/item/projectile/bullet/incendiary/Move() + . = ..() + var/turf/location = get_turf(src) + if(location) + new /obj/effect/hotspot(location) + location.hotspot_expose(700, 50, 1) diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm new file mode 100644 index 0000000000..023c3b9090 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -0,0 +1,39 @@ +/obj/item/projectile/bullet/dart + name = "dart" + icon_state = "cbbolt" + damage = 6 + var/piercing = FALSE + +/obj/item/projectile/bullet/dart/Initialize() + . = ..() + create_reagents(50) + reagents.set_reacting(FALSE) + +/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) // not completely blocked + if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..() + reagents.reaction(M, INJECT) + reagents.trans_to(M, reagents.total_volume) + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You were protected against \the [src]!") + + ..(target, blocked) + reagents.set_reacting(TRUE) + reagents.handle_reactions() + return TRUE + +/obj/item/projectile/bullet/dart/metalfoam/Initialize() + . = ..() + reagents.add_reagent("aluminium", 15) + reagents.add_reagent("foaming_agent", 5) + reagents.add_reagent("facid", 5) + +/obj/item/projectile/bullet/dart/syringe + name = "syringe" + icon_state = "syringeproj" diff --git a/code/modules/projectiles/projectile/bullets/dnainjector.dm b/code/modules/projectiles/projectile/bullets/dnainjector.dm new file mode 100644 index 0000000000..861ead5393 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/dnainjector.dm @@ -0,0 +1,24 @@ +/obj/item/projectile/bullet/dnainjector + name = "\improper DNA injector" + icon_state = "syringeproj" + var/obj/item/dnainjector/injector + damage = 5 + hitsound_wall = "shatter" + +/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = FALSE) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) + if(M.can_inject(null, FALSE, def_zone, FALSE)) + if(injector.inject(M, firer)) + QDEL_NULL(injector) + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You were protected against \the [src]!") + return ..() + +/obj/item/projectile/bullet/dnainjector/Destroy() + QDEL_NULL(injector) + return ..() diff --git a/code/modules/projectiles/projectile/bullets/grenade.dm b/code/modules/projectiles/projectile/bullets/grenade.dm new file mode 100644 index 0000000000..965001b55f --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/grenade.dm @@ -0,0 +1,12 @@ +// 40mm (Grenade Launcher + +/obj/item/projectile/bullet/a40mm + name ="40mm grenade" + desc = "USE A WEEL GUN" + icon_state= "bolter" + damage = 60 + +/obj/item/projectile/bullet/a40mm/on_hit(atom/target, blocked = FALSE) + ..() + explosion(target, -1, 0, 2, 1, 0, flame_range = 3) + return TRUE diff --git a/code/modules/projectiles/projectile/bullets/lmg.dm b/code/modules/projectiles/projectile/bullets/lmg.dm new file mode 100644 index 0000000000..03e64976d9 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/lmg.dm @@ -0,0 +1,44 @@ +// C3D (Borgs) + +/obj/item/projectile/bullet/c3d + damage = 20 + +// Mech LMG + +/obj/item/projectile/bullet/lmg + damage = 20 + +// Mech FNX-99 + +/obj/item/projectile/bullet/incendiary/fnx99 + damage = 20 + +// Turrets + +/obj/item/projectile/bullet/manned_turret + damage = 20 + +/obj/item/projectile/bullet/syndicate_turret + damage = 20 + +// 1.95x129mm (SAW) + +/obj/item/projectile/bullet/mm195x129 + name = "1.95x129mm bullet" + damage = 45 + armour_penetration = 5 + +/obj/item/projectile/bullet/mm195x129_ap + name = "1.95x129mm armor-piercing bullet" + damage = 40 + armour_penetration = 75 + +/obj/item/projectile/bullet/mm195x129_hp + name = "1.95x129mm hollow-point bullet" + damage = 60 + armour_penetration = -60 + +/obj/item/projectile/bullet/incendiary/mm195x129 + name = "1.95x129mm incendiary bullet" + damage = 15 + fire_stacks = 3 diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm new file mode 100644 index 0000000000..ac14fa563c --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/pistol.dm @@ -0,0 +1,36 @@ +// 9mm (Stechkin APS) + +/obj/item/projectile/bullet/c9mm + name = "9mm bullet" + damage = 20 + +/obj/item/projectile/bullet/c9mm_ap + name = "9mm armor-piercing bullet" + damage = 15 + armour_penetration = 40 + +/obj/item/projectile/bullet/incendiary/c9mm + name = "9mm incendiary bullet" + damage = 10 + fire_stacks = 1 + +// 10mm (Stechkin) + +/obj/item/projectile/bullet/c10mm + name = "10mm bullet" + damage = 30 + +/obj/item/projectile/bullet/c10mm_ap + name = "10mm armor-piercing bullet" + damage = 27 + armour_penetration = 40 + +/obj/item/projectile/bullet/c10mm_hp + name = "10mm hollow-point bullet" + damage = 40 + armour_penetration = -50 + +/obj/item/projectile/bullet/incendiary/c10mm + name = "10mm incendiary bullet" + damage = 15 + fire_stacks = 2 diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm new file mode 100644 index 0000000000..fc4ed0fa50 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/revolver.dm @@ -0,0 +1,25 @@ +// 7.62x38mmR (Nagant Revolver) + +/obj/item/projectile/bullet/n762 + name = "7.62x38mmR bullet" + damage = 60 + +// .50AE (Desert Eagle) + +/obj/item/projectile/bullet/a50AE + name = ".50AE bullet" + damage = 60 + +// .38 (Detective's Gun) + +/obj/item/projectile/bullet/c38 + name = ".38 bullet" + damage = 15 + knockdown = 60 + stamina = 50 + +// .357 (Syndie Revolver) + +/obj/item/projectile/bullet/a357 + name = ".357 bullet" + damage = 60 diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm new file mode 100644 index 0000000000..a019c05ef1 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -0,0 +1,16 @@ +// 5.56mm (M-90gl Carbine) + +/obj/item/projectile/bullet/a556 + name = "5.56mm bullet" + damage = 35 + +// 7.62 (Nagant Rifle) + +/obj/item/projectile/bullet/a762 + name = "7.62 bullet" + damage = 60 + +/obj/item/projectile/bullet/a762_enchanted + name = "enchanted 7.62 bullet" + damage = 5 + stamina = 80 diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm new file mode 100644 index 0000000000..ecbe2e96e4 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -0,0 +1,95 @@ +/obj/item/projectile/bullet/shotgun_slug + name = "12g shotgun slug" + damage = 60 + +/obj/item/projectile/bullet/shotgun_beanbag + name = "beanbag slug" + damage = 5 + stamina = 80 + +/obj/item/projectile/bullet/incendiary/shotgun + name = "incendiary slug" + damage = 20 + +/obj/item/projectile/bullet/incendiary/shotgun/dragonsbreath + name = "dragonsbreath pellet" + damage = 5 + +/obj/item/projectile/bullet/shotgun_stunslug + name = "stunslug" + damage = 5 + knockdown = 100 + stutter = 5 + jitter = 20 + range = 7 + icon_state = "spark" + color = "#FFFF00" + +/obj/item/projectile/bullet/shotgun_meteorslug + name = "meteorslug" + icon = 'icons/obj/meteor.dmi' + icon_state = "dust" + damage = 20 + knockdown = 80 + hitsound = 'sound/effects/meteorimpact.ogg' + +/obj/item/projectile/bullet/shotgun_meteorslug/on_hit(atom/target, blocked = FALSE) + . = ..() + if(ismovableatom(target)) + var/atom/movable/M = target + var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src))) + M.throw_at(throw_target, 3, 2) + +/obj/item/projectile/bullet/shotgun_meteorslug/Initialize() + . = ..() + SpinAnimation() + +/obj/item/projectile/bullet/shotgun_frag12 + name ="frag12 slug" + damage = 25 + knockdown = 50 + +/obj/item/projectile/bullet/shotgun_frag12/on_hit(atom/target, blocked = FALSE) + ..() + explosion(target, -1, 0, 1) + return TRUE + +/obj/item/projectile/bullet/pellet + var/tile_dropoff = 0.75 + var/tile_dropoff_s = 1.25 + +/obj/item/projectile/bullet/pellet/shotgun_buckshot + name = "buckshot pellet" + damage = 12.5 + +/obj/item/projectile/bullet/pellet/shotgun_rubbershot + name = "rubbershot pellet" + damage = 3 + stamina = 25 + +/obj/item/projectile/bullet/pellet/Range() + ..() + if(damage > 0) + damage -= tile_dropoff + if(stamina > 0) + stamina -= tile_dropoff_s + if(damage < 0 && stamina < 0) + qdel(src) + +/obj/item/projectile/bullet/pellet/shotgun_improvised + tile_dropoff = 0.55 //Come on it does 6 damage don't be like that. + damage = 6 + +/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize() + . = ..() + range = rand(1, 8) + +/obj/item/projectile/bullet/pellet/shotgun_improvised/on_range() + do_sparks(1, TRUE, src) + ..() + +// Mech Scattershot + +/obj/item/projectile/bullet/scattershot + damage = 20 + stamina = 65 diff --git a/code/modules/projectiles/projectile/bullets/smg.dm b/code/modules/projectiles/projectile/bullets/smg.dm new file mode 100644 index 0000000000..50532a5977 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/smg.dm @@ -0,0 +1,26 @@ +// .45 (M1911 & C20r) + +/obj/item/projectile/bullet/c45 + name = ".45 bullet" + damage = 20 + stamina = 65 + +/obj/item/projectile/bullet/c45_nostamina + name = ".45 bullet" + damage = 30 + +// 4.6x30mm (Autorifles) + +/obj/item/projectile/bullet/c46x30mm + name = "4.6x30mm bullet" + damage = 20 + +/obj/item/projectile/bullet/c46x30mm_ap + name = "4.6x30mm armor-piercing bullet" + damage = 15 + armour_penetration = 40 + +/obj/item/projectile/bullet/incendiary/c46x30mm + name = "4.6x30mm incendiary bullet" + damage = 10 + fire_stacks = 1 diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm new file mode 100644 index 0000000000..d29cb70440 --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/sniper.dm @@ -0,0 +1,39 @@ +// .50 (Sniper) + +/obj/item/projectile/bullet/p50 + name =".50 bullet" + speed = 0.4 + damage = 70 + knockdown = 100 + dismemberment = 50 + armour_penetration = 50 + var/breakthings = TRUE + +/obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0) + if((blocked != 100) && (!ismob(target) && breakthings)) + target.ex_act(rand(1,2)) + return ..() + +/obj/item/projectile/bullet/p50/soporific + name =".50 soporific bullet" + armour_penetration = 0 + nodamage = TRUE + dismemberment = 0 + knockdown = 0 + breakthings = FALSE + +/obj/item/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE) + if((blocked != 100) && isliving(target)) + var/mob/living/L = target + L.Sleeping(400) + return ..() + +/obj/item/projectile/bullet/p50/penetrator + name =".50 penetrator bullet" + icon_state = "gauss" + name = "penetrator round" + damage = 60 + forcedodge = TRUE + dismemberment = 0 //It goes through you cleanly. + knockdown = 0 + breakthings = FALSE diff --git a/code/modules/projectiles/projectile/bullets/special.dm b/code/modules/projectiles/projectile/bullets/special.dm new file mode 100644 index 0000000000..091dff454c --- /dev/null +++ b/code/modules/projectiles/projectile/bullets/special.dm @@ -0,0 +1,26 @@ +// Honker + +/obj/item/projectile/bullet/honker + damage = 0 + knockdown = 60 + forcedodge = TRUE + nodamage = TRUE + hitsound = 'sound/items/bikehorn.ogg' + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "banana" + range = 200 + +/obj/item/projectile/bullet/honker/Initialize() + . = ..() + SpinAnimation() + +// Mime + +/obj/item/projectile/bullet/mime + damage = 20 + +/obj/item/projectile/bullet/mime/on_hit(atom/target, blocked = FALSE) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.silent = max(M.silent, 10) diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm deleted file mode 100644 index 2d7f8f5cce..0000000000 --- a/code/modules/projectiles/projectile/energy.dm +++ /dev/null @@ -1,203 +0,0 @@ -/obj/item/projectile/energy - name = "energy" - icon_state = "spark" - damage = 0 - damage_type = BURN - flag = "energy" - is_reflectable = TRUE - -/obj/item/projectile/energy/chameleon - nodamage = TRUE - -/obj/item/projectile/energy/electrode - name = "electrode" - icon_state = "spark" - color = "#FFFF00" - nodamage = 1 - knockdown = 100 - stutter = 5 - jitter = 20 - hitsound = 'sound/weapons/taserhit.ogg' - range = 7 - tracer_type = /obj/effect/projectile/tracer/stun - muzzle_type = /obj/effect/projectile/muzzle/stun - impact_type = /obj/effect/projectile/impact/stun - -/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE) - . = ..() - if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks! - do_sparks(1, TRUE, src) - else if(iscarbon(target)) - var/mob/living/carbon/C = target - if(C.dna && C.dna.check_mutation(HULK)) - C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - else if((C.status_flags & CANKNOCKDOWN) && !C.has_trait(TRAIT_STUNIMMUNE)) - addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5) - -/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet - do_sparks(1, TRUE, src) - ..() - -/obj/item/projectile/energy/net - name = "energy netting" - icon_state = "e_netting" - damage = 10 - damage_type = STAMINA - hitsound = 'sound/weapons/taserhit.ogg' - range = 10 - -/obj/item/projectile/energy/net/Initialize() - . = ..() - SpinAnimation() - -/obj/item/projectile/energy/net/on_hit(atom/target, blocked = FALSE) - if(isliving(target)) - var/turf/Tloc = get_turf(target) - if(!locate(/obj/effect/nettingportal) in Tloc) - new /obj/effect/nettingportal(Tloc) - ..() - -/obj/item/projectile/energy/net/on_range() - do_sparks(1, TRUE, src) - ..() - -/obj/effect/nettingportal - name = "DRAGnet teleportation field" - desc = "A field of bluespace energy, locking on to teleport a target." - icon = 'icons/effects/effects.dmi' - icon_state = "dragnetfield" - light_range = 3 - anchored = TRUE - -/obj/effect/nettingportal/Initialize() - . = ..() - var/obj/item/device/radio/beacon/teletarget = null - for(var/obj/machinery/computer/teleporter/com in GLOB.machines) - if(com.target) - if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) - teletarget = com.target - - addtimer(CALLBACK(src, .proc/pop, teletarget), 30) - -/obj/effect/nettingportal/proc/pop(teletarget) - if(teletarget) - for(var/mob/living/L in get_turf(src)) - do_teleport(L, teletarget, 2)//teleport what's in the tile to the beacon - else - for(var/mob/living/L in get_turf(src)) - do_teleport(L, L, 15) //Otherwise it just warps you off somewhere. - - qdel(src) - -/obj/effect/nettingportal/singularity_act() - return - -/obj/effect/nettingportal/singularity_pull() - return - - -/obj/item/projectile/energy/trap - name = "energy snare" - icon_state = "e_snare" - nodamage = 1 - knockdown = 20 - hitsound = 'sound/weapons/taserhit.ogg' - range = 4 - -/obj/item/projectile/energy/trap/on_hit(atom/target, blocked = FALSE) - if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - drop a trap - new/obj/item/restraints/legcuffs/beartrap/energy(get_turf(loc)) - else if(iscarbon(target)) - var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy(get_turf(target)) - B.Crossed(target) - ..() - -/obj/item/projectile/energy/trap/on_range() - new /obj/item/restraints/legcuffs/beartrap/energy(loc) - ..() - -/obj/item/projectile/energy/trap/cyborg - name = "Energy Bola" - icon_state = "e_snare" - nodamage = 1 - knockdown = 0 - hitsound = 'sound/weapons/taserhit.ogg' - range = 10 - -/obj/item/projectile/energy/trap/cyborg/on_hit(atom/target, blocked = FALSE) - if(!ismob(target) || blocked >= 100) - do_sparks(1, TRUE, src) - qdel(src) - if(iscarbon(target)) - var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(target)) - B.Crossed(target) - QDEL_IN(src, 10) - ..() - -/obj/item/projectile/energy/trap/cyborg/on_range() - do_sparks(1, TRUE, src) - qdel(src) - -/obj/item/projectile/energy/declone - name = "radiation beam" - icon_state = "declone" - damage = 20 - damage_type = CLONE - irradiate = 10 - impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser - -/obj/item/projectile/energy/dart //ninja throwing dart - name = "dart" - icon_state = "toxin" - damage = 5 - damage_type = TOX - knockdown = 100 - range = 7 - -/obj/item/projectile/energy/bolt //ebow bolts - name = "bolt" - icon_state = "cbbolt" - damage = 8 - damage_type = TOX - nodamage = 0 - knockdown = 100 - stutter = 5 - -/obj/item/projectile/energy/bolt/halloween - name = "candy corn" - icon_state = "candy_corn" - -/obj/item/projectile/energy/bolt/large - damage = 20 - -/obj/item/projectile/energy/tesla - name = "tesla bolt" - icon_state = "tesla_projectile" - impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser - var/chain - -/obj/item/projectile/energy/tesla/fire(setAngle) - if(firer) - chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) - ..() - -/obj/item/projectile/energy/tesla/Destroy() - qdel(chain) - return ..() - -/obj/item/projectile/energy/tesla/revolver - name = "energy orb" - -/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target) - . = ..() - if(isliving(target)) - tesla_zap(target, 3, 10000) - qdel(src) - -/obj/item/projectile/energy/tesla/cannon - name = "tesla orb" - -/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target) - . = ..() - tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE) - qdel(src) diff --git a/code/modules/projectiles/projectile/energy/_energy.dm b/code/modules/projectiles/projectile/energy/_energy.dm new file mode 100644 index 0000000000..3df1eb74d3 --- /dev/null +++ b/code/modules/projectiles/projectile/energy/_energy.dm @@ -0,0 +1,8 @@ +/obj/item/projectile/energy + name = "energy" + icon_state = "spark" + damage = 0 + damage_type = BURN + flag = "energy" + is_reflectable = TRUE + diff --git a/code/modules/projectiles/projectile/energy/chameleon.dm b/code/modules/projectiles/projectile/energy/chameleon.dm new file mode 100644 index 0000000000..8ed6283c51 --- /dev/null +++ b/code/modules/projectiles/projectile/energy/chameleon.dm @@ -0,0 +1,3 @@ +/obj/item/projectile/energy/chameleon + nodamage = TRUE + diff --git a/code/modules/projectiles/projectile/energy/ebow.dm b/code/modules/projectiles/projectile/energy/ebow.dm new file mode 100644 index 0000000000..3e65bbfad2 --- /dev/null +++ b/code/modules/projectiles/projectile/energy/ebow.dm @@ -0,0 +1,15 @@ +/obj/item/projectile/energy/bolt //ebow bolts + name = "bolt" + icon_state = "cbbolt" + damage = 8 + damage_type = TOX + nodamage = 0 + knockdown = 100 + stutter = 5 + +/obj/item/projectile/energy/bolt/halloween + name = "candy corn" + icon_state = "candy_corn" + +/obj/item/projectile/energy/bolt/large + damage = 20 diff --git a/code/modules/projectiles/projectile/energy/misc.dm b/code/modules/projectiles/projectile/energy/misc.dm new file mode 100644 index 0000000000..21c3138add --- /dev/null +++ b/code/modules/projectiles/projectile/energy/misc.dm @@ -0,0 +1,15 @@ +/obj/item/projectile/energy/declone + name = "radiation beam" + icon_state = "declone" + damage = 20 + damage_type = CLONE + irradiate = 10 + impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser + +/obj/item/projectile/energy/dart //ninja throwing dart + name = "dart" + icon_state = "toxin" + damage = 5 + damage_type = TOX + knockdown = 100 + range = 7 diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm new file mode 100644 index 0000000000..01e87d26cd --- /dev/null +++ b/code/modules/projectiles/projectile/energy/net_snare.dm @@ -0,0 +1,98 @@ +/obj/item/projectile/energy/net + name = "energy netting" + icon_state = "e_netting" + damage = 10 + damage_type = STAMINA + hitsound = 'sound/weapons/taserhit.ogg' + range = 10 + +/obj/item/projectile/energy/net/Initialize() + . = ..() + SpinAnimation() + +/obj/item/projectile/energy/net/on_hit(atom/target, blocked = FALSE) + if(isliving(target)) + var/turf/Tloc = get_turf(target) + if(!locate(/obj/effect/nettingportal) in Tloc) + new /obj/effect/nettingportal(Tloc) + ..() + +/obj/item/projectile/energy/net/on_range() + do_sparks(1, TRUE, src) + ..() + +/obj/effect/nettingportal + name = "DRAGnet teleportation field" + desc = "A field of bluespace energy, locking on to teleport a target." + icon = 'icons/effects/effects.dmi' + icon_state = "dragnetfield" + light_range = 3 + anchored = TRUE + +/obj/effect/nettingportal/Initialize() + . = ..() + var/obj/item/device/radio/beacon/teletarget = null + for(var/obj/machinery/computer/teleporter/com in GLOB.machines) + if(com.target) + if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) + teletarget = com.target + + addtimer(CALLBACK(src, .proc/pop, teletarget), 30) + +/obj/effect/nettingportal/proc/pop(teletarget) + if(teletarget) + for(var/mob/living/L in get_turf(src)) + do_teleport(L, teletarget, 2)//teleport what's in the tile to the beacon + else + for(var/mob/living/L in get_turf(src)) + do_teleport(L, L, 15) //Otherwise it just warps you off somewhere. + + qdel(src) + +/obj/effect/nettingportal/singularity_act() + return + +/obj/effect/nettingportal/singularity_pull() + return + +/obj/item/projectile/energy/trap + name = "energy snare" + icon_state = "e_snare" + nodamage = 1 + knockdown = 20 + hitsound = 'sound/weapons/taserhit.ogg' + range = 4 + +/obj/item/projectile/energy/trap/on_hit(atom/target, blocked = FALSE) + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - drop a trap + new/obj/item/restraints/legcuffs/beartrap/energy(get_turf(loc)) + else if(iscarbon(target)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy(get_turf(target)) + B.Crossed(target) + ..() + +/obj/item/projectile/energy/trap/on_range() + new /obj/item/restraints/legcuffs/beartrap/energy(loc) + ..() + +/obj/item/projectile/energy/trap/cyborg + name = "Energy Bola" + icon_state = "e_snare" + nodamage = 1 + knockdown = 0 + hitsound = 'sound/weapons/taserhit.ogg' + range = 10 + +/obj/item/projectile/energy/trap/cyborg/on_hit(atom/target, blocked = FALSE) + if(!ismob(target) || blocked >= 100) + do_sparks(1, TRUE, src) + qdel(src) + if(iscarbon(target)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(target)) + B.Crossed(target) + QDEL_IN(src, 10) + ..() + +/obj/item/projectile/energy/trap/cyborg/on_range() + do_sparks(1, TRUE, src) + qdel(src) diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm new file mode 100644 index 0000000000..598b64d025 --- /dev/null +++ b/code/modules/projectiles/projectile/energy/stun.dm @@ -0,0 +1,28 @@ +/obj/item/projectile/energy/electrode + name = "electrode" + icon_state = "spark" + color = "#FFFF00" + nodamage = 1 + knockdown = 100 + stutter = 5 + jitter = 20 + hitsound = 'sound/weapons/taserhit.ogg' + range = 7 + tracer_type = /obj/effect/projectile/tracer/stun + muzzle_type = /obj/effect/projectile/muzzle/stun + impact_type = /obj/effect/projectile/impact/stun + +/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE) + . = ..() + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks! + do_sparks(1, TRUE, src) + else if(iscarbon(target)) + var/mob/living/carbon/C = target + if(C.dna && C.dna.check_mutation(HULK)) + C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else if((C.status_flags & CANKNOCKDOWN) && !C.has_trait(TRAIT_STUNIMMUNE)) + addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5) + +/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet + do_sparks(1, TRUE, src) + ..() diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm new file mode 100644 index 0000000000..6eebd6afbf --- /dev/null +++ b/code/modules/projectiles/projectile/energy/tesla.dm @@ -0,0 +1,31 @@ +/obj/item/projectile/energy/tesla + name = "tesla bolt" + icon_state = "tesla_projectile" + impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser + var/chain + +/obj/item/projectile/energy/tesla/fire(setAngle) + if(firer) + chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) + ..() + +/obj/item/projectile/energy/tesla/Destroy() + qdel(chain) + return ..() + +/obj/item/projectile/energy/tesla/revolver + name = "energy orb" + +/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target) + . = ..() + if(isliving(target)) + tesla_zap(target, 3, 10000) + qdel(src) + +/obj/item/projectile/energy/tesla/cannon + name = "tesla orb" + +/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target) + . = ..() + tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE) + qdel(src) diff --git a/code/modules/projectiles/projectile/reusable/_reusable.dm b/code/modules/projectiles/projectile/reusable/_reusable.dm new file mode 100644 index 0000000000..33c9678fe4 --- /dev/null +++ b/code/modules/projectiles/projectile/reusable/_reusable.dm @@ -0,0 +1,20 @@ +/obj/item/projectile/bullet/reusable + name = "reusable bullet" + desc = "How do you even reuse a bullet?" + var/ammo_type = /obj/item/ammo_casing/caseless + var/dropped = FALSE + impact_effect_type = null + +/obj/item/projectile/bullet/reusable/on_hit(atom/target, blocked = FALSE) + . = ..() + handle_drop() + +/obj/item/projectile/bullet/reusable/on_range() + handle_drop() + ..() + +/obj/item/projectile/bullet/reusable/proc/handle_drop() + if(!dropped) + var/turf/T = get_turf(src) + new ammo_type(T) + dropped = TRUE diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable/foam_dart.dm similarity index 59% rename from code/modules/projectiles/projectile/reusable.dm rename to code/modules/projectiles/projectile/reusable/foam_dart.dm index ccd4b7589c..c7f99c75aa 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable/foam_dart.dm @@ -1,69 +1,41 @@ -/obj/item/projectile/bullet/reusable - name = "reusable bullet" - desc = "How do you even reuse a bullet?" - var/ammo_type = /obj/item/ammo_casing/caseless - var/dropped = 0 - impact_effect_type = null - -/obj/item/projectile/bullet/reusable/on_hit(atom/target, blocked = FALSE) - . = ..() - handle_drop() - -/obj/item/projectile/bullet/reusable/on_range() - handle_drop() - ..() - -/obj/item/projectile/bullet/reusable/proc/handle_drop() - if(!dropped) - var/turf/T = get_turf(src) - new ammo_type(T) - dropped = 1 - -/obj/item/projectile/bullet/reusable/magspear - name = "magnetic spear" - desc = "WHITE WHALE, HOLY GRAIL" - damage = 30 //takes 3 spears to kill a mega carp, one to kill a normal carp - icon_state = "magspear" - ammo_type = /obj/item/ammo_casing/caseless/magspear - -/obj/item/projectile/bullet/reusable/foam_dart - name = "foam dart" - desc = "I hope you're wearing eye protection." - damage = 0 // It's a damn toy. - damage_type = OXY - nodamage = 1 - icon = 'icons/obj/guns/toy.dmi' - icon_state = "foamdart_proj" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart - range = 10 - var/modified = 0 - var/obj/item/pen/pen = null - -/obj/item/projectile/bullet/reusable/foam_dart/handle_drop() - if(dropped) - return - var/turf/T = get_turf(src) - dropped = 1 - var/obj/item/ammo_casing/caseless/foam_dart/newcasing = new ammo_type(T) - newcasing.modified = modified - var/obj/item/projectile/bullet/reusable/foam_dart/newdart = newcasing.BB - newdart.modified = modified - newdart.damage = damage - newdart.nodamage = nodamage - newdart.damage_type = damage_type - if(pen) - newdart.pen = pen - pen.forceMove(newdart) - pen = null - newdart.update_icon() - - -/obj/item/projectile/bullet/reusable/foam_dart/Destroy() - pen = null - return ..() - -/obj/item/projectile/bullet/reusable/foam_dart/riot - name = "riot foam dart" - icon_state = "foamdart_riot_proj" - ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot - stamina = 25 +/obj/item/projectile/bullet/reusable/foam_dart + name = "foam dart" + desc = "I hope you're wearing eye protection." + damage = 0 // It's a damn toy. + damage_type = OXY + nodamage = 1 + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foamdart_proj" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + range = 10 + var/modified = 0 + var/obj/item/pen/pen = null + +/obj/item/projectile/bullet/reusable/foam_dart/handle_drop() + if(dropped) + return + var/turf/T = get_turf(src) + dropped = 1 + var/obj/item/ammo_casing/caseless/foam_dart/newcasing = new ammo_type(T) + newcasing.modified = modified + var/obj/item/projectile/bullet/reusable/foam_dart/newdart = newcasing.BB + newdart.modified = modified + newdart.damage = damage + newdart.nodamage = nodamage + newdart.damage_type = damage_type + if(pen) + newdart.pen = pen + pen.forceMove(newdart) + pen = null + newdart.update_icon() + + +/obj/item/projectile/bullet/reusable/foam_dart/Destroy() + pen = null + return ..() + +/obj/item/projectile/bullet/reusable/foam_dart/riot + name = "riot foam dart" + icon_state = "foamdart_riot_proj" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + stamina = 25 diff --git a/code/modules/projectiles/projectile/reusable/magspear.dm b/code/modules/projectiles/projectile/reusable/magspear.dm new file mode 100644 index 0000000000..7fcd6b80a6 --- /dev/null +++ b/code/modules/projectiles/projectile/reusable/magspear.dm @@ -0,0 +1,6 @@ +/obj/item/projectile/bullet/reusable/magspear + name = "magnetic spear" + desc = "WHITE WHALE, HOLY GRAIL" + damage = 30 //takes 3 spears to kill a mega carp, one to kill a normal carp + icon_state = "magspear" + ammo_type = /obj/item/ammo_casing/caseless/magspear diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm deleted file mode 100644 index e8f309309a..0000000000 --- a/code/modules/projectiles/projectile/special.dm +++ /dev/null @@ -1,617 +0,0 @@ -/obj/item/projectile/ion - name = "ion bolt" - icon_state = "ion" - damage = 0 - damage_type = BURN - nodamage = 1 - flag = "energy" - impact_effect_type = /obj/effect/temp_visual/impact_effect/ion - - -/obj/item/projectile/ion/on_hit(atom/target, blocked = FALSE) - ..() - empulse(target, 1, 1) - return 1 - - -/obj/item/projectile/ion/weak - -/obj/item/projectile/ion/weak/on_hit(atom/target, blocked = FALSE) - ..() - empulse(target, 0, 0) - return 1 - - -/obj/item/projectile/bullet/gyro - name ="explosive bolt" - icon_state= "bolter" - damage = 50 - -/obj/item/projectile/bullet/gyro/on_hit(atom/target, blocked = FALSE) - ..() - explosion(target, -1, 0, 2) - return 1 - -/obj/item/projectile/bullet/a84mm - name ="anti-armour rocket" - desc = "USE A WEEL GUN" - icon_state= "atrocket" - damage = 80 - var/anti_armour_damage = 200 - armour_penetration = 100 - dismemberment = 100 - -/obj/item/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE) - ..() - explosion(target, -1, 1, 3, 1, 0, flame_range = 4) - - if(ismecha(target)) - var/obj/mecha/M = target - M.take_damage(anti_armour_damage) - if(issilicon(target)) - var/mob/living/silicon/S = target - S.take_overall_damage(anti_armour_damage*0.75, anti_armour_damage*0.25) - return 1 - -/obj/item/projectile/bullet/srmrocket - name ="SRM-8 Rocket" - desc = "Boom." - icon_state = "missile" - damage = 30 - ricochets_max = 0 //it's a MISSILE - -/obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0) - ..() - if(!isliving(target)) //if the target isn't alive, so is a wall or something - explosion(target, 0, 1, 2, 4) - else - explosion(target, 0, 0, 2, 4) - return 1 - -/obj/item/projectile/temp - name = "freeze beam" - icon_state = "ice_2" - damage = 0 - damage_type = BURN - nodamage = 1 - flag = "energy" - var/temperature = 100 - - -/obj/item/projectile/temp/on_hit(atom/target, blocked = FALSE)//These two could likely check temp protection on the mob - ..() - if(isliving(target)) - var/mob/M = target - M.bodytemperature = temperature - return 1 - -/obj/item/projectile/temp/hot - name = "heat beam" - temperature = 400 - -/obj/item/projectile/meteor - name = "meteor" - icon = 'icons/obj/meteor.dmi' - icon_state = "small1" - damage = 0 - damage_type = BRUTE - nodamage = 1 - flag = "bullet" - -/obj/item/projectile/meteor/Collide(atom/A) - if(A == firer) - forceMove(A.loc) - return - A.ex_act(EXPLODE_HEAVY) - playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) - for(var/mob/M in urange(10, src)) - if(!M.stat) - shake_camera(M, 3, 1) - qdel(src) - -/obj/item/projectile/energy/floramut - name = "alpha somatoray" - icon_state = "energy" - damage = 0 - damage_type = TOX - nodamage = 1 - flag = "energy" - -/obj/item/projectile/energy/floramut/on_hit(atom/target, blocked = FALSE) - . = ..() - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(C.dna.species.id == "pod") - C.randmuti() - C.randmut() - C.updateappearance() - C.domutcheck() - -/obj/item/projectile/energy/florayield - name = "beta somatoray" - icon_state = "energy2" - damage = 0 - damage_type = TOX - nodamage = 1 - flag = "energy" - -/obj/item/projectile/beam/mindflayer - name = "flayer ray" - -/obj/item/projectile/beam/mindflayer/on_hit(atom/target, blocked = FALSE) - . = ..() - if(ishuman(target)) - var/mob/living/carbon/human/M = target - M.adjustBrainLoss(20) - M.hallucination += 20 - -/obj/item/projectile/beam/wormhole - name = "bluespace beam" - icon_state = "spark" - hitsound = "sparks" - damage = 3 - var/obj/item/gun/energy/wormhole_projector/gun - color = "#33CCFF" - -/obj/item/projectile/beam/wormhole/orange - name = "orange bluespace beam" - color = "#FF6600" - -/obj/item/projectile/beam/wormhole/New(var/obj/item/ammo_casing/energy/wormhole/casing) - if(casing) - gun = casing.gun - -/obj/item/ammo_casing/energy/wormhole/New(var/obj/item/gun/energy/wormhole_projector/wh) - gun = wh - -/obj/item/projectile/beam/wormhole/on_hit(atom/target) - if(ismob(target)) - var/turf/portal_destination = pick(orange(6, src)) - do_teleport(target, portal_destination) - return ..() - if(!gun) - qdel(src) - gun.create_portal(src, get_turf(src)) - -/obj/item/projectile/plasma - name = "plasma blast" - icon_state = "plasmacutter" - damage_type = BRUTE - damage = 20 - range = 4 - dismemberment = 20 - impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser - var/pressure_decrease_active = FALSE - var/pressure_decrease = 0.25 - var/mine_range = 3 //mines this many additional tiles of rock - tracer_type = /obj/effect/projectile/tracer/plasma_cutter - muzzle_type = /obj/effect/projectile/muzzle/plasma_cutter - impact_type = /obj/effect/projectile/impact/plasma_cutter - -/obj/item/projectile/plasma/Initialize() - . = ..() - if(!lavaland_equipment_pressure_check(get_turf(src))) - name = "weakened [name]" - damage = damage * pressure_decrease - pressure_decrease_active = TRUE - -/obj/item/projectile/plasma/on_hit(atom/target) - . = ..() - if(ismineralturf(target)) - var/turf/closed/mineral/M = target - M.gets_drilled(firer) - if(mine_range) - mine_range-- - range++ - if(range > 0) - return -1 - -/obj/item/projectile/plasma/adv - damage = 28 - range = 5 - mine_range = 5 - -/obj/item/projectile/plasma/adv/mech - damage = 40 - range = 9 - mine_range = 3 - -/obj/item/projectile/plasma/turret - //Between normal and advanced for damage, made a beam so not the turret does not destroy glass - name = "plasma beam" - damage = 24 - range = 7 - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - - -/obj/item/projectile/gravityrepulse - name = "repulsion bolt" - icon = 'icons/effects/effects.dmi' - icon_state = "chronofield" - hitsound = 'sound/weapons/wave.ogg' - damage = 0 - damage_type = BRUTE - nodamage = 1 - color = "#33CCFF" - var/turf/T - var/power = 4 - var/list/thrown_items = list() - -/obj/item/projectile/gravityrepulse/Initialize() - . = ..() - var/obj/item/ammo_casing/energy/gravityrepulse/C = loc - if(istype(C)) //Hard-coded maximum power so servers can't be crashed by trying to throw the entire Z level's items - power = min(C.gun.power, 15) - -/obj/item/projectile/gravityrepulse/on_hit() - . = ..() - T = get_turf(src) - for(var/atom/movable/A in range(T, power)) - if(A == src || (firer && A == src.firer) || A.anchored || thrown_items[A]) - continue - var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(A, src))) - A.throw_at(throwtarget,power+1,1) - thrown_items[A] = A - for(var/turf/F in range(T,power)) - new /obj/effect/temp_visual/gravpush(F) - -/obj/item/projectile/gravityattract - name = "attraction bolt" - icon = 'icons/effects/effects.dmi' - icon_state = "chronofield" - hitsound = 'sound/weapons/wave.ogg' - damage = 0 - damage_type = BRUTE - nodamage = 1 - color = "#FF6600" - var/turf/T - var/power = 4 - var/list/thrown_items = list() - -/obj/item/projectile/gravityattract/Initialize() - . = ..() - var/obj/item/ammo_casing/energy/gravityattract/C = loc - if(istype(C)) //Hard-coded maximum power so servers can't be crashed by trying to throw the entire Z level's items - power = min(C.gun.power, 15) - -/obj/item/projectile/gravityattract/on_hit() - . = ..() - T = get_turf(src) - for(var/atom/movable/A in range(T, power)) - if(A == src || (firer && A == src.firer) || A.anchored || thrown_items[A]) - continue - A.throw_at(T, power+1, 1) - thrown_items[A] = A - for(var/turf/F in range(T,power)) - new /obj/effect/temp_visual/gravpush(F) - -/obj/item/projectile/gravitychaos - name = "gravitational blast" - icon = 'icons/effects/effects.dmi' - icon_state = "chronofield" - hitsound = 'sound/weapons/wave.ogg' - damage = 0 - damage_type = BRUTE - nodamage = 1 - color = "#101010" - var/turf/T - var/power = 4 - var/list/thrown_items = list() - -/obj/item/projectile/gravitychaos/Initialize() - . = ..() - var/obj/item/ammo_casing/energy/gravitychaos/C = loc - if(istype(C)) //Hard-coded maximum power so servers can't be crashed by trying to throw the entire Z level's items - power = min(C.gun.power, 15) - -/obj/item/projectile/gravitychaos/on_hit() - . = ..() - T = get_turf(src) - for(var/atom/movable/A in range(T, power)) - if(A == src|| (firer && A == src.firer) || A.anchored || thrown_items[A]) - continue - A.throw_at(get_edge_target_turf(A, pick(GLOB.cardinals)), power+1, 1) - thrown_items[A] = A - for(var/turf/Z in range(T,power)) - new /obj/effect/temp_visual/gravpush(Z) - -/obj/effect/ebeam/curse_arm - name = "curse arm" - layer = LARGE_MOB_LAYER - -/obj/item/projectile/curse_hand - name = "curse hand" - icon_state = "cursehand" - hitsound = 'sound/effects/curse4.ogg' - layer = LARGE_MOB_LAYER - damage_type = BURN - damage = 10 - knockdown = 20 - speed = 2 - range = 16 - forcedodge = TRUE - var/datum/beam/arm - var/handedness = 0 - -/obj/item/projectile/curse_hand/Initialize(mapload) - . = ..() - handedness = prob(50) - update_icon() - -/obj/item/projectile/curse_hand/update_icon() - icon_state = "[icon_state][handedness]" - -/obj/item/projectile/curse_hand/fire(setAngle) - if(starting) - arm = starting.Beam(src, icon_state = "curse[handedness]", time = INFINITY, maxdistance = INFINITY, beam_type=/obj/effect/ebeam/curse_arm) - ..() - -/obj/item/projectile/curse_hand/prehit(atom/target) - if(target == original) - forcedodge = FALSE - else if(!isturf(target)) - return FALSE - return ..() - -/obj/item/projectile/curse_hand/Destroy() - if(arm) - arm.End() - arm = null - if(forcedodge) - playsound(src, 'sound/effects/curse3.ogg', 25, 1, -1) - var/turf/T = get_step(src, dir) - new/obj/effect/temp_visual/dir_setting/curse/hand(T, dir, handedness) - for(var/obj/effect/temp_visual/dir_setting/curse/grasp_portal/G in starting) - qdel(G) - new /obj/effect/temp_visual/dir_setting/curse/grasp_portal/fading(starting, dir) - var/datum/beam/D = starting.Beam(T, icon_state = "curse[handedness]", time = 32, maxdistance = INFINITY, beam_type=/obj/effect/ebeam/curse_arm, beam_sleep_time = 1) - for(var/b in D.elements) - var/obj/effect/ebeam/B = b - animate(B, alpha = 0, time = 32) - return ..() - -/obj/item/projectile/hallucination - name = "bullet" - icon = null - icon_state = null - hitsound = "" - suppressed = TRUE - ricochets_max = 0 - ricochet_chance = 0 - damage = 0 - nodamage = TRUE - projectile_type = /obj/item/projectile/hallucination - log_override = TRUE - var/hal_icon_state - var/image/fake_icon - var/mob/living/carbon/hal_target - var/hal_fire_sound - var/hal_hitsound - var/hal_hitsound_wall - var/hal_impact_effect - var/hal_impact_effect_wall - var/hit_duration - var/hit_duration_wall - -/obj/item/projectile/hallucination/fire() - ..() - fake_icon = image('icons/obj/projectiles.dmi', src, hal_icon_state, ABOVE_MOB_LAYER) - if(hal_target.client) - hal_target.client.images += fake_icon - -/obj/item/projectile/hallucination/Destroy() - if(hal_target.client) - hal_target.client.images -= fake_icon - QDEL_NULL(fake_icon) - return ..() - -/obj/item/projectile/hallucination/Collide(atom/A) - if(!ismob(A)) - if(hal_hitsound_wall) - hal_target.playsound_local(loc, hal_hitsound_wall, 40, 1) - if(hal_impact_effect_wall) - spawn_hit(A, TRUE) - else if(A == hal_target) - if(hal_hitsound) - hal_target.playsound_local(A, hal_hitsound, 100, 1) - target_on_hit(A) - qdel(src) - return TRUE - -/obj/item/projectile/hallucination/proc/target_on_hit(mob/M) - if(M == hal_target) - to_chat(hal_target, "[M] is hit by \a [src] in the chest!") - hal_apply_effect() - else if(M in view(hal_target)) - to_chat(hal_target, "[M] is hit by \a [src] in the chest!!") - if(damage_type == BRUTE) - var/splatter_dir = dir - if(starting) - splatter_dir = get_dir(starting, get_turf(M)) - spawn_blood(M, splatter_dir) - else if(hal_impact_effect) - spawn_hit(M, FALSE) - -/obj/item/projectile/hallucination/proc/spawn_blood(mob/M, set_dir) - set waitfor = 0 - if(!hal_target.client) - return - - var/splatter_icon_state - if(set_dir in GLOB.diagonals) - splatter_icon_state = "splatter[pick(1, 2, 6)]" - else - splatter_icon_state = "splatter[pick(3, 4, 5)]" - - var/image/blood = image('icons/effects/blood.dmi', M, splatter_icon_state, ABOVE_MOB_LAYER) - var/target_pixel_x = 0 - var/target_pixel_y = 0 - switch(set_dir) - if(NORTH) - target_pixel_y = 16 - if(SOUTH) - target_pixel_y = -16 - layer = ABOVE_MOB_LAYER - if(EAST) - target_pixel_x = 16 - if(WEST) - target_pixel_x = -16 - if(NORTHEAST) - target_pixel_x = 16 - target_pixel_y = 16 - if(NORTHWEST) - target_pixel_x = -16 - target_pixel_y = 16 - if(SOUTHEAST) - target_pixel_x = 16 - target_pixel_y = -16 - layer = ABOVE_MOB_LAYER - if(SOUTHWEST) - target_pixel_x = -16 - target_pixel_y = -16 - layer = ABOVE_MOB_LAYER - hal_target.client.images += blood - animate(blood, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = 5) - addtimer(CALLBACK(src, .proc/cleanup_blood), 5) - -/obj/item/projectile/hallucination/proc/cleanup_blood(image/blood) - hal_target.client.images -= blood - qdel(blood) - -/obj/item/projectile/hallucination/proc/spawn_hit(atom/A, is_wall) - set waitfor = 0 - if(!hal_target.client) - return - - var/image/hit_effect = image('icons/effects/blood.dmi', A, is_wall ? hal_impact_effect_wall : hal_impact_effect, ABOVE_MOB_LAYER) - hit_effect.pixel_x = A.pixel_x + rand(-4,4) - hit_effect.pixel_y = A.pixel_y + rand(-4,4) - hal_target.client.images += hit_effect - sleep(is_wall ? hit_duration_wall : hit_duration) - hal_target.client.images -= hit_effect - qdel(hit_effect) - - -/obj/item/projectile/hallucination/proc/hal_apply_effect() - return - -/obj/item/projectile/hallucination/bullet - name = "bullet" - hal_icon_state = "bullet" - hal_fire_sound = "gunshot" - hal_hitsound = 'sound/weapons/pierce.ogg' - hal_hitsound_wall = "ricochet" - hal_impact_effect = "impact_bullet" - hal_impact_effect_wall = "impact_bullet" - hit_duration = 5 - hit_duration_wall = 5 - -/obj/item/projectile/hallucination/bullet/hal_apply_effect() - hal_target.adjustStaminaLoss(60) - -/obj/item/projectile/hallucination/laser - name = "laser" - damage_type = BURN - hal_icon_state = "laser" - hal_fire_sound = 'sound/weapons/laser.ogg' - hal_hitsound = 'sound/weapons/sear.ogg' - hal_hitsound_wall = 'sound/weapons/effects/searwall.ogg' - hal_impact_effect = "impact_laser" - hal_impact_effect_wall = "impact_laser_wall" - hit_duration = 4 - hit_duration_wall = 10 - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - -/obj/item/projectile/hallucination/laser/hal_apply_effect() - hal_target.adjustStaminaLoss(20) - hal_target.blur_eyes(2) - -/obj/item/projectile/hallucination/taser - name = "electrode" - damage_type = BURN - hal_icon_state = "spark" - color = "#FFFF00" - hal_fire_sound = 'sound/weapons/taser.ogg' - hal_hitsound = 'sound/weapons/taserhit.ogg' - hal_hitsound_wall = null - hal_impact_effect = null - hal_impact_effect_wall = null - -/obj/item/projectile/hallucination/taser/hal_apply_effect() - hal_target.Knockdown(100) - hal_target.stuttering += 20 - if(hal_target.dna && hal_target.dna.check_mutation(HULK)) - hal_target.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - else if((hal_target.status_flags & CANKNOCKDOWN) && !hal_target.has_trait(TRAIT_STUNIMMUNE)) - addtimer(CALLBACK(hal_target, /mob/living/carbon.proc/do_jitter_animation, 20), 5) - -/obj/item/projectile/hallucination/disabler - name = "disabler beam" - damage_type = STAMINA - hal_icon_state = "omnilaser" - hal_fire_sound = 'sound/weapons/taser2.ogg' - hal_hitsound = 'sound/weapons/tap.ogg' - hal_hitsound_wall = 'sound/weapons/effects/searwall.ogg' - hal_impact_effect = "impact_laser_blue" - hal_impact_effect_wall = null - hit_duration = 4 - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - -/obj/item/projectile/hallucination/disabler/hal_apply_effect() - hal_target.adjustStaminaLoss(25) - -/obj/item/projectile/hallucination/ebow - name = "bolt" - damage_type = TOX - hal_icon_state = "cbbolt" - hal_fire_sound = 'sound/weapons/genhit.ogg' - hal_hitsound = null - hal_hitsound_wall = null - hal_impact_effect = null - hal_impact_effect_wall = null - -/obj/item/projectile/hallucination/ebow/hal_apply_effect() - hal_target.Knockdown(100) - hal_target.stuttering += 5 - hal_target.adjustStaminaLoss(8) - -/obj/item/projectile/hallucination/change - name = "bolt of change" - damage_type = BURN - hal_icon_state = "ice_1" - hal_fire_sound = 'sound/magic/staff_change.ogg' - hal_hitsound = null - hal_hitsound_wall = null - hal_impact_effect = null - hal_impact_effect_wall = null - -/obj/item/projectile/hallucination/change/hal_apply_effect() - new /datum/hallucination/self_delusion(hal_target, TRUE, wabbajack = FALSE) - -/obj/item/projectile/hallucination/death - name = "bolt of death" - damage_type = BURN - hal_icon_state = "pulse1_bl" - hal_fire_sound = 'sound/magic/wandodeath.ogg' - hal_hitsound = null - hal_hitsound_wall = null - hal_impact_effect = null - hal_impact_effect_wall = null - -/obj/item/projectile/hallucination/death/hal_apply_effect() - new /datum/hallucination/death(hal_target, TRUE) - -// Neurotoxin - -/obj/item/projectile/bullet/neurotoxin - name = "neurotoxin spit" - icon_state = "neurotoxin" - damage = 5 - damage_type = TOX - knockdown = 100 - -/obj/item/projectile/bullet/neurotoxin/on_hit(atom/target, blocked = FALSE) - if(isalien(target)) - knockdown = 0 - nodamage = TRUE - return ..() diff --git a/code/modules/projectiles/projectile/special/curse.dm b/code/modules/projectiles/projectile/special/curse.dm new file mode 100644 index 0000000000..e5ac8126dd --- /dev/null +++ b/code/modules/projectiles/projectile/special/curse.dm @@ -0,0 +1,55 @@ +/obj/effect/ebeam/curse_arm + name = "curse arm" + layer = LARGE_MOB_LAYER + +/obj/item/projectile/curse_hand + name = "curse hand" + icon_state = "cursehand" + hitsound = 'sound/effects/curse4.ogg' + layer = LARGE_MOB_LAYER + damage_type = BURN + damage = 10 + knockdown = 20 + speed = 2 + range = 16 + forcedodge = TRUE + var/datum/beam/arm + var/handedness = 0 + +/obj/item/projectile/curse_hand/Initialize(mapload) + . = ..() + handedness = prob(50) + update_icon() + +/obj/item/projectile/curse_hand/update_icon() + icon_state = "[icon_state][handedness]" + +/obj/item/projectile/curse_hand/fire(setAngle) + if(starting) + arm = starting.Beam(src, icon_state = "curse[handedness]", time = INFINITY, maxdistance = INFINITY, beam_type=/obj/effect/ebeam/curse_arm) + ..() + +/obj/item/projectile/curse_hand/prehit(atom/target) + if(target == original) + forcedodge = FALSE + else if(!isturf(target)) + return FALSE + return ..() + +/obj/item/projectile/curse_hand/Destroy() + if(arm) + arm.End() + arm = null + if(forcedodge) + playsound(src, 'sound/effects/curse3.ogg', 25, 1, -1) + var/turf/T = get_step(src, dir) + new/obj/effect/temp_visual/dir_setting/curse/hand(T, dir, handedness) + for(var/obj/effect/temp_visual/dir_setting/curse/grasp_portal/G in starting) + qdel(G) + new /obj/effect/temp_visual/dir_setting/curse/grasp_portal/fading(starting, dir) + var/datum/beam/D = starting.Beam(T, icon_state = "curse[handedness]", time = 32, maxdistance = INFINITY, beam_type=/obj/effect/ebeam/curse_arm, beam_sleep_time = 1) + for(var/b in D.elements) + var/obj/effect/ebeam/B = b + animate(B, alpha = 0, time = 32) + return ..() + diff --git a/code/modules/projectiles/projectile/special/floral.dm b/code/modules/projectiles/projectile/special/floral.dm new file mode 100644 index 0000000000..295f89148a --- /dev/null +++ b/code/modules/projectiles/projectile/special/floral.dm @@ -0,0 +1,25 @@ +/obj/item/projectile/energy/floramut + name = "alpha somatoray" + icon_state = "energy" + damage = 0 + damage_type = TOX + nodamage = 1 + flag = "energy" + +/obj/item/projectile/energy/floramut/on_hit(atom/target, blocked = FALSE) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/C = target + if(C.dna.species.id == "pod") + C.randmuti() + C.randmut() + C.updateappearance() + C.domutcheck() + +/obj/item/projectile/energy/florayield + name = "beta somatoray" + icon_state = "energy2" + damage = 0 + damage_type = TOX + nodamage = 1 + flag = "energy" diff --git a/code/modules/projectiles/projectile/special/gravity.dm b/code/modules/projectiles/projectile/special/gravity.dm new file mode 100644 index 0000000000..89f753d36d --- /dev/null +++ b/code/modules/projectiles/projectile/special/gravity.dm @@ -0,0 +1,90 @@ +/obj/item/projectile/gravityrepulse + name = "repulsion bolt" + icon = 'icons/effects/effects.dmi' + icon_state = "chronofield" + hitsound = 'sound/weapons/wave.ogg' + damage = 0 + damage_type = BRUTE + nodamage = 1 + color = "#33CCFF" + var/turf/T + var/power = 4 + var/list/thrown_items = list() + +/obj/item/projectile/gravityrepulse/Initialize() + . = ..() + var/obj/item/ammo_casing/energy/gravityrepulse/C = loc + if(istype(C)) //Hard-coded maximum power so servers can't be crashed by trying to throw the entire Z level's items + power = min(C.gun.power, 15) + +/obj/item/projectile/gravityrepulse/on_hit() + . = ..() + T = get_turf(src) + for(var/atom/movable/A in range(T, power)) + if(A == src || (firer && A == src.firer) || A.anchored || thrown_items[A]) + continue + var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(A, src))) + A.throw_at(throwtarget,power+1,1) + thrown_items[A] = A + for(var/turf/F in range(T,power)) + new /obj/effect/temp_visual/gravpush(F) + +/obj/item/projectile/gravityattract + name = "attraction bolt" + icon = 'icons/effects/effects.dmi' + icon_state = "chronofield" + hitsound = 'sound/weapons/wave.ogg' + damage = 0 + damage_type = BRUTE + nodamage = 1 + color = "#FF6600" + var/turf/T + var/power = 4 + var/list/thrown_items = list() + +/obj/item/projectile/gravityattract/Initialize() + . = ..() + var/obj/item/ammo_casing/energy/gravityattract/C = loc + if(istype(C)) //Hard-coded maximum power so servers can't be crashed by trying to throw the entire Z level's items + power = min(C.gun.power, 15) + +/obj/item/projectile/gravityattract/on_hit() + . = ..() + T = get_turf(src) + for(var/atom/movable/A in range(T, power)) + if(A == src || (firer && A == src.firer) || A.anchored || thrown_items[A]) + continue + A.throw_at(T, power+1, 1) + thrown_items[A] = A + for(var/turf/F in range(T,power)) + new /obj/effect/temp_visual/gravpush(F) + +/obj/item/projectile/gravitychaos + name = "gravitational blast" + icon = 'icons/effects/effects.dmi' + icon_state = "chronofield" + hitsound = 'sound/weapons/wave.ogg' + damage = 0 + damage_type = BRUTE + nodamage = 1 + color = "#101010" + var/turf/T + var/power = 4 + var/list/thrown_items = list() + +/obj/item/projectile/gravitychaos/Initialize() + . = ..() + var/obj/item/ammo_casing/energy/gravitychaos/C = loc + if(istype(C)) //Hard-coded maximum power so servers can't be crashed by trying to throw the entire Z level's items + power = min(C.gun.power, 15) + +/obj/item/projectile/gravitychaos/on_hit() + . = ..() + T = get_turf(src) + for(var/atom/movable/A in range(T, power)) + if(A == src|| (firer && A == src.firer) || A.anchored || thrown_items[A]) + continue + A.throw_at(get_edge_target_turf(A, pick(GLOB.cardinals)), power+1, 1) + thrown_items[A] = A + for(var/turf/Z in range(T,power)) + new /obj/effect/temp_visual/gravpush(Z) diff --git a/code/modules/projectiles/projectile/special/hallucination.dm b/code/modules/projectiles/projectile/special/hallucination.dm new file mode 100644 index 0000000000..e158ed89f0 --- /dev/null +++ b/code/modules/projectiles/projectile/special/hallucination.dm @@ -0,0 +1,230 @@ +/obj/item/projectile/hallucination + name = "bullet" + icon = null + icon_state = null + hitsound = "" + suppressed = TRUE + ricochets_max = 0 + ricochet_chance = 0 + damage = 0 + nodamage = TRUE + projectile_type = /obj/item/projectile/hallucination + log_override = TRUE + var/hal_icon_state + var/image/fake_icon + var/mob/living/carbon/hal_target + var/hal_fire_sound + var/hal_hitsound + var/hal_hitsound_wall + var/hal_impact_effect + var/hal_impact_effect_wall + var/hit_duration + var/hit_duration_wall + +/obj/item/projectile/hallucination/fire() + ..() + fake_icon = image('icons/obj/projectiles.dmi', src, hal_icon_state, ABOVE_MOB_LAYER) + if(hal_target.client) + hal_target.client.images += fake_icon + +/obj/item/projectile/hallucination/Destroy() + if(hal_target.client) + hal_target.client.images -= fake_icon + QDEL_NULL(fake_icon) + return ..() + +/obj/item/projectile/hallucination/Collide(atom/A) + if(!ismob(A)) + if(hal_hitsound_wall) + hal_target.playsound_local(loc, hal_hitsound_wall, 40, 1) + if(hal_impact_effect_wall) + spawn_hit(A, TRUE) + else if(A == hal_target) + if(hal_hitsound) + hal_target.playsound_local(A, hal_hitsound, 100, 1) + target_on_hit(A) + qdel(src) + return TRUE + +/obj/item/projectile/hallucination/proc/target_on_hit(mob/M) + if(M == hal_target) + to_chat(hal_target, "[M] is hit by \a [src] in the chest!") + hal_apply_effect() + else if(M in view(hal_target)) + to_chat(hal_target, "[M] is hit by \a [src] in the chest!!") + if(damage_type == BRUTE) + var/splatter_dir = dir + if(starting) + splatter_dir = get_dir(starting, get_turf(M)) + spawn_blood(M, splatter_dir) + else if(hal_impact_effect) + spawn_hit(M, FALSE) + +/obj/item/projectile/hallucination/proc/spawn_blood(mob/M, set_dir) + set waitfor = 0 + if(!hal_target.client) + return + + var/splatter_icon_state + if(set_dir in GLOB.diagonals) + splatter_icon_state = "splatter[pick(1, 2, 6)]" + else + splatter_icon_state = "splatter[pick(3, 4, 5)]" + + var/image/blood = image('icons/effects/blood.dmi', M, splatter_icon_state, ABOVE_MOB_LAYER) + var/target_pixel_x = 0 + var/target_pixel_y = 0 + switch(set_dir) + if(NORTH) + target_pixel_y = 16 + if(SOUTH) + target_pixel_y = -16 + layer = ABOVE_MOB_LAYER + if(EAST) + target_pixel_x = 16 + if(WEST) + target_pixel_x = -16 + if(NORTHEAST) + target_pixel_x = 16 + target_pixel_y = 16 + if(NORTHWEST) + target_pixel_x = -16 + target_pixel_y = 16 + if(SOUTHEAST) + target_pixel_x = 16 + target_pixel_y = -16 + layer = ABOVE_MOB_LAYER + if(SOUTHWEST) + target_pixel_x = -16 + target_pixel_y = -16 + layer = ABOVE_MOB_LAYER + hal_target.client.images += blood + animate(blood, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = 5) + addtimer(CALLBACK(src, .proc/cleanup_blood), 5) + +/obj/item/projectile/hallucination/proc/cleanup_blood(image/blood) + hal_target.client.images -= blood + qdel(blood) + +/obj/item/projectile/hallucination/proc/spawn_hit(atom/A, is_wall) + set waitfor = 0 + if(!hal_target.client) + return + + var/image/hit_effect = image('icons/effects/blood.dmi', A, is_wall ? hal_impact_effect_wall : hal_impact_effect, ABOVE_MOB_LAYER) + hit_effect.pixel_x = A.pixel_x + rand(-4,4) + hit_effect.pixel_y = A.pixel_y + rand(-4,4) + hal_target.client.images += hit_effect + sleep(is_wall ? hit_duration_wall : hit_duration) + hal_target.client.images -= hit_effect + qdel(hit_effect) + + +/obj/item/projectile/hallucination/proc/hal_apply_effect() + return + +/obj/item/projectile/hallucination/bullet + name = "bullet" + hal_icon_state = "bullet" + hal_fire_sound = "gunshot" + hal_hitsound = 'sound/weapons/pierce.ogg' + hal_hitsound_wall = "ricochet" + hal_impact_effect = "impact_bullet" + hal_impact_effect_wall = "impact_bullet" + hit_duration = 5 + hit_duration_wall = 5 + +/obj/item/projectile/hallucination/bullet/hal_apply_effect() + hal_target.adjustStaminaLoss(60) + +/obj/item/projectile/hallucination/laser + name = "laser" + damage_type = BURN + hal_icon_state = "laser" + hal_fire_sound = 'sound/weapons/laser.ogg' + hal_hitsound = 'sound/weapons/sear.ogg' + hal_hitsound_wall = 'sound/weapons/effects/searwall.ogg' + hal_impact_effect = "impact_laser" + hal_impact_effect_wall = "impact_laser_wall" + hit_duration = 4 + hit_duration_wall = 10 + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE + +/obj/item/projectile/hallucination/laser/hal_apply_effect() + hal_target.adjustStaminaLoss(20) + hal_target.blur_eyes(2) + +/obj/item/projectile/hallucination/taser + name = "electrode" + damage_type = BURN + hal_icon_state = "spark" + color = "#FFFF00" + hal_fire_sound = 'sound/weapons/taser.ogg' + hal_hitsound = 'sound/weapons/taserhit.ogg' + hal_hitsound_wall = null + hal_impact_effect = null + hal_impact_effect_wall = null + +/obj/item/projectile/hallucination/taser/hal_apply_effect() + hal_target.Knockdown(100) + hal_target.stuttering += 20 + if(hal_target.dna && hal_target.dna.check_mutation(HULK)) + hal_target.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else if((hal_target.status_flags & CANKNOCKDOWN) && !hal_target.has_trait(TRAIT_STUNIMMUNE)) + addtimer(CALLBACK(hal_target, /mob/living/carbon.proc/do_jitter_animation, 20), 5) + +/obj/item/projectile/hallucination/disabler + name = "disabler beam" + damage_type = STAMINA + hal_icon_state = "omnilaser" + hal_fire_sound = 'sound/weapons/taser2.ogg' + hal_hitsound = 'sound/weapons/tap.ogg' + hal_hitsound_wall = 'sound/weapons/effects/searwall.ogg' + hal_impact_effect = "impact_laser_blue" + hal_impact_effect_wall = null + hit_duration = 4 + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE + +/obj/item/projectile/hallucination/disabler/hal_apply_effect() + hal_target.adjustStaminaLoss(25) + +/obj/item/projectile/hallucination/ebow + name = "bolt" + damage_type = TOX + hal_icon_state = "cbbolt" + hal_fire_sound = 'sound/weapons/genhit.ogg' + hal_hitsound = null + hal_hitsound_wall = null + hal_impact_effect = null + hal_impact_effect_wall = null + +/obj/item/projectile/hallucination/ebow/hal_apply_effect() + hal_target.Knockdown(100) + hal_target.stuttering += 5 + hal_target.adjustStaminaLoss(8) + +/obj/item/projectile/hallucination/change + name = "bolt of change" + damage_type = BURN + hal_icon_state = "ice_1" + hal_fire_sound = 'sound/magic/staff_change.ogg' + hal_hitsound = null + hal_hitsound_wall = null + hal_impact_effect = null + hal_impact_effect_wall = null + +/obj/item/projectile/hallucination/change/hal_apply_effect() + new /datum/hallucination/self_delusion(hal_target, TRUE, wabbajack = FALSE) + +/obj/item/projectile/hallucination/death + name = "bolt of death" + damage_type = BURN + hal_icon_state = "pulse1_bl" + hal_fire_sound = 'sound/magic/wandodeath.ogg' + hal_hitsound = null + hal_hitsound_wall = null + hal_impact_effect = null + hal_impact_effect_wall = null + +/obj/item/projectile/hallucination/death/hal_apply_effect() + new /datum/hallucination/death(hal_target, TRUE) diff --git a/code/modules/projectiles/projectile/special/ion.dm b/code/modules/projectiles/projectile/special/ion.dm new file mode 100644 index 0000000000..403a1bedd7 --- /dev/null +++ b/code/modules/projectiles/projectile/special/ion.dm @@ -0,0 +1,20 @@ +/obj/item/projectile/ion + name = "ion bolt" + icon_state = "ion" + damage = 0 + damage_type = BURN + nodamage = 1 + flag = "energy" + impact_effect_type = /obj/effect/temp_visual/impact_effect/ion + +/obj/item/projectile/ion/on_hit(atom/target, blocked = FALSE) + ..() + empulse(target, 1, 1) + return TRUE + +/obj/item/projectile/ion/weak + +/obj/item/projectile/ion/weak/on_hit(atom/target, blocked = FALSE) + ..() + empulse(target, 0, 0) + return TRUE diff --git a/code/modules/projectiles/projectile/special/meteor.dm b/code/modules/projectiles/projectile/special/meteor.dm new file mode 100644 index 0000000000..f4e60998e1 --- /dev/null +++ b/code/modules/projectiles/projectile/special/meteor.dm @@ -0,0 +1,19 @@ +/obj/item/projectile/meteor + name = "meteor" + icon = 'icons/obj/meteor.dmi' + icon_state = "small1" + damage = 0 + damage_type = BRUTE + nodamage = 1 + flag = "bullet" + +/obj/item/projectile/meteor/Collide(atom/A) + if(A == firer) + forceMove(A.loc) + return + A.ex_act(EXPLODE_HEAVY) + playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) + for(var/mob/M in urange(10, src)) + if(!M.stat) + shake_camera(M, 3, 1) + qdel(src) diff --git a/code/modules/projectiles/projectile/special/mindflayer.dm b/code/modules/projectiles/projectile/special/mindflayer.dm new file mode 100644 index 0000000000..eaa998f7e0 --- /dev/null +++ b/code/modules/projectiles/projectile/special/mindflayer.dm @@ -0,0 +1,9 @@ +/obj/item/projectile/beam/mindflayer + name = "flayer ray" + +/obj/item/projectile/beam/mindflayer/on_hit(atom/target, blocked = FALSE) + . = ..() + if(ishuman(target)) + var/mob/living/carbon/human/M = target + M.adjustBrainLoss(20) + M.hallucination += 20 diff --git a/code/modules/projectiles/projectile/special/neurotoxin.dm b/code/modules/projectiles/projectile/special/neurotoxin.dm new file mode 100644 index 0000000000..46027e7bdf --- /dev/null +++ b/code/modules/projectiles/projectile/special/neurotoxin.dm @@ -0,0 +1,12 @@ +/obj/item/projectile/bullet/neurotoxin + name = "neurotoxin spit" + icon_state = "neurotoxin" + damage = 5 + damage_type = TOX + knockdown = 100 + +/obj/item/projectile/bullet/neurotoxin/on_hit(atom/target, blocked = FALSE) + if(isalien(target)) + knockdown = 0 + nodamage = TRUE + return ..() diff --git a/code/modules/projectiles/projectile/special/plasma.dm b/code/modules/projectiles/projectile/special/plasma.dm new file mode 100644 index 0000000000..aeafb6157a --- /dev/null +++ b/code/modules/projectiles/projectile/special/plasma.dm @@ -0,0 +1,49 @@ +/obj/item/projectile/plasma + name = "plasma blast" + icon_state = "plasmacutter" + damage_type = BRUTE + damage = 20 + range = 4 + dismemberment = 20 + impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser + var/pressure_decrease_active = FALSE + var/pressure_decrease = 0.25 + var/mine_range = 3 //mines this many additional tiles of rock + tracer_type = /obj/effect/projectile/tracer/plasma_cutter + muzzle_type = /obj/effect/projectile/muzzle/plasma_cutter + impact_type = /obj/effect/projectile/impact/plasma_cutter + +/obj/item/projectile/plasma/Initialize() + . = ..() + if(!lavaland_equipment_pressure_check(get_turf(src))) + name = "weakened [name]" + damage = damage * pressure_decrease + pressure_decrease_active = TRUE + +/obj/item/projectile/plasma/on_hit(atom/target) + . = ..() + if(ismineralturf(target)) + var/turf/closed/mineral/M = target + M.gets_drilled(firer) + if(mine_range) + mine_range-- + range++ + if(range > 0) + return -1 + +/obj/item/projectile/plasma/adv + damage = 28 + range = 5 + mine_range = 5 + +/obj/item/projectile/plasma/adv/mech + damage = 40 + range = 9 + mine_range = 3 + +/obj/item/projectile/plasma/turret + //Between normal and advanced for damage, made a beam so not the turret does not destroy glass + name = "plasma beam" + damage = 24 + range = 7 + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm new file mode 100644 index 0000000000..6518b2a4d5 --- /dev/null +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -0,0 +1,45 @@ +/obj/item/projectile/bullet/gyro + name ="explosive bolt" + icon_state= "bolter" + damage = 50 + +/obj/item/projectile/bullet/gyro/on_hit(atom/target, blocked = FALSE) + ..() + explosion(target, -1, 0, 2) + return TRUE + +/obj/item/projectile/bullet/a84mm + name ="anti-armour rocket" + desc = "USE A WEEL GUN" + icon_state= "atrocket" + damage = 80 + var/anti_armour_damage = 200 + armour_penetration = 100 + dismemberment = 100 + +/obj/item/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE) + ..() + explosion(target, -1, 1, 3, 1, 0, flame_range = 4) + + if(ismecha(target)) + var/obj/mecha/M = target + M.take_damage(anti_armour_damage) + if(issilicon(target)) + var/mob/living/silicon/S = target + S.take_overall_damage(anti_armour_damage*0.75, anti_armour_damage*0.25) + return TRUE + +/obj/item/projectile/bullet/srmrocket + name ="SRM-8 Rocket" + desc = "Boom." + icon_state = "missile" + damage = 30 + ricochets_max = 0 //it's a MISSILE + +/obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0) + ..() + if(!isliving(target)) //if the target isn't alive, so is a wall or something + explosion(target, 0, 1, 2, 4) + else + explosion(target, 0, 0, 2, 4) + return TRUE diff --git a/code/modules/projectiles/projectile/special/temperature.dm b/code/modules/projectiles/projectile/special/temperature.dm new file mode 100644 index 0000000000..7fb9c6efb2 --- /dev/null +++ b/code/modules/projectiles/projectile/special/temperature.dm @@ -0,0 +1,19 @@ +/obj/item/projectile/temp + name = "freeze beam" + icon_state = "ice_2" + damage = 0 + damage_type = BURN + nodamage = FALSE + flag = "energy" + var/temperature = 100 + +/obj/item/projectile/temp/on_hit(atom/target, blocked = FALSE)//These two could likely check temp protection on the mob + ..() + if(isliving(target)) + var/mob/M = target + M.bodytemperature = temperature + return TRUE + +/obj/item/projectile/temp/hot + name = "heat beam" + temperature = 400 diff --git a/code/modules/projectiles/projectile/special/wormhole.dm b/code/modules/projectiles/projectile/special/wormhole.dm new file mode 100644 index 0000000000..94ef5b9a23 --- /dev/null +++ b/code/modules/projectiles/projectile/special/wormhole.dm @@ -0,0 +1,25 @@ +/obj/item/projectile/beam/wormhole + name = "bluespace beam" + icon_state = "spark" + hitsound = "sparks" + damage = 3 + var/obj/item/gun/energy/wormhole_projector/gun + color = "#33CCFF" + +/obj/item/projectile/beam/wormhole/orange + name = "orange bluespace beam" + color = "#FF6600" + +/obj/item/projectile/beam/wormhole/Initialize(mapload, obj/item/ammo_casing/energy/wormhole/casing) + . = ..() + if(casing) + gun = casing.gun + +/obj/item/projectile/beam/wormhole/on_hit(atom/target) + if(ismob(target)) + var/turf/portal_destination = pick(orange(6, src)) + do_teleport(target, portal_destination) + return ..() + if(!gun) + qdel(src) + gun.create_portal(src, get_turf(src)) diff --git a/tgstation.dme b/tgstation.dme index a678b93d03..f6f772f8c8 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2198,29 +2198,57 @@ #include "code\modules\procedural_mapping\mapGenerators\repair.dm" #include "code\modules\procedural_mapping\mapGenerators\shuttle.dm" #include "code\modules\procedural_mapping\mapGenerators\syndicate.dm" -#include "code\modules\projectiles\ammunition.dm" -#include "code\modules\projectiles\box_magazine.dm" -#include "code\modules\projectiles\firing.dm" #include "code\modules\projectiles\gun.dm" #include "code\modules\projectiles\pins.dm" #include "code\modules\projectiles\projectile.dm" -#include "code\modules\projectiles\ammunition\ammo_casings.dm" -#include "code\modules\projectiles\ammunition\caseless.dm" -#include "code\modules\projectiles\ammunition\energy.dm" -#include "code\modules\projectiles\ammunition\plasma.dm" -#include "code\modules\projectiles\ammunition\special.dm" +#include "code\modules\projectiles\ammunition\_ammunition.dm" +#include "code\modules\projectiles\ammunition\_firing.dm" +#include "code\modules\projectiles\ammunition\ballistic\lmg.dm" +#include "code\modules\projectiles\ammunition\ballistic\pistol.dm" +#include "code\modules\projectiles\ammunition\ballistic\revolver.dm" +#include "code\modules\projectiles\ammunition\ballistic\rifle.dm" +#include "code\modules\projectiles\ammunition\ballistic\shotgun.dm" +#include "code\modules\projectiles\ammunition\ballistic\smg.dm" +#include "code\modules\projectiles\ammunition\ballistic\sniper.dm" +#include "code\modules\projectiles\ammunition\caseless\_caseless.dm" +#include "code\modules\projectiles\ammunition\caseless\foam.dm" +#include "code\modules\projectiles\ammunition\caseless\misc.dm" +#include "code\modules\projectiles\ammunition\caseless\rocket.dm" +#include "code\modules\projectiles\ammunition\energy\_energy.dm" +#include "code\modules\projectiles\ammunition\energy\chameleon.dm" +#include "code\modules\projectiles\ammunition\energy\ebow.dm" +#include "code\modules\projectiles\ammunition\energy\gravity.dm" +#include "code\modules\projectiles\ammunition\energy\laser.dm" +#include "code\modules\projectiles\ammunition\energy\lmg.dm" +#include "code\modules\projectiles\ammunition\energy\plasma.dm" +#include "code\modules\projectiles\ammunition\energy\plasma_cit.dm" +#include "code\modules\projectiles\ammunition\energy\portal.dm" +#include "code\modules\projectiles\ammunition\energy\special.dm" +#include "code\modules\projectiles\ammunition\energy\stun.dm" +#include "code\modules\projectiles\ammunition\special\magic.dm" +#include "code\modules\projectiles\ammunition\special\syringe.dm" +#include "code\modules\projectiles\boxes_magazines\_box_magazine.dm" #include "code\modules\projectiles\boxes_magazines\ammo_boxes.dm" -#include "code\modules\projectiles\boxes_magazines\external_mag.dm" -#include "code\modules\projectiles\boxes_magazines\internal_mag.dm" +#include "code\modules\projectiles\boxes_magazines\external\grenade.dm" +#include "code\modules\projectiles\boxes_magazines\external\lmg.dm" +#include "code\modules\projectiles\boxes_magazines\external\pistol.dm" +#include "code\modules\projectiles\boxes_magazines\external\rechargable.dm" +#include "code\modules\projectiles\boxes_magazines\external\rifle.dm" +#include "code\modules\projectiles\boxes_magazines\external\shotgun.dm" +#include "code\modules\projectiles\boxes_magazines\external\smg.dm" +#include "code\modules\projectiles\boxes_magazines\external\sniper.dm" +#include "code\modules\projectiles\boxes_magazines\external\toy.dm" +#include "code\modules\projectiles\boxes_magazines\internal\_cylinder.dm" +#include "code\modules\projectiles\boxes_magazines\internal\_internal.dm" +#include "code\modules\projectiles\boxes_magazines\internal\grenade.dm" +#include "code\modules\projectiles\boxes_magazines\internal\misc.dm" +#include "code\modules\projectiles\boxes_magazines\internal\revolver.dm" +#include "code\modules\projectiles\boxes_magazines\internal\rifle.dm" +#include "code\modules\projectiles\boxes_magazines\internal\shotgun.dm" +#include "code\modules\projectiles\boxes_magazines\internal\toy.dm" #include "code\modules\projectiles\guns\ballistic.dm" -#include "code\modules\projectiles\guns\beam_rifle.dm" -#include "code\modules\projectiles\guns\chem_gun.dm" #include "code\modules\projectiles\guns\energy.dm" -#include "code\modules\projectiles\guns\grenade_launcher.dm" #include "code\modules\projectiles\guns\magic.dm" -#include "code\modules\projectiles\guns\medbeam.dm" -#include "code\modules\projectiles\guns\mounted.dm" -#include "code\modules\projectiles\guns\syringe_gun.dm" #include "code\modules\projectiles\guns\ballistic\automatic.dm" #include "code\modules\projectiles\guns\ballistic\laser_gatling.dm" #include "code\modules\projectiles\guns\ballistic\launchers.dm" @@ -2232,21 +2260,58 @@ #include "code\modules\projectiles\guns\energy\kinetic_accelerator.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\megabuster.dm" -#include "code\modules\projectiles\guns\energy\plasma.dm" +#include "code\modules\projectiles\guns\energy\mounted.dm" +#include "code\modules\projectiles\guns\energy\plasma_cit.dm" #include "code\modules\projectiles\guns\energy\pulse.dm" #include "code\modules\projectiles\guns\energy\special.dm" #include "code\modules\projectiles\guns\energy\stun.dm" #include "code\modules\projectiles\guns\magic\staff.dm" #include "code\modules\projectiles\guns\magic\wand.dm" +#include "code\modules\projectiles\guns\misc\beam_rifle.dm" #include "code\modules\projectiles\guns\misc\blastcannon.dm" +#include "code\modules\projectiles\guns\misc\chem_gun.dm" +#include "code\modules\projectiles\guns\misc\grenade_launcher.dm" +#include "code\modules\projectiles\guns\misc\medbeam.dm" +#include "code\modules\projectiles\guns\misc\syringe_gun.dm" #include "code\modules\projectiles\projectile\beams.dm" #include "code\modules\projectiles\projectile\bullets.dm" -#include "code\modules\projectiles\projectile\energy.dm" #include "code\modules\projectiles\projectile\magic.dm" #include "code\modules\projectiles\projectile\megabuster.dm" #include "code\modules\projectiles\projectile\plasma.dm" -#include "code\modules\projectiles\projectile\reusable.dm" -#include "code\modules\projectiles\projectile\special.dm" +#include "code\modules\projectiles\projectile\bullets\_incendiary.dm" +#include "code\modules\projectiles\projectile\bullets\dart_syringe.dm" +#include "code\modules\projectiles\projectile\bullets\dnainjector.dm" +#include "code\modules\projectiles\projectile\bullets\grenade.dm" +#include "code\modules\projectiles\projectile\bullets\lmg.dm" +#include "code\modules\projectiles\projectile\bullets\pistol.dm" +#include "code\modules\projectiles\projectile\bullets\revolver.dm" +#include "code\modules\projectiles\projectile\bullets\rifle.dm" +#include "code\modules\projectiles\projectile\bullets\shotgun.dm" +#include "code\modules\projectiles\projectile\bullets\smg.dm" +#include "code\modules\projectiles\projectile\bullets\sniper.dm" +#include "code\modules\projectiles\projectile\bullets\special.dm" +#include "code\modules\projectiles\projectile\energy\_energy.dm" +#include "code\modules\projectiles\projectile\energy\chameleon.dm" +#include "code\modules\projectiles\projectile\energy\ebow.dm" +#include "code\modules\projectiles\projectile\energy\misc.dm" +#include "code\modules\projectiles\projectile\energy\net_snare.dm" +#include "code\modules\projectiles\projectile\energy\stun.dm" +#include "code\modules\projectiles\projectile\energy\tesla.dm" +#include "code\modules\projectiles\projectile\reusable\_reusable.dm" +#include "code\modules\projectiles\projectile\reusable\foam_dart.dm" +#include "code\modules\projectiles\projectile\reusable\magspear.dm" +#include "code\modules\projectiles\projectile\special\curse.dm" +#include "code\modules\projectiles\projectile\special\floral.dm" +#include "code\modules\projectiles\projectile\special\gravity.dm" +#include "code\modules\projectiles\projectile\special\hallucination.dm" +#include "code\modules\projectiles\projectile\special\ion.dm" +#include "code\modules\projectiles\projectile\special\meteor.dm" +#include "code\modules\projectiles\projectile\special\mindflayer.dm" +#include "code\modules\projectiles\projectile\special\neurotoxin.dm" +#include "code\modules\projectiles\projectile\special\plasma.dm" +#include "code\modules\projectiles\projectile\special\rocket.dm" +#include "code\modules\projectiles\projectile\special\temperature.dm" +#include "code\modules\projectiles\projectile\special\wormhole.dm" #include "code\modules\reagents\chem_splash.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm"