From 95d7a68a7501518b80d70f86babfc41404b3e7e6 Mon Sep 17 00:00:00 2001 From: TheDZD Date: Fri, 27 May 2016 19:14:04 -0400 Subject: [PATCH 01/10] Here we go again... --- code/__DEFINES/combat.dm | 9 + code/__DEFINES/misc.dm | 2 +- .../game/objects/items/weapons/power_cells.dm | 13 +- code/game/sound.dm | 44 +- code/modules/projectiles/ammunition.dm | 159 ++--- .../projectiles/ammunition/ammo_casings.dm | 211 ++++--- code/modules/projectiles/ammunition/boxes.dm | 23 +- code/modules/projectiles/ammunition/energy.dm | 224 +++++++ .../projectiles/ammunition/magazines.dm | 268 ++++---- .../modules/projectiles/ammunition/special.dm | 49 ++ code/modules/projectiles/firing.dm | 95 +++ code/modules/projectiles/gun.dm | 572 ++++++++--------- code/modules/projectiles/guns/alien.dm | 2 +- code/modules/projectiles/guns/energy.dm | 171 +++-- .../projectiles/guns/energy/advtaser.dm | 40 -- .../projectiles/guns/energy/blueshield.dm | 37 -- code/modules/projectiles/guns/energy/hos.dm | 45 -- code/modules/projectiles/guns/energy/laser.dm | 116 ++-- .../projectiles/guns/energy/nuclear.dm | 240 +++---- code/modules/projectiles/guns/energy/pulse.dm | 84 +-- .../projectiles/guns/energy/special.dm | 592 ++++++++++++------ code/modules/projectiles/guns/energy/stun.dm | 89 ++- .../projectiles/guns/energy/telegun.dm | 6 +- .../projectiles/guns/energy/temperature.dm | 182 ------ .../projectiles/guns/grenade_launcher.dm | 54 ++ code/modules/projectiles/guns/magic.dm | 50 +- code/modules/projectiles/guns/magic/staff.dm | 32 +- code/modules/projectiles/guns/magic/wand.dm | 131 ++-- .../modules/projectiles/{ => guns}/medbeam.dm | 8 +- code/modules/projectiles/guns/mounted.dm | 24 +- code/modules/projectiles/guns/projectile.dm | 98 +-- .../projectiles/guns/projectile/automatic.dm | 127 ++-- .../projectiles/guns/projectile/crossbow.dm | 323 ---------- .../guns/projectile/grenade launcher.dm | 91 --- .../projectiles/guns/projectile/launchers.dm | 91 +-- .../projectiles/guns/projectile/pistol.dm | 24 +- .../projectiles/guns/projectile/revolver.dm | 319 ++++++---- .../projectiles/guns/projectile/rocket.dm | 20 +- .../projectiles/guns/projectile/saw.dm | 179 ++++++ .../projectiles/guns/projectile/shotgun.dm | 225 ++++--- .../projectiles/guns/projectile/sniper.dm | 26 +- .../projectiles/guns/projectile/toy.dm | 71 ++- code/modules/projectiles/guns/syringe_gun.dm | 41 +- code/modules/projectiles/projectile.dm | 495 ++++++--------- code/modules/projectiles/projectile/beams.dm | 127 ++-- .../modules/projectiles/projectile/bullets.dm | 190 +++--- code/modules/projectiles/projectile/energy.dm | 58 +- code/modules/projectiles/projectile/force.dm | 23 +- code/modules/projectiles/projectile/magic.dm | 119 ++-- .../projectiles/projectile/reusable.dm | 65 +- .../modules/projectiles/projectile/special.dm | 287 ++++----- code/modules/reagents/grenade_launcher.dm | 111 ---- .../reagents/reagent_containers/syringes.dm | 3 +- paradise.dme | 14 +- 54 files changed, 3403 insertions(+), 3296 deletions(-) create mode 100644 code/modules/projectiles/ammunition/energy.dm create mode 100644 code/modules/projectiles/ammunition/special.dm create mode 100644 code/modules/projectiles/firing.dm delete mode 100644 code/modules/projectiles/guns/energy/advtaser.dm delete mode 100644 code/modules/projectiles/guns/energy/blueshield.dm delete mode 100644 code/modules/projectiles/guns/energy/hos.dm delete mode 100644 code/modules/projectiles/guns/energy/temperature.dm create mode 100644 code/modules/projectiles/guns/grenade_launcher.dm rename code/modules/projectiles/{ => guns}/medbeam.dm (93%) delete mode 100644 code/modules/projectiles/guns/projectile/crossbow.dm delete mode 100644 code/modules/projectiles/guns/projectile/grenade launcher.dm create mode 100644 code/modules/projectiles/guns/projectile/saw.dm delete mode 100644 code/modules/reagents/grenade_launcher.dm diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index bf620aad6e3..c137c320390 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -53,3 +53,12 @@ #define AI_ON 1 #define AI_IDLE 2 #define AI_OFF 3 + +//Gun Stuff + #define SAWN_INTACT 0 + #define SAWN_OFF 1 + #define SAWN_SAWING -1 + + #define WEAPON_LIGHT 0 + #define WEAPON_MEDIUM 1 + #define WEAPON_HEAVY 2 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index d375f63dd39..99918eccbc8 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -250,4 +250,4 @@ #define MATRIX_GREYSCALE list(0.3, 0.3, 0.3, 0,\ 0.3, 0.3, 0.3, 0,\ 0.3, 0.3, 0.3, 0,\ - 0, 0, 0, 1) + 0, 0, 0, 1)//Gun trigger guards #define TRIGGER_GUARD_ALLOW_ALL -1 #define TRIGGER_GUARD_NONE 0 #define TRIGGER_GUARD_NORMAL 1 \ No newline at end of file diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm index 62f60a91bc4..a34a8328457 100644 --- a/code/game/objects/items/weapons/power_cells.dm +++ b/code/game/objects/items/weapons/power_cells.dm @@ -128,7 +128,6 @@ materials = list() minor_fault = 1 - /obj/item/weapon/stock_parts/cell/high/slime name = "charged slime core" desc = "A yellow slime core infused with plasma, it crackles with power." @@ -138,6 +137,12 @@ materials = list() self_recharge = 1 // Infused slime cores self-recharge, over time +/obj/item/weapon/stock_parts/cell/pulse //200 pulse shots + name = "pulse rifle power cell" + maxcharge = 40000 + rating = 3 + chargerate = 1500 + /obj/item/weapon/stock_parts/cell/pulse/carbine name = "pulse carbine power cell" maxcharge = 4000 @@ -168,9 +173,3 @@ /obj/item/weapon/stock_parts/cell/emproof/corrupt() return - -/obj/item/weapon/stock_parts/cell/temperaturegun - name = "temperature gun cell" - desc = "A specially designed power cell for heating and cooling projectiles" - icon_state = "icell" - maxcharge = 900 \ No newline at end of file diff --git a/code/game/sound.dm b/code/game/sound.dm index cecf12c657d..1890a0966e7 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -9,8 +9,9 @@ var/list/jackboot_sound = list('sound/effects/jackboot1.ogg','sound/effects/jack var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') -//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') +var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') var/list/computer_ambience = list('sound/goonstation/machines/ambicomp1.ogg', 'sound/goonstation/machines/ambicomp2.ogg', 'sound/goonstation/machines/ambicomp3.ogg') +var/list/ricochet = list('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg','sound/weapons/effects/ric3.ogg','sound/weapons/effects/ric4.ogg','sound/weapons/effects/ric5.ogg') /proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/pitch) @@ -107,17 +108,32 @@ var/const/FALLOFF_SOUNDS = 0.5 /proc/get_sfx(soundin) if(istext(soundin)) switch(soundin) - if ("shatter") soundin = pick(shatter_sound) - if ("explosion") soundin = pick(explosion_sound) - if ("sparks") soundin = pick(spark_sound) - if ("rustle") soundin = pick(rustle_sound) - if ("bodyfall") soundin = pick(bodyfall_sound) - if ("punch") soundin = pick(punch_sound) - if ("clownstep") soundin = pick(clown_sound) - if ("jackboot") soundin = pick(jackboot_sound) - if ("swing_hit") soundin = pick(swing_hit_sound) - if ("hiss") soundin = pick(hiss_sound) - if ("pageturn") soundin = pick(page_sound) - //if ("gunshot") soundin = pick(gun_sound) - if("computer_ambience") soundin = pick(computer_ambience) + if ("shatter") + soundin = pick(shatter_sound) + if ("explosion") + soundin = pick(explosion_sound) + if ("sparks") + soundin = pick(spark_sound) + if ("rustle") + soundin = pick(rustle_sound) + if ("bodyfall") + soundin = pick(bodyfall_sound) + if ("punch") + soundin = pick(punch_sound) + if ("clownstep") + soundin = pick(clown_sound) + if ("jackboot") + soundin = pick(jackboot_sound) + if ("swing_hit") + soundin = pick(swing_hit_sound) + if ("hiss") + soundin = pick(hiss_sound) + if ("pageturn") + soundin = pick(page_sound) + if ("gunshot") + soundin = pick(gun_sound) + if("computer_ambience") + soundin = pick(computer_ambience) + if("ricochet") + soundin = pick(ricochet) return soundin diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 45670ec70b0..169e968afaf 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -6,13 +6,16 @@ flags = CONDUCT slot_flags = SLOT_BELT throwforce = 1 - w_class = 1.0 - var/caliber = "" //Which kind of guns it can be loaded into - var/projectile_type = ""//The bullet type to create when New() is called + w_class = 1 + var/fire_sound = null //What sound should play when this ammo is fired + var/caliber = null //Which kind of guns it can be loaded into + var/projectile_type = null //The bullet type to create when New() is called var/obj/item/projectile/BB = null //The loaded bullet - var/pellets = 1 - var/deviation = 0 - var/spread = 0 + var/pellets = 1 //Pellets for spreadshot + var/variance = 0 //Variance for inaccuracy fundamental to the casing + var/delay = 0 //Delay for energy weapons + var/randomspread = 0 //Randomspread for automatics + var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. /obj/item/ammo_casing/New() @@ -29,54 +32,45 @@ icon_state = "[initial(icon_state)][BB ? "-live" : ""]" desc = "[initial(desc)][BB ? "" : " This one is spent"]" - - -/obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/weapon/screwdriver)) - if(BB) - if(initial(BB.name) == "bullet") - var/tmp_label = "" - var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label)) - if(length(label_text) > 20) - to_chat(user, "The inscription can be at most 20 characters long.") +/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob, params) + if(istype(I, /obj/item/ammo_box)) + var/obj/item/ammo_box/box = I + if(isturf(loc)) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in loc) + if (box.stored_ammo.len >= box.max_ammo) + break + if (bullet.BB) + if (box.give_round(bullet, 0)) + boolets++ else - if(label_text == "") - to_chat(user, "You scratch the inscription off of [initial(BB)].") - BB.name = initial(BB.name) + continue + if (boolets > 0) + box.update_icon() + to_chat(user, "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.") + else + to_chat(user, "You fail to collect anything!") + else + if(istype(I, /obj/item/weapon/screwdriver)) + if(BB) + if(initial(BB.name) == "bullet") + var/tmp_label = "" + var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label)) + if(length(label_text) > 20) + to_chat(user, "The inscription can be at most 20 characters long.") else - to_chat(user, "You inscribe \"[label_text]\" into \the [initial(BB.name)].") - BB.name = "[initial(BB.name)] \"[label_text]\"" + if(label_text == "") + to_chat(user, "You scratch the inscription off of [initial(BB)].") + BB.name = initial(BB.name) + else + to_chat(user, "You inscribe \"[label_text]\" into \the [initial(BB.name)].") + BB.name = "[initial(BB.name)] \"[label_text]\"" + else + to_chat(user, "You can only inscribe a metal bullet.")//because inscribing beanbags is silly + else - to_chat(user, "You can only inscribe a metal bullet.")//because inscribing beanbags is silly - - else - to_chat(user, "There is no bullet in the casing to inscribe anything into.") - -/obj/item/ammo_casing/attackby(obj/item/ammo_box/box as obj, mob/user as mob, params) - if(!istype(box, /obj/item/ammo_box)) - return - if(isturf(loc)) - var/boolets = 0 - for(var/obj/item/ammo_casing/pew in loc) - if(box.stored_ammo.len >= box.max_ammo) - break - if(pew.BB) - if(box.give_round(pew)) - boolets++ - else - continue - if(boolets > 0) - box.update_icon() - to_chat(user, "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.") - else - to_chat(user, "You fail to collect anything.") - -/obj/item/ammo_casing/proc/newshot() //For energy weapons, shotgun shells and wands (!). - if(!BB) - BB = new projectile_type(src) - return - - + to_chat(user, "There is no bullet in the casing to inscribe anything into.") + ..() //Boxes of ammo /obj/item/ammo_box @@ -89,53 +83,78 @@ item_state = "syringe_kit" materials = list(MAT_METAL=30000) throwforce = 2 - w_class = 1.0 + w_class = 1 throw_speed = 4 throw_range = 10 var/list/stored_ammo = list() - var/obj/item/ammo_casing/ammo_type + var/ammo_type = /obj/item/ammo_casing var/max_ammo = 7 var/multiple_sprites = 0 - var/caliber = "" + var/caliber var/multiload = 1 + /obj/item/ammo_box/New() - for(var/i = 1, i <= max_ammo, i++) + for(var/i in 1 to max_ammo) stored_ammo += new ammo_type(src) update_icon() -/obj/item/ammo_box/proc/get_round(var/keep = 0) - if(!stored_ammo.len) +/obj/item/ammo_box/Destroy() + for(atom/A in stored_ammo) + qdel(A) + stored_ammo = null + return ..() + +/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) + if (keep) stored_ammo.Insert(1,b) return b -/obj/item/ammo_box/proc/give_round(var/obj/item/ammo_casing/r) - var/obj/item/ammo_casing/rb = r - if(rb) - if(stored_ammo.len < max_ammo && rb.caliber == caliber) - stored_ammo += rb - rb.loc = src - return 1 +/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.loc = 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.loc = get_turf(src.loc) + + stored_ammo += R + R.loc = src + return 1 + return 0 -/obj/item/ammo_box/attackby(var/obj/item/A as obj, mob/user as mob, var/silent = 0, params) +/obj/item/ammo_box/proc/can_load(mob/user) + return 1 + +/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = 0, 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/didload = give_round(AC) - if(didload) + var/did_load = give_round(AC, replace_spent) + if(did_load) AM.stored_ammo -= AC num_loaded++ - if(!multiload || !didload) + if(!multiload || !did_load) break if(istype(A, /obj/item/ammo_casing)) var/obj/item/ammo_casing/AC = A - if(give_round(AC)) + if(give_round(AC, replace_spent)) user.drop_item() AC.loc = src num_loaded++ diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 44189411515..010ce185acb 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -1,128 +1,137 @@ /obj/item/ammo_casing/a357 desc = "A .357 bullet casing." caliber = "357" - projectile_type = "/obj/item/projectile/bullet" + projectile_type = /obj/item/projectile/bullet + +/obj/item/ammo_casing/a762 + desc = "A 7.62mm bullet casing." + icon_state = "762-casing" + caliber = "a762" + projectile_type = /obj/item/projectile/bullet + +/obj/item/ammo_casing/a762/enchanted + projectile_type = /obj/item/projectile/bullet/weakbullet3 /obj/item/ammo_casing/a50 desc = "A .50AE bullet casing." caliber = ".50" - projectile_type = "/obj/item/projectile/bullet" + projectile_type = /obj/item/projectile/bullet /obj/item/ammo_casing/c38 desc = "A .38 bullet casing." caliber = "38" - projectile_type = "/obj/item/projectile/bullet/weakbullet2/rubber" - -/obj/item/ammo_casing/cap - desc = "A cap for children toys." - caliber = "caps" - projectile_type = "/obj/item/projectile/bullet/cap" - + projectile_type = /obj/item/projectile/bullet/weakbullet2/rubber /obj/item/ammo_casing/c10mm desc = "A 10mm bullet casing." caliber = "10mm" - projectile_type = "/obj/item/projectile/bullet/midbullet3" - + projectile_type = /obj/item/projectile/bullet/midbullet3 /obj/item/ammo_casing/c9mm desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/weakbullet3" + projectile_type = /obj/item/projectile/bullet/weakbullet3 /obj/item/ammo_casing/c9mmap desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/armourpiercing" + projectile_type = /obj/item/projectile/bullet/armourpiercing /obj/item/ammo_casing/c9mmtox desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/toxinbullet" + projectile_type = /obj/item/projectile/bullet/toxinbullet /obj/item/ammo_casing/c9mminc desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/incendiary/firebullet" + projectile_type = /obj/item/projectile/bullet/incendiary/firebullet /obj/item/ammo_casing/c46x30mm desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/weakbullet3" + projectile_type = /obj/item/projectile/bullet/weakbullet3 /obj/item/ammo_casing/c46x30mmap desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/armourpiercing" + projectile_type = /obj/item/projectile/bullet/armourpiercing /obj/item/ammo_casing/c46x30mmtox desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/toxinbullet" + projectile_type = /obj/item/projectile/bullet/toxinbullet /obj/item/ammo_casing/c46x30mminc desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/incendiary/firebullet" + projectile_type = /obj/item/projectile/bullet/incendiary/firebullet /obj/item/ammo_casing/c45 desc = "A .45 bullet casing." caliber = ".45" - projectile_type = "/obj/item/projectile/bullet/midbullet" + projectile_type = /obj/item/projectile/bullet/midbullet +/obj/item/ammo_casing/c45nostamina + desc = "A .45 bullet casing." + caliber = ".45" + projectile_type = /obj/item/projectile/bullet/midbullet3 + +/obj/item/ammo_casing/n762 + desc = "A 7.62x38mmR bullet casing." + caliber = "n762" + projectile_type = /obj/item/projectile/bullet /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" + projectile_type = /obj/item/projectile/bullet materials = list(MAT_METAL=4000) - /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" + projectile_type = /obj/item/projectile/bullet/pellet pellets = 6 - deviation = 30 + deviation = 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/rpellet" + projectile_type = /obj/item/projectile/bullet/rpellet pellets = 6 - deviation = 30 + deviation = 25 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/weakbullet/rubber" + projectile_type = /obj/item/projectile/bullet/weakbullet/rubber materials = list(MAT_METAL=250) - /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 = "gshell" - projectile_type = "/obj/item/projectile/bullet/pellet/weak" + projectile_type = /obj/item/projectile/bullet/pellet/weak materials = list(MAT_METAL=250) pellets = 5 - deviation = 30 + deviation = 25 /obj/item/ammo_casing/shotgun/improvised/overload name = "overloaded improvised shell" desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards. This one has been packed with even more \ propellant. It's like playing russian roulette, with a shotgun." icon_state = "improvshell" - projectile_type = "/obj/item/projectile/bullet/pellet/random" + projectile_type = /obj/item/projectile/bullet/pellet/random materials = list(MAT_METAL=250) pellets = 5 - deviation = 30 + deviation = 40 /obj/item/ammo_casing/shotgun/improvised/overload/New() ..() @@ -132,15 +141,20 @@ name = "taser slug" desc = "A stunning taser slug." icon_state = "stunshell" - projectile_type = "/obj/item/projectile/bullet/stunshot" + projectile_type = /obj/item/projectile/bullet/stunshot materials = list(MAT_METAL=250) - /obj/item/ammo_casing/shotgun/meteorshot name = "meteorshot 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/meteorshot" + projectile_type = /obj/item/projectile/bullet/meteorshot + +/obj/item/ammo_casing/shotgun/breaching + name = "breaching shell" + desc = "An economic version of the meteorshot, utilizing similar technologies. Great for busting down doors." + icon_state = "mshell" + projectile_type = /obj/item/projectile/bullet/meteorshot/weak /obj/item/ammo_casing/shotgun/pulseslug name = "pulse slug" @@ -148,42 +162,42 @@ 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/shot" + projectile_type = /obj/item/projectile/beam/pulse/shot /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/shell" + projectile_type = /obj/item/projectile/bullet/incendiary/shell /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/frag12" + projectile_type = /obj/item/projectile/bullet/frag12 /obj/item/ammo_casing/shotgun/incendiary/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/shell/dragonsbreath" + projectile_type = /obj/item/projectile/bullet/incendiary/shell/dragonsbreath pellets = 4 - deviation = 30 + variance = 35 /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 splot the pulse into a spread of individually weaker bolts." icon_state = "ionshell" - projectile_type = "/obj/item/projectile/ion/weak" + projectile_type = /obj/item/projectile/ion/weak pellets = 4 - deviation = 30 + deviation = 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" + projectile_type = /obj/item/projectile/beam /obj/item/ammo_casing/shotgun/techshell name = "unloaded technological shell" @@ -195,7 +209,7 @@ 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" + projectile_type = /obj/item/projectile/bullet/dart /obj/item/ammo_casing/shotgun/dart/New() ..() @@ -206,93 +220,125 @@ /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/New() + ..() + reagents.add_reagent("neurotoxin", 6) + reagents.add_reagent("spores", 6) + reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT + reagents.add_reagent("coniine", 6) + reagents.add_reagent("sodium_thiopental", 6) + /obj/item/ammo_casing/shotgun/tranquilizer name = "tranquilizer darts" desc = "A tranquilizer round used to subdue individuals utilizing stimulants." icon_state = "cshell" - projectile_type = "/obj/item/projectile/bullet/dart/syringe/tranquilizer" + projectile_type = /obj/item/projectile/bullet/dart/syringe/tranquilizer materials = list(MAT_METAL=250) -/obj/item/ammo_casing/syringegun - name = "syringe gun spring" - desc = "A high-power spring that throws syringes." - projectile_type = null +/obj/item/ammo_casing/a556 + desc = "A 5.56mm bullet casing." + caliber = "a556" + projectile_type = /obj/item/projectile/bullet/heavybullet /obj/item/ammo_casing/shotgun/fakebeanbag name = "beanbag shell" desc = "A weak beanbag shell." icon_state = "bshell" - projectile_type = "/obj/item/projectile/bullet/weakbullet/booze" - -/obj/item/ammo_casing/a762 - desc = "A 7.62mm bullet casing." - icon_state = "762-casing" - caliber = "a762" - projectile_type = "/obj/item/projectile/bullet" - -/obj/item/ammo_casing/a556 - desc = "A 5.56mm bullet casing." - caliber = "a556" - projectile_type = "/obj/item/projectile/bullet/heavybullet" + projectile_type = /obj/item/projectile/bullet/weakbullet/booze /obj/item/ammo_casing/rocket name = "rocket shell" desc = "A high explosive designed to be fired from a launcher." icon_state = "rocketshell" - projectile_type = "/obj/item/missile" + projectile_type = /obj/item/missile caliber = "rocket" /obj/item/ammo_casing/caseless desc = "A caseless bullet casing." +/obj/item/ammo_casing/caseless/fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params, distro, quiet) + if (..()) + loc = null + return 1 + else + return 0 + /obj/item/ammo_casing/caseless/a75 desc = "A .75 bullet casing." caliber = "75" - projectile_type = "/obj/item/projectile/bullet/gyro" + projectile_type = /obj/item/projectile/bullet/gyro /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" + projectile_type = /obj/item/projectile/bullet/a40mm + +/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 -//FOAM DARTS /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" + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart caliber = "foam_force" icon = 'icons/obj/toyguns.dmi' icon_state = "foamdart" var/modified = 0 /obj/item/ammo_casing/caseless/foam_dart/update_icon() - if(modified) - icon_state = "foamdart_empty" - -/obj/item/ammo_casing/caseless/foam_dart/attackby(var/obj/item/weapon/A as obj, mob/user as mob, params) ..() - if(istype(A, /obj/item/weapon/screwdriver) && !modified) - modified = 1 - BB.damage_type = BRUTE + if (modified) icon_state = "foamdart_empty" - desc = "It's nerf or nothing! ...Although, this one doesn't look too safe." - to_chat(user, "You pop the safety cap off of [src].") - else if((istype(A, /obj/item/weapon/pen)) && modified && !BB.contents.len) + desc = "Its nerf or nothing! ... Although, this one doesn't look too safe." + if(BB) + BB.icon_state = "foamdart_empty" + else + icon_state = "foamdart" + desc = "Its nerf or nothing! Ages 8 and up." + if(BB) + BB.icon_state = "foamdart_empty" + +/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/weapon/screwdriver) && !modified) + modified = 1 + FD.damage_type = BRUTE + update_icon() + else if ((istype(A, /obj/item/weapon/pen)) && modified && !FD.pen) if(!user.unEquip(A)) return - A.forceMove(BB) - BB.damage = 5 - BB.nodamage = 0 + A.loc = FD + FD.pen = A + FD.damage = 5 + FD.nodamage = 0 to_chat(user, "You insert [A] into [src].") 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" + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/riot icon_state = "foamdart_riot" /obj/item/ammo_casing/shotgun/dart/assassination @@ -301,3 +347,8 @@ /obj/item/ammo_casing/shotgun/dart/assassination/New() ..() reagents.add_reagent("neurotoxin", 6) + +/obj/item/ammo_casing/cap + desc = "A cap for children toys." + caliber = "caps" + projectile_type = /obj/item/projectile/bullet/cap diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index eb998823b6a..3a82a0b625e 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -1,5 +1,6 @@ /obj/item/ammo_box/a357 name = "speed loader (.357)" + desc = "Designed to quickly reload revolvers." icon_state = "357" ammo_type = /obj/item/ammo_casing/a357 max_ammo = 7 @@ -7,18 +8,12 @@ /obj/item/ammo_box/c38 name = "speed loader (.38)" + desc = "Designed to quickly reload revolvers." icon_state = "38" ammo_type = /obj/item/ammo_casing/c38 max_ammo = 6 multiple_sprites = 1 -/obj/item/ammo_box/caps - name = "speed loader (caps)" - icon_state = "357" - ammo_type = /obj/item/ammo_casing/cap - max_ammo = 7 - multiple_sprites = 1 - /obj/item/ammo_box/c9mm name = "ammo box (9mm)" icon_state = "9mmbox" @@ -55,6 +50,13 @@ max_ammo = 5 multiple_sprites = 1 +/obj/item/ammo_box/n762 + name = "ammo box (7.62x38mmR)" + icon_state = "10mmbox" + origin_tech = "combat=2" + ammo_type = /obj/item/ammo_casing/n762 + max_ammo = 14 + /obj/item/ammo_box/shotgun name = "Ammunition Box (slug)" icon_state = "9mmbox" @@ -99,3 +101,10 @@ /obj/item/ammo_box/foambox/riot icon_state = "foambox_riot" ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/caps + name = "speed loader (caps)" + icon_state = "357" + ammo_type = /obj/item/ammo_casing/cap + max_ammo = 7 + multiple_sprites = 1 diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm new file mode 100644 index 00000000000..b4e979e3b20 --- /dev/null +++ b/code/modules/projectiles/ammunition/energy.dm @@ -0,0 +1,224 @@ +/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 = 1000 //The amount of energy a cell needs to expend to create this shot. + var/select_name = "energy" + fire_sound = 'sound/weapons/Laser.ogg' + +/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 = 830 + select_name = "kill" + +/obj/item/ammo_casing/energy/laser/hos //allows balancing of HoS and blueshit guns seperately from other energy weapons + +/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 = 0.8 + select_name = "scatter" + +/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/scatter/pulse + projectile_type = /obj/item/projectile/beam/pulse + e_cost = 2000 + select_name = "ANNIHILATE" + 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/redtag + projectile_type = /obj/item/projectile/beam/lasertag/redtag + select_name = "redtag" + +/obj/item/ammo_casing/energy/xray + projectile_type = /obj/item/projectile/beam/xray + e_cost = 500 + fire_sound = 'sound/weapons/laser3.ogg' + +/obj/item/ammo_casing/energy/immolator + projectile_type = /obj/item/projectile/beam/immolator + fire_sound = 'sound/weapons/laser3.ogg' + e_cost = 1250 + +/obj/item/ammo_casing/energy/electrode + projectile_type = /obj/item/projectile/energy/electrode + select_name = "stun" + fire_sound = 'sound/weapons/taser.ogg' + e_cost = 2000 + delay = 15 + +/obj/item/ammo_casing/energy/electrode/gun + fire_sound = 'sound/weapons/gunshot.ogg' + e_cost = 1000 + +/obj/item/ammo_casing/energy/electrode/hos //allows balancing of HoS and blueshit guns seperately from other energy weapons + +/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 + var/temperature = 300 + e_cost = 100 + fire_sound = 'sound/weapons/pulse3.ogg' + +/obj/item/ammo_casing/energy/temp/newshot() + ..() + BB.temperature = temperature + +/obj/item/ammo_casing/energy/meteor + projectile_type = /obj/item/projectile/meteor + select_name = "goddamn meteor" + +/obj/item/ammo_casing/energy/kinetic + projectile_type = /obj/item/projectile/kinetic + select_name = "kinetic" + e_cost = 5000 + fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap + +/obj/item/ammo_casing/energy/kinetic/super + projectile_type = /obj/item/projectile/kinetic/super + +/obj/item/ammo_casing/energy/kinetic/hyper + projectile_type = /obj/item/projectile/kinetic/hyper + +/obj/item/ammo_casing/energy/disabler + projectile_type = /obj/item/projectile/beam/disabler + select_name = "disable" + e_cost = 500 + 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 = 250 + +/obj/item/ammo_casing/energy/plasma/adv + projectile_type = /obj/item/projectile/plasma/adv + delay = 10 + e_cost = 100 + +/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/weapon/gun/energy/wormhole_projector/gun = null + select_name = "blue" + +/obj/item/ammo_casing/energy/wormhole/New(var/obj/item/weapon/gun/energy/wormhole_projector/wh) + gun = wh + +/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 = 5000 + fire_sound = 'sound/weapons/Genhit.ogg' + +/obj/item/ammo_casing/energy/bolt/large + projectile_type = /obj/item/projectile/energy/bolt/large + select_name = "heavy bolt" + +/obj/item/ammo_casing/energy/dart + projectile_type = /obj/item/projectile/energy/dart + fire_sound = 'sound/weapons/Genhit.ogg' + e_cost = 5000 + select_name = "toxic dart" + +/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/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 + +/obj/item/ammo_casing/energy/shock_revolver + fire_sound = 'sound/magic/lightningbolt.ogg' + e_cost = 2000 + select_name = "lightning beam" + projectile_type = /obj/item/projectile/energy/shock_revolver + +/obj/item/ammo_casing/energy/toxplasma + projectile_type = /obj/item/projectile/toxplasma + fire_sound = "sound/weapons/taser2.ogg" + select_name = "plasma dart" + +/obj/item/ammo_casing/energy/clown + projectile_type = /obj/item/projectile/clown + fire_sound = 'sound/weapons/Gunshot_smg.ogg' + select_name = "clown" + +/obj/item/ammo_casing/energy/sniper + projectile_type = /obj/item/projectile/beam/sniper + fire_sound = 'sound/weapons/marauder.ogg' + fire_delay = 50 + select_name = "sniper beam" + +/obj/item/ammo_casing/energy/teleport + projectile_type = /obj/item/projectile/energy/teleport + fire_sound = 'sound/weapons/wave.ogg' + e_cost = 1250 + select_name = "teleport beam" diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 32c3eeaa37c..e26e536e62a 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -1,113 +1,160 @@ ////////////////INTERNAL MAGAZINES////////////////////// +/obj/item/ammo_box/magazine/internal + desc = "Oh god, this shouldn't be here" + +//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" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/a357" + ammo_type = /obj/item/ammo_casing/a357 caliber = "357" max_ammo = 7 -/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(var/countempties = 1) - if (!countempties) - var/boolets = 0 - for (var/i = 1, i <= stored_ammo.len, i++) - var/obj/item/ammo_casing/bullet = stored_ammo[i] - if (bullet.BB) - boolets++ - return boolets - else - return stored_ammo.len +/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/rus357 - name = "russian revolver cylinder" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/a357" - caliber = "357" - max_ammo = 6 - multiload = 0 +/obj/item/ammo_box/magazine/internal/cylinder/get_round(keep = 0) + rotate() -/obj/item/ammo_box/magazine/internal/cylinder/rus357/New() - stored_ammo += new ammo_type(src) + 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.loc = src + + if(bullet) + bullet.loc = get_turf(src.loc) + return 1 + + return 0 /obj/item/ammo_box/magazine/internal/cylinder/rev38 - name = "d-tiv revolver cylinder" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/c38" + 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/cap name = "cap gun revolver cylinder" desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/cap" + ammo_type = /obj/item/ammo_casing/cap caliber = "cap" max_ammo = 7 +// Shotgun internal mags /obj/item/ammo_box/magazine/internal/shot name = "shotgun internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" + ammo_type = /obj/item/ammo_casing/shotgun/beanbag caliber = "shotgun" max_ammo = 4 multiload = 0 -/obj/item/ammo_box/magazine/internal/shotcom +/obj/item/ammo_box/magazine/internal/shot/lethal + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + +/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/com name = "combat shotgun internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" - caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot max_ammo = 6 - multiload = 0 -/obj/item/ammo_box/magazine/internal/cylinder/dualshot +/obj/item/ammo_box/magazine/internal/shot/dual name = "double-barrel shotgun internal magazine" - desc = "This doesn't even exist" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" - caliber = "shotgun" max_ammo = 2 - multiload = 0 -/obj/item/ammo_box/magazine/internal/cylinder/improvised +/obj/item/ammo_box/magazine/internal/shot/improvised name = "improvised shotgun internal magazine" - desc = "This doesn't even exist" - ammo_type = "/obj/item/ammo_casing/shotgun/improvised" - caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/improvised max_ammo = 1 - multiload = 0 -/obj/item/ammo_box/magazine/internal/shotriot +/obj/item/ammo_box/magazine/internal/shot/riot name = "riot shotgun internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/shotgun/rubbershot" - caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/rubbershot max_ammo = 6 - multiload = 0 -/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher +/obj/item/ammo_box/magazine/internal/grenadelauncher name = "grenade launcher internal magazine" - ammo_type = "/obj/item/ammo_casing/a40mm" + ammo_type = /obj/item/ammo_casing/a40mm caliber = "40mm" max_ammo = 1 /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher/multi - ammo_type = "/obj/item/ammo_casing/a40mm" + ammo_type = /obj/item/ammo_casing/a40mm max_ammo = 6 +/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/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/New() + 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" + ammo_type = /obj/item/ammo_casing/a762 caliber = "a762" max_ammo = 5 multiload = 1 /obj/item/ammo_box/magazine/internal/shot/toy - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart" + 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 + max_ammo = 5 /obj/item/ammo_box/magazine/internal/shot/toy/tommygun max_ammo = 10 @@ -116,17 +163,18 @@ /obj/item/ammo_box/magazine/m10mm name = "pistol magazine (10mm)" + desc = "A gun magazine." icon_state = "9x19p" origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c10mm" + ammo_type = /obj/item/ammo_casing/c10mm caliber = "10mm" max_ammo = 8 multiple_sprites = 2 /obj/item/ammo_box/magazine/m45 name = "handgun magazine (.45)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/c45" + icon_state = "45-8" + ammo_type = /obj/item/ammo_casing/c45 caliber = ".45" max_ammo = 8 @@ -137,7 +185,7 @@ /obj/item/ammo_box/magazine/wt550m9 name = "wt550 magazine (4.6x30mm)" icon_state = "46x30mmt-20" - ammo_type = "/obj/item/ammo_casing/c46x30mm" + ammo_type = /obj/item/ammo_casing/c46x30mm caliber = "4.6x30mm" max_ammo = 20 @@ -147,20 +195,20 @@ /obj/item/ammo_box/magazine/wt550m9/wtap name = "wt550 magazine (Armour Piercing 4.6x30mm)" - ammo_type = "/obj/item/ammo_casing/c46x30mmap" + ammo_type = /obj/item/ammo_casing/c46x30mmap /obj/item/ammo_box/magazine/wt550m9/wttx name = "wt550 magazine (Toxin Tipped 4.6x30mm)" - ammo_type = "/obj/item/ammo_casing/c46x30mmtox" + ammo_type = /obj/item/ammo_casing/c46x30mmtox /obj/item/ammo_box/magazine/wt550m9/wtic name = "wt550 magazine (Incindiary 4.6x30mm)" - ammo_type = "/obj/item/ammo_casing/c46x30mminc" + ammo_type = /obj/item/ammo_casing/c46x30mminc /obj/item/ammo_box/magazine/uzim9mm name = "uzi magazine (9mm)" icon_state = "uzi9mm-32" - ammo_type = "/obj/item/ammo_casing/c9mm" + ammo_type = /obj/item/ammo_casing/c9mm caliber = "9mm" max_ammo = 32 @@ -171,35 +219,46 @@ /obj/item/ammo_box/magazine/smgm9mm name = "SMG magazine (9mm)" icon_state = "smg9mm" - ammo_type = "/obj/item/ammo_casing/c9mm" + ammo_type = /obj/item/ammo_casing/c9mm caliber = "9mm" max_ammo = 30 materials = list(MAT_METAL = 2000) /obj/item/ammo_box/magazine/smgm9mm/ap name = "SMG magazine (Armour Piercing 9mm)" - ammo_type = "/obj/item/ammo_casing/c9mmap" + ammo_type = /obj/item/ammo_casing/c9mmap materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/toxin name = "SMG magazine (Toxin Tipped 9mm)" - ammo_type = "/obj/item/ammo_casing/c9mmtox" + ammo_type = /obj/item/ammo_casing/c9mmtox materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/fire name = "SMG Magazine (Incendiary 9mm)" - ammo_type = "/obj/item/ammo_casing/c9mminc" + ammo_type = /obj/item/ammo_casing/c9mminc materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/update_icon() ..() icon_state = "[initial(icon_state)]-[round(ammo_count(),6)]" +/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" origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c45" + ammo_type = /obj/item/ammo_casing/c45 caliber = ".45" max_ammo = 20 @@ -210,7 +269,7 @@ /obj/item/ammo_box/magazine/tommygunm45 name = "drum magazine (.45)" icon_state = "drum45" - ammo_type = "/obj/item/ammo_casing/c45" + ammo_type = /obj/item/ammo_casing/c45 caliber = ".45" max_ammo = 50 @@ -218,7 +277,7 @@ name = "handgun magazine (.50ae)" icon_state = "50ae" origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a50" + ammo_type = /obj/item/ammo_casing/a50 caliber = ".50" max_ammo = 7 multiple_sprites = 1 @@ -226,7 +285,7 @@ /obj/item/ammo_box/magazine/m75 name = "specialized magazine (.75)" icon_state = "75" - ammo_type = "/obj/item/ammo_casing/caseless/a75" + ammo_type = /obj/item/ammo_casing/caseless/a75 caliber = "75" multiple_sprites = 2 max_ammo = 8 @@ -235,50 +294,16 @@ name = "toploader magazine (5.56mm)" icon_state = "5.56m" origin_tech = "combat=5;syndicate=1" - ammo_type = "/obj/item/ammo_casing/a556" + ammo_type = /obj/item/ammo_casing/a556 caliber = "a556" max_ammo = 30 multiple_sprites = 2 -/obj/item/ammo_box/magazine/m762 - name = "box magazine (7.62mm)" - icon_state = "a762" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a762" - caliber = "a762" - max_ammo = 50 - -/obj/item/ammo_box/magazine/m762/update_icon() - ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),10)]" - -/obj/item/ammo_box/magazine/m762/buckshot - name = "box magazine (buckshot)" - icon_state = "b762" - caliber = "shotgun" - ammo_type ="/obj/item/ammo_casing/shotgun/buckshot" - max_ammo = 300 // Bluespace! - -/obj/item/ammo_box/magazine/m762/buckshot/update_icon() - ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),60)]" - -/obj/item/ammo_box/magazine/m762/he // I am not a good person. - name = "box magazine (40mm high explosive)" - icon_state = "g762" - caliber = "40mm" - ammo_type ="/obj/item/ammo_casing/a40mm" - max_ammo = 25 - -/obj/item/ammo_box/magazine/m762/he/update_icon() - ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),5)]" - - /obj/item/ammo_box/magazine/m12g name = "shotgun magazine (12g slugs)" + desc = "A drum magazine." icon_state = "m12gb" - ammo_type = "/obj/item/ammo_casing/shotgun" + ammo_type = /obj/item/ammo_casing/shotgun origin_tech = "combat=3;syndicate=1" caliber = "shotgun" max_ammo = 8 @@ -290,36 +315,45 @@ /obj/item/ammo_box/magazine/m12g/buckshot name = "shotgun magazine (12g buckshot slugs)" icon_state = "m12gb" - ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot /obj/item/ammo_box/magazine/m12g/stun name = "shotgun magazine (12g taser slugs)" icon_state = "m12gs" - ammo_type = "/obj/item/ammo_casing/shotgun/stunslug" + ammo_type = /obj/item/ammo_casing/shotgun/stunslug /obj/item/ammo_box/magazine/m12g/dragon name = "shotgun magazine (12g dragon's breath)" icon_state = "m12gf" - ammo_type = "/obj/item/ammo_casing/shotgun/incendiary/dragonsbreath" + ammo_type = /obj/item/ammo_casing/shotgun/incendiary/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/breach + name = "shotgun magazine (12g breacher slugs)" + icon_state = "m12gbc" + ammo_type = /obj/item/ammo_casing/shotgun/breaching -//FOAM DARTS /obj/item/ammo_box/magazine/toy name = "foam force META magazine" - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart" + 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-30" - max_ammo = 30 + max_ammo = 20 /obj/item/ammo_box/magazine/toy/smg/update_icon() ..() - icon_state = "smg9mm-[round(ammo_count(),6)]" + icon_state = "smg9mm-[round(ammo_count(),5)]" /obj/item/ammo_box/magazine/toy/smg/riot - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot /obj/item/ammo_box/magazine/toy/pistol name = "foam force pistol magazine" @@ -328,11 +362,11 @@ multiple_sprites = 2 /obj/item/ammo_box/magazine/toy/pistol/riot - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot /obj/item/ammo_box/magazine/toy/smgm45 name = "donksoft SMG magazine" - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot max_ammo = 20 /obj/item/ammo_box/magazine/toy/smgm45/update_icon() @@ -341,7 +375,7 @@ /obj/item/ammo_box/magazine/toy/m762 name = "donksoft box magazine" - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot max_ammo = 50 /obj/item/ammo_box/magazine/toy/m762/update_icon() diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm new file mode 100644 index 00000000000..d17d65e9fc8 --- /dev/null +++ b/code/modules/projectiles/ammunition/special.dm @@ -0,0 +1,49 @@ +/obj/item/ammo_casing/magic + name = "magic casing" + desc = "I didn't even know magic needed ammo..." + projectile_type = /obj/item/projectile/magic + +/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/fireball + +/obj/item/ammo_casing/magic/chaos + projectile_type = /obj/item/projectile/magic + +/obj/item/ammo_casing/magic/chaos/newshot() + projectile_type = pick(typesof(/obj/item/projectile/magic)) + ..() + +/obj/item/ammo_casing/magic/honk + projectile_type = /obj/item/projectile/bullet/honker + +/obj/item/ammo_casing/forcebolt + projectile_type = /obj/item/projectile/forcebolt + +/obj/item/ammo_casing/syringegun + name = "syringe gun spring" + desc = "A high-power spring that throws syringes." + projectile_type = null + +/obj/item/ammo_casing/energy/c3dbullet + projectile_type = /obj/item/projectile/bullet/midbullet3 + select_name = "spraydown" + fire_sound = 'sound/weapons/gunshot_smg.ogg' + e_cost = 200 diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm new file mode 100644 index 00000000000..9642923c452 --- /dev/null +++ b/code/modules/projectiles/firing.dm @@ -0,0 +1,95 @@ +/obj/item/ammo_casing/proc/fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params, distro, quiet, zone_override = "",spread) + distro += variance + for (var/i = max(1, pellets), i > 0, i--) + var/targloc = get_turf(target) + ready_proj(target, user, quiet, zone_override) + if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now... + if(randomspread) + spread = round((rand() - 0.5) * distro) + else //Smart spread + spread = round((i / pellets - 0.5) * distro) + if(!throw_proj(target, targloc, user, params, spread)) + return 0 + if(i > 1) + newshot() + if(click_cooldown_override) + user.changeNext_move(click_cooldown_override) + else + user.changeNext_move(CLICK_CD_RANGE) + user.newtonian_move(get_dir(target, user)) + update_icon() + return 1 + +/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if (!BB) + return + BB.original = target + BB.firer = user + if (zone_override) + BB.def_zone = zone_override + else + BB.def_zone = user.zone_selected + BB.suppressed = quiet + + if(reagents && BB.reagents) + reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets + qdel(reagents) + +/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread) + var/turf/curloc = get_turf(user) + if (!istype(targloc) || !istype(curloc) || !BB) + return 0 + BB.ammo_casing = src + if(targloc == curloc) + if(target) //if the target is right on our location we go straight to bullet_act() + target.bullet_act(BB, BB.def_zone) + qdel(BB) + BB = null + return 1 + + BB.preparePixelProjectile(target, targloc, user, params, spread) + if(BB) + BB.fire() + BB = null + return 1 + +/obj/item/ammo_casing/proc/spread(turf/target, turf/current, distro) + var/dx = abs(target.x - current.x) + var/dy = abs(target.y - current.y) + return locate(target.x + round(gaussian(0, distro) * (dy+2)/8, 1), target.y + round(gaussian(0, distro) * (dx+2)/8, 1), target.z) + +/obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread) + var/turf/curloc = get_turf(user) + src.loc = get_turf(user) + src.starting = get_turf(user) + src.current = curloc + src.yo = targloc.y - curloc.y + src.xo = targloc.x - curloc.x + + if(params) + var/list/mouse_control = params2list(params) + if(mouse_control["icon-x"]) + src.p_x = text2num(mouse_control["icon-x"]) + if(mouse_control["icon-y"]) + src.p_y = text2num(mouse_control["icon-y"]) + if(mouse_control["screen-loc"]) + //Split screen-loc up into X+Pixel_X and Y+Pixel_Y + var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") + + //Split X+Pixel_X up into list(X, Pixel_X) + var/list/screen_loc_X = splittext(screen_loc_params[1],":") + + //Split Y+Pixel_Y up into list(Y, Pixel_Y) + var/list/screen_loc_Y = splittext(screen_loc_params[2],":") + var/x = text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32 + var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32 + + //Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average. + var/screenview = (user.client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths + + var/ox = round(screenview/2) //"origin" x + var/oy = round(screenview/2) //"origin" y + var/angle = Atan2(y - oy, x - ox) + src.Angle = angle + if(spread) + src.Angle += spread diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index cb4f21d2497..7d72082b297 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -1,54 +1,59 @@ - #define SAWN_INTACT 0 - #define SAWN_OFF 1 - #define SAWN_SAWING -1 - /obj/item/weapon/gun name = "gun" - desc = "Its a gun. It's pretty terrible, though." + desc = "It's a gun. It's pretty terrible, though." icon = 'icons/obj/gun.dmi' icon_state = "detective" item_state = "gun" - lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/guns_righthand.dmi' flags = CONDUCT slot_flags = SLOT_BELT materials = list(MAT_METAL=2000) - w_class = 3.0 + w_class = 3 throwforce = 5 - throw_speed = 4 + throw_speed = 3 throw_range = 5 - force = 5.0 + force = 5 origin_tech = "combat=1" needs_permit = 1 attack_verb = list("struck", "hit", "bashed") - var/fire_sound = 'sound/weapons/Gunshot.ogg' - var/obj/item/projectile/in_chamber = null - var/silenced = 0 - var/ghettomodded = 0 - var/recoil = 0 + var/fire_sound = "gunshot" + var/fire_sound_text = "gunshot" //the fire sound that shows in chat messages: laser blast, gunshot, etc. + var/suppressed = 0 //whether or not a message is displayed when fired var/can_suppress = 0 var/can_unsuppress = 1 + var/recoil = 0 //boom boom shake the room var/clumsy_check = 1 - var/sawn_desc = null + var/obj/item/ammo_casing/chambered = null + var/trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers + var/sawn_desc = null //description change if weapon is sawn-off var/sawn_state = SAWN_INTACT - var/obj/item/ammo_casing/chambered = null // The round (not bullet) that is in the chamber. THIS MISPLACED ITEM BROUGHT TO YOU BY HACKY BUCKSHOT. - var/tmp/list/mob/living/target //List of who yer targeting. - var/tmp/lock_time = -100 - var/tmp/mouthshoot = 0 ///To stop people from suiciding twice... >.> - var/automatic = 0 //Used to determine if you can target multiple people. - var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person. - var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them. - var/firerate = 1 // 0 for one bullet after tarrget moves and aim is lowered, - //1 for keep shooting until aim is lowered - var/fire_delay = 0 - var/last_fired = 0 + var/burst_size = 1 //how large a burst is + var/fire_delay = 0 //rate of fire for burst firing and semi auto + var/firing_burst = 0 //Prevent the weapon from firing again while already firing + var/semicd = 0 //cooldown handler + var/weapon_weight = WEAPON_LIGHT + + var/spread = 0 + var/randomspread = 1 + + var/unique_rename = 0 //allows renaming with a pen + var/unique_reskin = 0 //allows one-time reskinning + var/reskinned = 0 //whether or not the gun has been reskinned + var/current_skin = null + var/list/options = list() + + lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' + righthand_file = 'icons/mob/inhands/guns_righthand.dmi' + var/obj/item/device/flashlight/F = null var/can_flashlight = 0 - var/heavy_weapon = 0 - var/randomspread = 0 - var/burst_size = 1 + var/list/upgrades = list() + + var/ammo_x_offset = 0 //used for positioning ammo count overlay on sprite + var/ammo_y_offset = 0 + var/flight_x_offset = 0 + var/flight_y_offset = 0 //Zooming var/zoomable = FALSE //whether the gun generates a Zoom action on creation @@ -56,312 +61,196 @@ var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect) var/datum/action/toggle_scope_zoom/azoom - proc/ready_to_fire() - if(world.time >= last_fired + fire_delay) - last_fired = world.time - return 1 - else - return 0 - - proc/process_chambered() - return 0 - - - proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver. - if(!M.IsAdvancedToolUser()) - return 0 - return 1 - - - proc/shoot_with_empty_chamber(mob/living/user as mob|obj) - to_chat(user, "*click*") - playsound(user, 'sound/weapons/emptyclick.ogg', 40, 1) - return - - emp_act(severity) - for(var/obj/O in contents) - O.emp_act(severity) - - proc/prepare_shot(var/obj/item/projectile/proj) //Transfer properties from the gun to the bullet - proj.shot_from = src - proj.silenced = silenced - return - /obj/item/weapon/gun/New() + ..() + if(F) + verbs += /obj/item/weapon/gun/proc/toggle_gunlight + new /datum/action/item_action/toggle_gunlight(src) build_zooming() + +/obj/item/weapon/gun/examine(mob/user) ..() + if(unique_reskin && !reskinned) + to_chat(user, "Alt-click it to reskin it.") + if(unique_rename) + to_chat(user, "Use a pen on it to rename it.") -/obj/item/weapon/gun/pickup(mob/user) +/obj/item/weapon/gun/proc/process_chamber() + return 0 - if(azoom) - azoom.Grant(user) - ..() - -/obj/item/weapon/gun/dropped(mob/user) - - zoom(user,FALSE) - if(azoom) - azoom.Remove(user) - ..() - -/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) - if(flag) return //we're placing gun on a table or in backpack - if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? - Fire(A,user,params) //Otherwise, fire normally. - -/obj/item/weapon/gun/proc/isHandgun() +//check if there's enough ammo/energy/whatever to shoot one time +//i.e if clicking would make it shoot +/obj/item/weapon/gun/proc/can_shoot() return 1 -/obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this +/obj/item/weapon/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) + to_chat(user, "*click*") + playsound(user, 'sound/weapons/empty.ogg', 100, 1) + +/obj/item/weapon/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) + if(recoil) + shake_camera(user, recoil + 1, recoil) + + if(suppressed) + playsound(user, fire_sound, 10, 1) + else + playsound(user, fire_sound, 50, 1) + if(!message) + return + if(pointblank) + user.visible_message("[user] fires [src] point blank at [pbtarget]!", "You fire [src] point blank at [pbtarget]!", "You hear \a [fire_sound_text]!") + else + user.visible_message("[user] fires [src]!", "You fire [src]!", "You hear \a [fire_sound_text]!") + + if(weapon_weight >= WEAPON_MEDIUM) + if(user.get_inactive_hand()) + if(prob(15)) + if(user.drop_item()) + user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") + +/obj/item/weapon/gun/emp_act(severity) + for(var/obj/O in contents) + O.emp_act(severity) + +/obj/item/weapon/gun/afterattack(atom/target, mob/living/user, flag, params) + if(firing_burst) + return + 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 == "harm") //melee attack + return + if(target == user && user.zone_selected != "mouth") //so we can't shoot ourselves (unless mouth selected) + return + + if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can. + var/mob/living/L = user + if(!can_trigger_gun(L)) + return + + if(!can_shoot()) //Just because you can pull the trigger doesn't mean it can't shoot. + shoot_with_empty_chamber(user) + return + + if(flag) + if(user.zone_selected == "mouth") + handle_suicide(user, target, params) + return + + //Exclude lasertag guns from the CLUMSY check. if(clumsy_check) - if(istype(user, /mob/living)) - var/mob/living/M = user - if ((CLUMSY in M.mutations) && prob(50)) - to_chat(M, "[src] blows up in your face.") - M.take_organ_damage(0,20) - M.drop_item() - qdel(src) + if(istype(user)) + if (user.disabilities & CLUMSY && prob(40)) + to_chat(user, "You shoot yourself in the foot with \the [src]!") + var/shot_leg = pick("l_foot", "r_foot") + process_fire(user, user, 0, params, zone_override = shot_leg) + user.drop_item() return - if (!user.IsAdvancedToolUser() || istype(user, /mob/living/simple_animal/diona)) - to_chat(user, "You don't have the dexterity to do this!") + if(weapon_weight == WEAPON_HEAVY && user.get_inactive_hand()) + to_chat(user, "You need both hands free to fire \the [src]!") return - if(istype(user, /mob/living)) - var/mob/living/M = user - if (HULK in M.mutations) - to_chat(M, "Your meaty finger is much too large for the trigger guard!") - return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.species.flags & NOGUNS) - to_chat(user, "Your fingers don't fit in the trigger guard!") - return - if(H.martial_art && H.martial_art.name == "The Sleeping Carp") //great dishonor to famiry - to_chat(user, "Use of ranged weaponry would bring dishonor to the clan.") - return + process_fire(target,user,1,params) + +/obj/item/weapon/gun/proc/can_trigger_gun(var/mob/living/user) + if(!user.can_use_guns(src)) + return 0 + return 1 + +obj/item/weapon/gun/proc/newshot() + return + +/obj/item/weapon/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) add_fingerprint(user) - if(!special_check(user)) + if(semicd) return - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - to_chat(user, "[src] is not ready to fire again!") - return - - if(heavy_weapon) + if(weapon_weight) if(user.get_inactive_hand()) recoil = 4 //one-handed kick else recoil = initial(recoil) - if (istype(in_chamber, /obj/item/projectile/bullet/blank)) // A hacky way of making blank shotgun shells work again. Honk. - in_chamber.delete() - in_chamber = null - return - - user.changeNext_move(CLICK_CD_RANGE) - - var/spread = 0 - var/turf/targloc = get_turf(target) - for(var/f = 1 to burst_size) - if(!process_chambered()) //CHECK - return click_empty(user) - - if(chambered) - for (var/i = max(1, chambered.pellets), i > 0, i--) //Previous way of doing it fucked up math for spreading. This way, even the first projectile is part of the spread code. - if(i != max(1, chambered.pellets)) //Have we fired the initial chambered bullet yet? - in_chamber = new chambered.projectile_type() - ready_projectile(target, user) - prepare_shot(in_chamber) - if(chambered.deviation) - if(randomspread) //Random spread - spread = (rand() - 0.5) * chambered.deviation - else //Smart spread - spread = (i / chambered.pellets - 0.5) * chambered.deviation - if(!process_projectile(targloc, user, params, spread)) - return 0 - else - ready_projectile(target, user) - prepare_shot(in_chamber) - if(!process_projectile(targloc, user, params, spread)) - return 0 - - if(recoil) - spawn() - shake_camera(user, recoil + 1, recoil) - - if(silenced) - playsound(user, fire_sound, 10, 1) - else - playsound(user, fire_sound, 50, 1) - if(f == 1) // Only print this once - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - - if(heavy_weapon) - if(user.get_inactive_hand()) - if(prob(15)) - user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") - user.drop_item() + if(burst_size > 1) + firing_burst = 1 + for(var/i = 1 to burst_size) + if(!user) + break + if(!issilicon(user)) + if( i>1 && !(src in get_both_hands(user))) //for burst firing break - - user.newtonian_move(get_dir(target, user)) + if(chambered) + if(!chambered.fire(target, user, params, , suppressed, zone_override)) + shoot_with_empty_chamber(user) + break + else + if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot + shoot_live_shot(user, 1, target, message) + else + shoot_live_shot(user, 0, target, message) + else + shoot_with_empty_chamber(user) + break + process_chamber() + update_icon() + sleep(fire_delay) + firing_burst = 0 + else + if(chambered) + if(!chambered.fire(target, user, params, , suppressed, zone_override, spread)) + shoot_with_empty_chamber(user) + return + else + if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot + shoot_live_shot(user, 1, target, message) + else + shoot_live_shot(user, 0, target, message) + else + shoot_with_empty_chamber(user) + return + process_chamber() update_icon() + semicd = 1 + spawn(fire_delay) + semicd = 0 + + if(user) if(user.hand) user.update_inv_l_hand() else user.update_inv_r_hand() - sleep(fire_delay) + feedback_add_details("gun_fired","[src.type]") -/obj/item/weapon/gun/proc/ready_projectile(atom/target as mob|obj|turf, mob/living/user) - in_chamber.firer = user - in_chamber.def_zone = user.zone_sel.selecting - in_chamber.original = target - return - -/obj/item/weapon/gun/proc/process_projectile(var/turf/targloc, mob/living/user as mob|obj, params, spread) - var/turf/curloc = user.loc - if (!istype(targloc) || !istype(curloc) || !in_chamber) - return 0 - if(targloc == curloc) //Fire the projectile - user.bullet_act(in_chamber) - del(in_chamber) - update_icon() - return 1 - - in_chamber.loc = get_turf(user) - in_chamber.starting = get_turf(user) - in_chamber.current = curloc - in_chamber.OnFired() - in_chamber.yo = targloc.y - curloc.y - in_chamber.xo = targloc.x - curloc.x - if(params) - var/list/mouse_control = params2list(params) - if(mouse_control["icon-x"]) - in_chamber.p_x = text2num(mouse_control["icon-x"]) - if(mouse_control["icon-y"]) - in_chamber.p_y = text2num(mouse_control["icon-y"]) - if(mouse_control["screen-loc"]) - //Split screen-loc up into X+Pixel_X and Y+Pixel_Y - var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") - - //Split X+Pixel_X up into list(X, Pixel_X) - var/list/screen_loc_X = splittext(screen_loc_params[1],":") - - //Split Y+Pixel_Y up into list(Y, Pixel_Y) - var/list/screen_loc_Y = splittext(screen_loc_params[2],":") - - var/x = text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32 - var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32 - var/ox = round(480/2) //"origin" x - Basically center of the screen. This is a bad way of doing it because if you are able to view MORE than 17 tiles at a time your aim will get fucked. - var/oy = round(480/2) //"origin" y - Basically center of the screen. - - var/angle = Atan2(y - oy, x - ox) - - in_chamber.Angle = angle - - if(istype(user, /mob/living/carbon)) //Increase spread based on shock - var/mob/living/carbon/mob = user - if(mob.shock_stage > 120) - spread += rand(-5,5) - else if(mob.shock_stage > 70) - spread += rand(-2,2) - - if(spread) - in_chamber.Angle += spread - if(in_chamber) - in_chamber.process() - in_chamber = null - return 1 - -/obj/item/weapon/gun/proc/can_fire() - return process_chambered() - -/obj/item/weapon/gun/proc/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return in_chamber.check_fire(target,user) - -/obj/item/weapon/gun/proc/click_empty(mob/user = null) - if (user) - user.visible_message("*click click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) +/obj/item/weapon/gun/attack(mob/M as mob, mob/user) + if(user.a_intent == "harm") //Flogging + ..() else - src.visible_message("*click click*") - playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) + return -/obj/item/weapon/gun/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - //Suicide handling. - if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot) - mouthshoot = 1 - M.visible_message(" [user] sticks their gun in their mouth, ready to pull the trigger...") - if(!do_after(user, 40, target = M)) - M.visible_message(" [user] decided life was worth living") - mouthshoot = 0 - return - if (process_chambered()) - user.visible_message("[user] pulls the trigger.") - if(silenced) - playsound(user, fire_sound, 10, 1) - else - playsound(user, fire_sound, 50, 1) - if(istype(in_chamber, /obj/item/projectile/lasertag) || istype(in_chamber, /obj/item/projectile/bullet/reusable/foam_dart)) - user.show_message("You feel rather silly, trying to commit suicide with a toy.") - mouthshoot = 0 - return - in_chamber.on_hit(M) - if (in_chamber.damage_type != STAMINA) - user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) - user.death() - else - to_chat(user, "Ow...") - user.apply_effect(110,STAMINA,0) - del(in_chamber) - mouthshoot = 0 - return - else - click_empty(user) - mouthshoot = 0 - return - - if (src.process_chambered()) - //Point blank shooting if on harm intent or target we were targeting. - if(user.a_intent == I_HARM) - user.visible_message("\red \The [user] fires \the [src] point blank at [M]!") - if(istype(in_chamber)) in_chamber.damage *= 1.3 - Fire(M,user,0,0,1) - return - else if(target && M in target) - Fire(M,user,0,0,1) ///Otherwise, shoot! - return - else - return ..() //Pistolwhippin' - - -/obj/item/weapon/gun/attackby(var/obj/item/A as obj, mob/user as mob, params) - if(istype(A, /obj/item/device/flashlight/seclite)) - var/obj/item/device/flashlight/seclite/S = A +/obj/item/weapon/gun/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/device/flashlight/seclite)) + var/obj/item/device/flashlight/seclite/S = I if(can_flashlight) if(!F) - if(user.l_hand != src && user.r_hand != src) - to_chat(user, "You'll need [src] in your hands to do that.") + if(!user.unEquip(I)) return - user.drop_item() to_chat(user, "You click [S] into place on [src].") if(S.on) - set_light(0) + SetLuminosity(0) F = S - A.loc = src + I.loc = src update_icon() update_gunlight(user) verbs += /obj/item/weapon/gun/proc/toggle_gunlight - if(istype(A, /obj/item/weapon/screwdriver)) - if(F) - if(user.l_hand != src && user.r_hand != src) - to_chat(user, "You'll need [src] in your hands to do that.") - return + var/datum/action/A = new /datum/action/item_action/toggle_gunlight(src) + if(loc == user) + A.Grant(user) + + if(istype(I, /obj/item/weapon/screwdriver)) + if(F && can_flashlight) for(var/obj/item/device/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") F = null @@ -370,8 +259,13 @@ S.update_brightness(user) update_icon() verbs -= /obj/item/weapon/gun/proc/toggle_gunlight + for(var/datum/action/item_action/toggle_gunlight/TGL in actions) + qdel(TGL) + + if(unique_rename) + if(istype(I, /obj/item/weapon/pen)) + rename_gun(user) ..() - return /obj/item/weapon/gun/proc/toggle_gunlight() set name = "Toggle Gunlight" @@ -383,15 +277,14 @@ var/mob/living/carbon/human/user = usr if(!isturf(user.loc)) - to_chat(user, "You cannot turn the light on while in this [user.loc].") + to_chat(user, "You cannot turn the light on while in this [user.loc]!") F.on = !F.on to_chat(user, "You toggle the gunlight [F.on ? "on":"off"].") playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_gunlight(user) - return -/obj/item/weapon/gun/proc/update_gunlight(var/mob/user = null) +/obj/item/weapon/gun/proc/update_gunlight(mob/user = null) if(F) if(F.on) set_light(F.brightness_on) @@ -400,7 +293,84 @@ update_icon() else set_light(0) + +/obj/item/weapon/gun/pickup(mob/user) + ..() + if(azoom) + azoom.Grant(user) + +/obj/item/weapon/gun/dropped(mob/user) + ..() + zoom(user,FALSE) + if(azoom) + azoom.Remove(user) + +/obj/item/weapon/gun/AltClick(mob/user) + ..() + if(user.incapacitated()) + to_chat(user, "You can't do that right now!") return + if(unique_reskin && !reskinned && loc == user) + reskin_gun(user) + +/obj/item/weapon/gun/proc/reskin_gun(mob/M) + var/choice = input(M,"Warning, you can only reskin your weapon once!","Reskin Gun") in options + + if(src && choice && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) + if(options[choice] == null) + return + if(sawn_state == SAWN_OFF) + icon_state = options[choice] + "-sawn" + else + icon_state = options[choice] + current_skin = icon_state + to_chat(M, "Your gun is now skinned as [choice]. Say hello to your new friend.") + reskinned = 1 + +/obj/item/weapon/gun/proc/rename_gun(mob/M) + var/input = stripped_input(M,"What do you want to name the gun?", ,"", MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) + name = input + to_chat(M, "You name the gun [input]. Say hello to your new friend.") + return + +/obj/item/weapon/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params) + if(!ishuman(user) || !ishuman(target)) + return + + if(semicd) + return + + if(user == target) + target.visible_message("[user] sticks [src] in their mouth, ready to pull the trigger...", \ + "You stick [src] in your mouth, ready to pull the trigger...") + else + target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \ + "[user] points [src] at your head, ready to pull the trigger...") + + semicd = 1 + + if(!do_mob(user, target, 120) || user.zone_selected != "mouth") + if(user) + if(user == target) + user.visible_message("[user] decided life was worth living.") + else if(target && target.Adjacent(user)) + target.visible_message("[user] has decided to spare [target]'s life.", "[user] has decided to spare your life!") + semicd = 0 + return + + semicd = 0 + + target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!") + + if(chambered && chambered.BB) + chambered.BB.damage *= 5 + + process_fire(target, user, 1, params) + +/obj/item/weapon/gun/proc/isHandgun() + return 1 ///////////// // ZOOMING // @@ -424,8 +394,6 @@ gun.zoom(L, FALSE) ..() - - /obj/item/weapon/gun/proc/zoom(mob/living/user, forced_zoom) if(!user || !user.client) return diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index eeb775be84a..56852f4e1ae 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -115,4 +115,4 @@ /obj/item/projectile/energy/sonic/proc/split() //TODO: create two more projectiles to either side of this one, fire at targets to the side of target turf. - return \ No newline at end of file + return diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 8add6a5caf9..df023424265 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -5,22 +5,22 @@ fire_sound = 'sound/weapons/Taser.ogg' var/obj/item/weapon/stock_parts/cell/power_supply //What type of power cell this uses - var/charge_cost = 1000 //How much energy is needed to fire. - var/cell_type = "/obj/item/weapon/stock_parts/cell" - var/projectile_type = "/obj/item/projectile/beam" - var/modifystate + var/cell_type = /obj/item/weapon/stock_parts/cell + var/modifystate = 0 + var/list/ammo_type = list(/obj/item/ammo_casing/energy) + var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next. var/can_charge = 1 - - //self-recharging - var/self_recharge = 0 //if set, the weapon will recharge itself + var/charge_sections = 4 + ammo_x_offset = 2 + var/shaded_charge = 0 //if this gun uses a stateful charge bar for more detail + var/selfcharge = 0 var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically - var/recharge_time = 4 var/charge_tick = 0 + var/charge_delay = 4 /obj/item/weapon/gun/energy/emp_act(severity) - if(power_supply) - power_supply.use(round(power_supply.charge / severity)) - update_icon() + power_supply.use(round(power_supply.charge / severity)) + update_icon() /obj/item/weapon/gun/energy/New() ..() @@ -29,7 +29,15 @@ else power_supply = new(src) power_supply.give(power_supply.maxcharge) - if(self_recharge) + var/obj/item/ammo_casing/energy/shot + for (var/i = 1, i <= ammo_type.len, i++) + var/shottype = ammo_type[i] + shot = new shottype(src) + ammo_type[i] = shot + shot = ammo_type[select] + fire_sound = shot.fire_sound + fire_delay = shot.delay + if(selfcharge) processing_objects.Add(src) update_icon() @@ -39,27 +47,122 @@ return ..() /obj/item/weapon/gun/energy/process() - if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the cyborg + if(selfcharge) //Every [recharge_time] ticks, recharge a shot for the cyborg charge_tick++ - if(charge_tick < recharge_time) return 0 + if(charge_tick < recharge_time) + return 0 charge_tick = 0 - - if(!power_supply || power_supply.charge >= power_supply.maxcharge) + if(!power_supply) return 0 // check if we actually need to recharge - if(use_external_power) var/obj/item/weapon/stock_parts/cell/external = get_external_power_supply() if(!external || !external.use(charge_cost/10)) //Take power from the borg... return 0 //Note, uses /10 because of shitty mods to the cell system - power_supply.give(charge_cost) //... to recharge the shot update_icon() - return 1 -/obj/item/weapon/gun/energy/proc/get_external_power_supply() +/obj/item/weapon/gun/energy/attack_self(mob/living/user as mob) + if(ammo_type.len > 1) + select_fire(user) + update_icon() + +/obj/item/weapon/gun/energy/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) + newshot() //prepare a new shot + ..() + +/obj/item/weapon/gun/energy/can_shoot() + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + return power_supply.charge >= shot.e_cost + +/obj/item/weapon/gun/energy/newshot() + if (!ammo_type || !power_supply) + return + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... + chambered = shot //...prepare a new shot based on the current ammo type selected + chambered.newshot() + return + +/obj/item/weapon/gun/energy/process_chamber() + if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... + var/obj/item/ammo_casing/energy/shot = chambered + power_supply.use(shot.e_cost)//... drain the power_supply cell + chambered = null //either way, released the prepared shot + return + +/obj/item/weapon/gun/energy/proc/select_fire(mob/living/user) + select++ + if (select > ammo_type.len) + select = 1 + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + fire_sound = shot.fire_sound + fire_delay = shot.delay + if (shot.select_name) + to_chat(user, "[src] is now set to [shot.select_name].") + update_icon() + return + +/obj/item/weapon/gun/energy/update_icon() + overlays.Cut() + var/ratio = Ceiling((power_supply.charge / power_supply.maxcharge) * charge_sections) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + var/iconState = "[icon_state]_charge" + var/itemState = null + if(!initial(item_state)) + itemState = icon_state + if (modifystate) + overlays += "[icon_state]_[shot.select_name]" + iconState += "_[shot.select_name]" + if(itemState) + itemState += "[shot.select_name]" + if(power_supply.charge < shot.e_cost) + overlays += "[icon_state]_empty" + else + if(!shaded_charge) + for(var/i = ratio, i >= 1, i--) + overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1)) + else + overlays += image(icon = icon, icon_state = "[icon_state]_charge[ratio]") + if(F && can_flashlight) + var/iconF = "flight" + if(F.on) + iconF = "flight_on" + overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + if(itemState) + itemState += "[ratio]" + item_state = itemState + +/obj/item/weapon/gun/energy/ui_action_click() + toggle_gunlight() + +/obj/item/weapon/gun/energy/suicide_act(mob/user) + if (src.can_shoot()) + user.visible_message("[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.") + sleep(25) + if(user.l_hand == src || user.r_hand == src) + user.visible_message("[user] melts \his face off with the [src.name]!") + playsound(loc, fire_sound, 50, 1, -1) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + power_supply.use(shot.e_cost) + update_icon() + return(FIRELOSS) + else + user.visible_message("[user] panics and starts choking to death!") + return(OXYLOSS) + else + user.visible_message("[user] is pretending to blow \his brains out with the [src.name]! It looks like \he's trying to commit suicide!") + playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + return (OXYLOSS) + +/obj/item/weapon/gun/energy/proc/robocharge() if(isrobot(src.loc)) var/mob/living/silicon/robot/R = src.loc - return R.cell + if(R && R.cell) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot + if(R.cell.use(shot.e_cost/10)) //Take power from the borg... //Divided by 10 because cells and charge costs are fucked. + power_supply.give(shot.e_cost) //... to recharge the shot + +/obj/item/weapon/gun/energy/proc/get_external_power_supply() if(istype(src.loc, /obj/item/rig_module)) var/obj/item/rig_module/module = src.loc if(module.holder && module.holder.wearer) @@ -69,29 +172,3 @@ if(istype(suit)) return suit.cell return null - -/obj/item/weapon/gun/energy/process_chambered() - if(in_chamber) return 1 - if(!power_supply) return 0 - if(!power_supply.use(charge_cost)) return 0 - if(!projectile_type) return 0 - in_chamber = new projectile_type(src) - return 1 - -/obj/item/weapon/gun/energy/update_icon() - if(cell_type) - var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 - if(modifystate) - icon_state = "[modifystate][ratio]" - else - icon_state = "[initial(icon_state)][ratio]" - else - icon_state = "energy0" - overlays.Cut() - if(F) - if(F.on) - overlays += "flight-on" - else - overlays += "flight" - return diff --git a/code/modules/projectiles/guns/energy/advtaser.dm b/code/modules/projectiles/guns/energy/advtaser.dm deleted file mode 100644 index 8601a388f15..00000000000 --- a/code/modules/projectiles/guns/energy/advtaser.dm +++ /dev/null @@ -1,40 +0,0 @@ -/obj/item/weapon/gun/energy/advtaser - name = "hybrid taser" - desc = "A hybrid taser designed to fire both short-range high-power electrodes and long-range disabler beams." - icon_state = "advtaser" - item_state = null //so the human update icon uses the icon_state instead. - cell_type = "/obj/item/weapon/stock_parts/cell" - origin_tech = null - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" - charge_cost = 2000 - modifystate = "advtaserstun" - can_flashlight = 1 - fire_delay = 15 - - var/mode = 0 //0 = stun, 1 = disable - - - attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 500 - fire_sound = 'sound/weapons/taser2.ogg' - to_chat(user, "\red [src.name] is now set to Disable.") - projectile_type = "/obj/item/projectile/beam/disabler" - modifystate = "advtaserdisable" - fire_delay = 0 - if(1) - mode = 0 - charge_cost = 2000 - fire_sound = 'sound/weapons/Taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = "/obj/item/projectile/energy/electrode" - modifystate = "advtaserstun" - fire_delay = 15 - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() diff --git a/code/modules/projectiles/guns/energy/blueshield.dm b/code/modules/projectiles/guns/energy/blueshield.dm deleted file mode 100644 index 914b92e19a6..00000000000 --- a/code/modules/projectiles/guns/energy/blueshield.dm +++ /dev/null @@ -1,37 +0,0 @@ -/obj/item/weapon/gun/energy/blueshield - name = "advanced stun revolver" - desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers." - icon_state = "bsgun_stun" - item_state = "gun" - modifystate = "bsgun_stun" - force = 7 - fire_sound = 'sound/weapons/gunshot.ogg' - charge_cost = 2000 - projectile_type = "/obj/item/projectile/energy/electrode" - fire_delay = 15 - var/fire_mode = 0 // 0 for taser, 1 for lethals. - -/obj/item/weapon/gun/energy/blueshield/attack_self(mob/living/user as mob) - if(!fire_mode) - fire_mode = 1 - charge_cost = 1000 - fire_delay = 0 - - fire_sound = 'sound/weapons/Laser.ogg' - projectile_type = "/obj/item/projectile/beam" - modifystate = "bsgun_kill" - - to_chat(user, "You adjust [src.name] to the kill setting.") - - else - fire_mode = 0 - charge_cost = 2000 - fire_delay = 15 - - projectile_type = "/obj/item/projectile/energy/electrode" - fire_sound = 'sound/weapons/gunshot.ogg' - modifystate = "bsgun_stun" - - to_chat(user, "You adjust [src.name] to the stun setting.") - - update_icon() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/hos.dm b/code/modules/projectiles/guns/energy/hos.dm deleted file mode 100644 index 6bcb9992c4d..00000000000 --- a/code/modules/projectiles/guns/energy/hos.dm +++ /dev/null @@ -1,45 +0,0 @@ -/obj/item/weapon/gun/energy/hos - name = "head of security's energy gun" - desc = "This is a modern recreation of the captain's antique laser gun. This gun has several unique fire modes, but lacks the ability to recharge over time." - icon_state = "hoslaser" - item_state = null //so the human update icon uses the icon_state instead. - force = 10 - fire_sound = 'sound/weapons/Taser.ogg' - origin_tech = "combat=3;magnets=2" - charge_cost = 2000 - modifystate = "hoslaserstun" - projectile_type = "/obj/item/projectile/energy/electrode" - fire_delay = 15 - var/mode = 2 - - attack_self(mob/living/user as mob) - switch(mode) - if(2) - mode = 0 - charge_cost = 1000 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = "/obj/item/projectile/beam" - modifystate = "hoslaserkill" - fire_delay = 0 - if(0) - mode = 1 - charge_cost = 500 - fire_sound = 'sound/weapons/taser2.ogg' - to_chat(user, "\red [src.name] is now set to disable.") - projectile_type = "/obj/item/projectile/beam/disabler" - modifystate = "hoslaserdisable" - fire_delay = 0 - if(1) - mode = 2 - charge_cost = 2000 - fire_sound = 'sound/weapons/taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = "/obj/item/projectile/energy/electrode" - modifystate = "hoslaserstun" - fire_delay = 15 - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 330d9136f17..46add8b8b47 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -1,59 +1,63 @@ /obj/item/weapon/gun/energy/laser name = "laser gun" - desc = "a basic weapon designed kill with concentrated energy bolts" + desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal." icon_state = "laser" item_state = "laser" - fire_sound = 'sound/weapons/Laser.ogg' - charge_cost = 760 - w_class = 3.0 + w_class = 3 materials = list(MAT_METAL=2000) origin_tech = "combat=3;magnets=2" - projectile_type = "/obj/item/projectile/beam" + ammo_type = list(/obj/item/ammo_casing/energy/lasergun) + ammo_x_offset = 1 + shaded_charge = 1 /obj/item/weapon/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." - projectile_type = "/obj/item/projectile/practice" + ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 needs_permit = 0 -obj/item/weapon/gun/energy/laser/retro +/obj/item/weapon/gun/energy/laser/retro name ="retro laser gun" icon_state = "retro" - desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." - + desc = "An older model of the basic lasergun, no longer used by Nanotrasen's private security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." + ammo_x_offset = 3 /obj/item/weapon/gun/energy/laser/captain - name = "captain's antique laser gun" + name = "antique laser gun" icon_state = "caplaser" item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 10 origin_tech = null + ammo_x_offset = 3 + selfcharge = 1 - self_recharge = 1 - +/obj/item/weapon/gun/energy/laser/captain/scattershot + name = "scatter shot laser rifle" + icon_state = "lasercannon" + item_state = "laser" + desc = "An industrial-grade heavy-duty laser rifle with a modified laser lense to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theorically infinite use." + origin_tech = "combat=5;materials=4;powerstorage=4" + ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser) /obj/item/weapon/gun/energy/laser/cyborg + can_charge = 0 desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?" -/obj/item/weapon/gun/energy/laser/cyborg/process() - return 1 - -/obj/item/weapon/gun/energy/laser/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell && R.cell.charge >= 83) - R.cell.use(83) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/laser/cyborg/newshot() + ..() + robocharge() /obj/item/weapon/gun/energy/laser/cyborg/emp_act() return +/obj/item/weapon/gun/energy/laser/scatter + name = "scatter laser gun" + desc = "A laser gun equipped with a refraction kit that spreads bolts." + ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser) + +///Laser Cannon /obj/item/weapon/gun/energy/lasercannon name = "accelerator laser cannon" @@ -64,13 +68,18 @@ obj/item/weapon/gun/energy/laser/retro force = 10 flags = CONDUCT slot_flags = SLOT_BACK - fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" - projectile_type = "/obj/item/projectile/beam/laser/accelerator" + ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator) + ammo_x_offset = 3 /obj/item/weapon/gun/energy/lasercannon/isHandgun() return 0 +/obj/item/ammo_casing/energy/laser/accelerator + projectile_type = /obj/item/projectile/beam/laser/accelerator + select_name = "accelerator" + fire_sound = 'sound/weapons/lasercannonfire.ogg' + /obj/item/projectile/beam/laser/accelerator name = "accelerator laser" icon_state = "heavylaser" @@ -87,36 +96,29 @@ obj/item/weapon/gun/energy/laser/retro use_external_power = 1 recharge_time = 10 +/obj/item/weapon/gun/energy/lasercannon/cyborg -/obj/item/weapon/gun/energy/lasercannon/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(250) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/lasercannon/cyborg/newshot() + ..() + robocharge() + +/obj/item/weapon/gun/energy/lasercannon/cyborg/emp_act() + return /obj/item/weapon/gun/energy/xray name = "xray laser gun" desc = "A high-power laser gun capable of expelling concentrated xray blasts." icon_state = "xray" - fire_sound = 'sound/weapons/laser3.ogg' origin_tech = "combat=5;materials=3;magnets=2;syndicate=2" - projectile_type = "/obj/item/projectile/beam/xray" - charge_cost = 500 + ammo_type = list(/obj/item/ammo_casing/energy/xray) /obj/item/weapon/gun/energy/immolator name = "Immolator laser gun" desc = "A modified laser gun, shooting highly concetrated beams with higher intensity that ignites the target, for the cost of draining more power per shot" icon_state = "immolator" item_state = "laser" - fire_sound = 'sound/weapons/laser3.ogg' - projectile_type = "/obj/item/projectile/beam/immolator" + ammo_type = list(/obj/item/ammo_casing/energy/immolator) origin_tech = "combat=4;materials=4;magnets=3;plasmatech=2" - charge_cost = 1250 ////////Laser Tag//////////////////// @@ -124,34 +126,22 @@ obj/item/weapon/gun/energy/laser/retro name = "laser tag gun" icon_state = "bluetag" desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/lasertag/blue" + ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag) origin_tech = "combat=1;magnets=2" clumsy_check = 0 needs_permit = 0 - - self_recharge = 1 - -/obj/item/weapon/gun/energy/laser/bluetag/special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) - return 1 - to_chat(M, "\red You need to be wearing your laser tag vest!") - return 0 + pin = /obj/item/device/firing_pin/tag/blue + ammo_x_offset = 2 + selfcharge = 1 /obj/item/weapon/gun/energy/laser/redtag name = "laser tag gun" icon_state = "redtag" desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/lasertag/red" + ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag) origin_tech = "combat=1;magnets=2" clumsy_check = 0 needs_permit = 0 - - self_recharge = 1 - -/obj/item/weapon/gun/energy/laser/redtag/special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) - return 1 - to_chat(M, "\red You need to be wearing your laser tag vest!") - return 0 \ No newline at end of file + pin = /obj/item/device/firing_pin/tag/red + ammo_x_offset = 2 + selfcharge = 1 diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 5bc164c5d76..b53563c81a7 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -3,169 +3,133 @@ desc = "A basic energy-based gun with two settings: kill and disable." icon_state = "energystun100" item_state = null //so the human update icon uses the icon_state instead. - fire_sound = 'sound/weapons/Taser2.ogg' - charge_cost = 500 - projectile_type = "/obj/item/projectile/beam/disabler" + ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) origin_tech = "combat=3;magnets=2" - modifystate = "energystun" + modifystate = 2 can_flashlight = 1 - - var/mode = 0 //0 = disable, 1 = kill - - - attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 1000 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = "/obj/item/projectile/beam" - modifystate = "energykill" - if(1) - mode = 0 - charge_cost = 500 - fire_sound = 'sound/weapons/Taser2.ogg' - to_chat(user, "\red [src.name] is now set to disable.") - projectile_type = "/obj/item/projectile/beam/disabler" - modifystate = "energystun" - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() + ammo_x_offset = 3 + flight_x_offset = 15 + flight_y_offset = 10 /obj/item/weapon/gun/energy/gun/cyborg desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?" -/obj/item/weapon/gun/energy/gun/cyborg/process() - return 1 - -/obj/item/weapon/gun/energy/gun/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell && R.cell.charge >= 83) - R.cell.use(83) - in_chamber = new projectile_type(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/gun/cyborg/newshot() + ..() + robocharge() +/obj/item/weapon/gun/energy/gun/cyborg/emp_act() + return /obj/item/weapon/gun/energy/gun/mounted name = "mounted energy gun" self_recharge = 1 use_external_power = 1 -/obj/item/weapon/gun/energy/gun/nuclear - name = "Advanced Energy Gun" - desc = "An energy gun with an experimental miniaturized reactor." - icon_state = "nucgun" - origin_tech = "combat=3;materials=5;powerstorage=3" - var/lightfail = 0 - can_flashlight = 0 - can_charge = 0 +/obj/item/weapon/gun/energy/gun/mini + name = "miniature energy gun" + desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: stun and kill." + icon_state = "mini" + item_state = "gun" + w_class = 2 + ammo_x_offset = 2 + charge_sections = 3 + can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update - New() - ..() - processing_objects.Add(src) +/obj/item/weapon/gun/energy/gun/mini/New() + cell.maxcharge = 6000 + cell.charge = 6000 + F = new /obj/item/device/flashlight/seclite(src) + ..() +/obj/item/weapon/gun/energy/gun/mini/update_icon() + ..() + if(F && F.on) + overlays += "mini-light" - Destroy() - processing_objects.Remove(src) - return ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - if((power_supply.charge / power_supply.maxcharge) != 1) - if(!failcheck()) return 0 - power_supply.give(1000) - update_icon() - return 1 - - - proc - failcheck() - lightfail = 0 - if (prob(src.reliability)) return 1 //No failure - if (prob(src.reliability)) - for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it - if (src in M.contents) - to_chat(M, "\red Your gun feels pleasantly warm for a moment.") - else - to_chat(M, "\red You feel a warm sensation.") - M.apply_effect(rand(3,120), IRRADIATE) - lightfail = 1 - else - for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES - if (src in M.contents) - to_chat(M, "\red Your gun's reactor overloads!") - to_chat(M, "\red You feel a wave of heat wash over you.") - M.apply_effect(300, IRRADIATE) - crit_fail = 1 //break the gun so it stops recharging - processing_objects.Remove(src) - update_icon() - return 0 - - - update_charge() - if (crit_fail) - overlays += "nucgun-whee" - return - var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 - overlays += "nucgun-[ratio]" - - - update_reactor() - if(crit_fail) - overlays += "nucgun-crit" - return - if(lightfail) - overlays += "nucgun-medium" - else if ((power_supply.charge/power_supply.maxcharge) <= 0.5) - overlays += "nucgun-light" - else - overlays += "nucgun-clean" - - - update_mode() - if (mode == 0) - overlays += "nucgun-stun" - else if (mode == 1) - overlays += "nucgun-kill" - - emp_act(severity) - ..() - reliability = max(reliability - round(15/severity), 0) //Do not allow it to go negative! - - - update_icon() - overlays.Cut() - update_charge() - update_reactor() - update_mode() +/obj/item/weapon/gun/energy/gun/hos + name = "\improper X-01 MultiPhase Energy Gun" + desc = "This is a expensive, modern recreation of a antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." + icon_state = "hoslaser" + force = 10 + ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler) + ammo_x_offset = 4 +/obj/item/weapon/gun/energy/blueshield + name = "advanced stun revolver" + desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers." + icon_state = "bsgun_stun" + force = 7 + ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos) + ammo_x_offset = 4 /obj/item/weapon/gun/energy/gun/turret name = "hybrid turret gun" desc = "A heavy hybrid energy cannon with two settings: Stun and kill." icon_state = "turretlaser" + item_state = "turretlaser" slot_flags = null w_class = 5 - heavy_weapon = 1 + ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) + weapon_weight = WEAPON_MEDIUM can_flashlight = 0 - projectile_type = /obj/item/projectile/energy/electrode - charge_cost = 1000 - fire_delay = 15 + trigger_guard = TRIGGER_GUARD_NONE + ammo_x_offset = 2 -/obj/item/weapon/gun/energy/gun/turret/update_icon() - icon_state = initial(icon_state) +/obj/item/weapon/gun/energy/gun/nuclear + name = "advanced energy gun" + desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell." + icon_state = "nucgun" + item_state = "nucgun" + origin_tech = "combat=3;materials=5;powerstorage=3" + var/fail_tick = 0 + charge_delay = 5 + pin = null + can_charge = 0 + ammo_x_offset = 1 + ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler) + selfcharge = 1 + +/obj/item/weapon/gun/energy/gun/nuclear/process() + if(fail_tick > 0) + fail_tick-- + ..() + +/obj/item/weapon/gun/energy/gun/nuclear/shoot_live_shot() + failcheck() + update_icon() + ..() + +/obj/item/weapon/gun/energy/gun/nuclear/proc/failcheck() + if(!prob(reliability) && istype(loc, /mob/living)) + var/mob/living/M = loc + switch(fail_tick) + if(0 to 200) + fail_tick += (2*(100-reliability)) + M.rad_act(40) + to_chat(M, "Your [name] feels warmer.") + if(201 to INFINITY) + SSobj.processing.Remove(src) + M.rad_act(80) + crit_fail = 1 + to_chat(M, "Your [name]'s reactor overloads!") + +/obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity) + ..() + reliability = max(reliability - round(15/severity), 0) //Do not allow it to go negative! + +/obj/item/weapon/gun/energy/gun/nuclear/update_icon() + ..() + if(crit_fail) + overlays += "[icon_state]_fail_3" + else + switch(fail_tick) + if(0) + overlays += "[icon_state]_fail_0" + if(1 to 150) + overlays += "[icon_state]_fail_1" + if(151 to INFINITY) + overlays += "[icon_state]_fail_2" /obj/item/weapon/gun/energy/gun/turret/attack_self(mob/living/user as mob) switch(mode) @@ -189,4 +153,4 @@ if(user.l_hand == src) user.update_inv_l_hand() else - user.update_inv_r_hand() \ No newline at end of file + user.update_inv_r_hand() diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index bc7704d709a..b8ddc12a691 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -1,64 +1,26 @@ -/obj/item/weapon/gun/energy/pulse_rifle +/obj/item/weapon/gun/energy/pulse name = "pulse rifle" - desc = "A heavy-duty, pulse-based energy weapon, preferred by front-line combat personnel." + desc = "A heavy-duty, multifaceted energy rifle with three modes. Preferred by front-line combat personnel." icon_state = "pulse" - item_state = null //so the human update icon uses the icon_state instead. + item_state = null + w_class = 4 force = 10 - fire_sound = 'sound/weapons/pulse.ogg' - charge_cost = 200 - projectile_type = "/obj/item/projectile/beam/pulse" - cell_type = "/obj/item/weapon/stock_parts/cell/super" - var/mode = 2 + flags = CONDUCT slot_flags = SLOT_BACK - w_class = 4.0 + ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) + cell_type = "/obj/item/weapon/stock_parts/cell/pulse" - emp_act() - return +/obj/item/weapon/gun/energy/pulse/emp_act(severity) + return - attack_self(mob/living/user as mob) - switch(mode) - if(2) - mode = 0 - charge_cost = 50 - fire_sound = 'sound/weapons/Taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = "/obj/item/projectile/energy/electrode" - if(0) - mode = 1 - charge_cost = 100 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = "/obj/item/projectile/beam" - if(1) - mode = 2 - charge_cost = 200 - fire_sound = 'sound/weapons/pulse.ogg' - to_chat(user, "\red [src.name] is now set to DESTROY.") - projectile_type = "/obj/item/projectile/beam/pulse" - return - - isHandgun() - return 0 - -/obj/item/weapon/gun/energy/pulse_rifle/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) - in_chamber = new projectile_type(src) - return 1 +/obj/item/weapon/gun/energy/pulse/isHandgun() return 0 +/obj/item/weapon/gun/energy/pulse_rifle/cyborg -/obj/item/weapon/gun/energy/pulse_rifle/destroyer - name = "pulse destroyer" - desc = "A heavy-duty, pulse-based energy weapon." - cell_type = "/obj/item/weapon/stock_parts/cell/infinite" - - attack_self(mob/living/user as mob) - to_chat(user, "\red [src.name] has three settings, and they are all DESTROY.") +/obj/item/weapon/gun/energy/pulse_rifle/cyborg/newshot() + ..() + robocharge() /obj/item/weapon/gun/energy/pulse_rifle/carbine name = "pulse carbine" @@ -69,7 +31,8 @@ item_state = "pulse" cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine" can_flashlight = 1 - + flight_x_offset = 18 + flight_y_offset = 12 /obj/item/weapon/gun/energy/pulse_rifle/pistol name = "pulse pistol" @@ -79,15 +42,26 @@ icon_state = "pulse_pistol" item_state = "gun" cell_type = "/obj/item/weapon/stock_parts/cell/pulse/pistol" + can_charge = 0 /obj/item/weapon/gun/energy/pulse_rifle/pistol/isHandgun() return 1 +/obj/item/weapon/gun/energy/pulse_rifle/destroyer + name = "pulse destroyer" + desc = "A heavy-duty, pulse-based energy weapon." + cell_type = "/obj/item/weapon/stock_parts/cell/infinite" + ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse) + +/obj/item/weapon/gun/energy/pulse/destroyer/attack_self(mob/living/user) + to_chat(user, "[src.name] has three settings, and they are all DESTROY.") + /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911 name = "\improper M1911-P" desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people." icon_state = "m1911-p" item_state = "gun" cell_type = "/obj/item/weapon/stock_parts/cell/infinite" - isHandgun() - return 1 \ No newline at end of file + +/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911/isHandgun() + return 1 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d6c0ad7beb3..e0328ac6058 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -8,7 +8,10 @@ w_class = 5.0 flags = CONDUCT slot_flags = SLOT_BACK - projectile_type = "/obj/item/projectile/ion" + ammo_type = list(/obj/item/ammo_casing/energy/ion) + ammo_x_offset = 3 + flight_x_offset = 17 + flight_y_offset = 9 /obj/item/weapon/gun/energy/ionrifle/emp_act(severity) return @@ -17,10 +20,12 @@ name = "ion carbine" desc = "The MK.II Prototype Ion Projector is a lightweight carbine version of the larger ion rifle, built to be ergonomic and efficient." icon_state = "ioncarbine" - item_state = "ioncarbine" origin_tech = "combat=4;magnets=4;materials=4" w_class = 3 slot_flags = SLOT_BELT + ammo_x_offset = 2 + flight_x_offset = 18 + flight_y_offset = 11 /obj/item/weapon/gun/energy/decloner name = "biological demolecularisor" @@ -28,8 +33,14 @@ icon_state = "decloner" fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = "combat=5;materials=4;powerstorage=3" - projectile_type = "/obj/item/projectile/energy/declone" + ammo_type = list(/obj/item/ammo_casing/energy/declone) + ammo_x_offset = 1 +/obj/item/weapon/gun/energy/decloner/update_icon() + ..() + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge > shot.e_cost) + overlays += "decloner_spin" /obj/item/weapon/gun/energy/floragun name = "floral somatoray" @@ -37,42 +48,11 @@ icon_state = "floramut100" item_state = "gun" fire_sound = 'sound/effects/stealthoff.ogg' - projectile_type = "/obj/item/projectile/energy/floramut" + ammo_type = list(/obj/item/ammo_casing/energy/flora/yield, /obj/item/ammo_casing/energy/flora/mut) origin_tech = "materials=2;biotech=3;powerstorage=3" - modifystate = "floramut" - var/mode = 0 //0 = mutate, 1 = yield boost - needs_permit = 0 - - self_recharge = 1 - -/obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 1000 - to_chat(user, "\red The [src.name] is now set to increase yield.") - projectile_type = "/obj/item/projectile/energy/florayield" - modifystate = "florayield" - if(1) - mode = 0 - charge_cost = 1000 - to_chat(user, "\red The [src.name] is now set to induce mutations.") - projectile_type = "/obj/item/projectile/energy/floramut" - modifystate = "floramut" - update_icon() - return - - -/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, flag) - - if(flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/tray = target - if(process_chambered()) - user.visible_message("\red \The [user] fires \the [src] into \the [tray]!") - Fire(target,user) - return - - ..() + modifystate = 1 + ammo_x_offset = 1 + selfcharge = 1 /obj/item/weapon/gun/energy/meteorgun name = "meteor gun" @@ -80,13 +60,10 @@ icon_state = "riotgun" item_state = "c20r" w_class = 4 - projectile_type = "/obj/item/projectile/meteor" + ammo_type = list(/obj/item/ammo_casing/energy/meteor) cell_type = "/obj/item/weapon/stock_parts/cell/potato" clumsy_check = 0 //Admin spawn only, might as well let clowns use it. - - self_recharge = 1 - recharge_time = 5 //Time it takes for shots to recharge (in ticks) - + selfcharge = 1 /obj/item/weapon/gun/energy/meteorgun/pen name = "meteor pen" @@ -98,119 +75,115 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' w_class = 1 - /obj/item/weapon/gun/energy/mindflayer name = "\improper Mind Flayer" desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon." icon_state = "xray" - projectile_type = "/obj/item/projectile/beam/mindflayer" - fire_sound = 'sound/weapons/Laser.ogg' - -obj/item/weapon/gun/energy/staff/focus - name = "mental focus" - desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." - icon = 'icons/obj/wizard.dmi' - icon_state = "focus" - item_state = "focus" - projectile_type = "/obj/item/projectile/forcebolt" - /* - attack_self(mob/living/user as mob) - if(projectile_type == "/obj/item/projectile/forcebolt") - charge_cost = 200 - to_chat(user, "\red The [src.name] will now strike a small area.") - projectile_type = "/obj/item/projectile/forcebolt/strong" - else - charge_cost = 100 - to_chat(user, "\red The [src.name] will now strike only a single person.") - projectile_type = "/obj/item/projectile/forcebolt" - */ - -/obj/item/weapon/gun/energy/clown - name = "HONK Rifle" - desc = "Clown Planet's finest." - icon_state = "energy" - projectile_type = "/obj/item/projectile/clown" - fire_sound = 'sound/weapons/Gunshot_smg.ogg' - clumsy_check = 0 - - - -/obj/item/weapon/gun/energy/toxgun - name = "plasma pistol" - desc = "A specialized firearm designed to fire lethal bolts of toxins." - icon_state = "toxgun" - fire_sound = 'sound/effects/stealthoff.ogg' - w_class = 3.0 - origin_tech = "combat=4;plasmatech=3" - projectile_type = "/obj/item/projectile/energy/plasma" - -/obj/item/weapon/gun/energy/sniperrifle - name = "L.W.A.P. Sniper Rifle" - desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope." - icon = 'icons/obj/gun.dmi' - icon_state = "esniper" - fire_sound = 'sound/weapons/marauder.ogg' - origin_tech = "combat=6;materials=5;powerstorage=4" - projectile_type = "/obj/item/projectile/beam/sniper" - slot_flags = SLOT_BACK - charge_cost = 2500 - fire_delay = 50 - w_class = 4.0 - zoomable = TRUE - zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. - + item_state = null + ammo_type = list(/obj/item/ammo_casing/energy/mindflayer) + ammo_x_offset = 2 /obj/item/weapon/gun/energy/kinetic_accelerator name = "proto-kinetic accelerator" desc = "According to Nanotrasen accounting, this is mining equipment. It's been modified for extreme power output to crush rocks, but often serves as a miner's first defense against hostile alien life; it's not very powerful unless used in a low pressure environment." icon_state = "kineticgun" item_state = "kineticgun" - projectile_type = "/obj/item/projectile/kinetic" - fire_sound = 'sound/weapons/Kenetic_accel.ogg' - charge_cost = 5000 - cell_type = "/obj/item/weapon/stock_parts/cell/emproof" - needs_permit = 0 // Aparently these are safe to carry? I'm sure Golliaths would disagree. - fire_delay = 16 //Because guncode is bad and you can bug the reload for rapid fire otherwise. - var/recently_fired = 0 + ammo_type = list(/obj/item/ammo_casing/energy/kinetic) + cell_type = /obj/item/weapon/stock_parts/cell/emproof + // Apparently these are safe to carry? I'm sure goliaths would disagree. + var/overheat_time = 16 + unique_rename = 1 + weapon_weight = WEAPON_LIGHT + origin_tech = "combat=2;powerstorage=1" + var/holds_charge = FALSE + var/unique_frequency = FALSE // modified by KA modkits + + var/overheat = FALSE /obj/item/weapon/gun/energy/kinetic_accelerator/super name = "super-kinetic accelerator" desc = "An upgraded, superior version of the proto-kinetic accelerator." icon_state = "kineticgun_u" - projectile_type = "/obj/item/projectile/kinetic/super" - fire_delay = 15 + ammo_type = list(/obj/item/ammo_casing/energy/kinetic/super) + overheat_time = 15 origin_tech = "combat=3;powerstorage=2" /obj/item/weapon/gun/energy/kinetic_accelerator/hyper name = "hyper-kinetic accelerator" desc = "An upgraded, even more superior version of the proto-kinetic accelerator." icon_state = "kineticgun_h" - projectile_type = "/obj/item/projectile/kinetic/hyper" - fire_delay = 13 + ammo_type = list(/obj/item/ammo_casing/energy/kinetic/hyper) + overheat_time = 14 origin_tech = "combat=4;powerstorage=3" /obj/item/weapon/gun/energy/kinetic_accelerator/cyborg - flags = NODROP + holds_charge = TRUE + unique_frequency = TRUE -/obj/item/weapon/gun/energy/kinetic_accelerator/Fire() - if(!recently_fired) - recently_fired = 1 - spawn(fire_delay) - reload(usr) - ..() +/obj/item/weapon/gun/energy/kinetic_accelerator/New() + . = ..() + if(!holds_charge) + empty() + +/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot() + . = ..() + attempt_reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/equipped(mob/user) + . = ..() + if(!can_shoot()) + attempt_reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/dropped() + . = ..() + if(!holds_charge) + // Put it on a delay because moving item from slot to hand + // calls dropped(). + spawn(1) + if(!ismob(loc)) + empty() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty() + power_supply.use(5000) + update_icon() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload() + if(overheat) + return + overheat = TRUE + + var/carried = 0 + if(!unique_frequency) + for(var/obj/item/weapon/gun/energy/kinetic_accelerator/K in \ + loc.GetAllContents()) + + carried++ + + carried = max(carried, 1) + else + carried = 1 + + spawn(overheat_time * carried) + reload() + overheat = FALSE /obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity) return -/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload(mob/living/user) +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload() power_supply.give(5000) - if(!silenced) + if(!suppressed) playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) - else if(user) - to_chat(usr, "You silently charge [src].") - recently_fired = 0 + else + to_chat(loc, "[src] silently charges up.") update_icon() +/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon() + if(!can_shoot()) + icon_state = "[initial(icon_state)]_empty" + else + icon_state = initial(icon_state) + /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow name = "mini energy crossbow" desc = "A weapon favored by syndicate stealth specialists." @@ -219,10 +192,13 @@ obj/item/weapon/gun/energy/staff/focus w_class = 2 materials = list(MAT_METAL=2000) origin_tech = "combat=2;magnets=2;syndicate=5" - silenced = 1 - projectile_type = "/obj/item/projectile/energy/bolt" - fire_sound = 'sound/weapons/Genhit.ogg' - fire_delay = 20 + suppressed = 1 + ammo_type = list(/obj/item/ammo_casing/energy/bolt) + weapon_weight = WEAPON_LIGHT + unique_rename = 0 + overheat_time = 20 + holds_charge = TRUE + unique_frequency = TRUE /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large name = "energy crossbow" @@ -231,8 +207,8 @@ obj/item/weapon/gun/energy/staff/focus w_class = 3 materials = list(MAT_METAL=4000) origin_tech = "combat=2;magnets=2;syndicate=3" //can be further researched for more syndie tech - silenced = 0 - projectile_type = "/obj/item/projectile/energy/bolt/large" + suppressed = 0 + ammo_type = list(/obj/item/ammo_casing/energy/bolt/large) /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large/cyborg desc = "One and done!" @@ -240,27 +216,35 @@ obj/item/weapon/gun/energy/staff/focus origin_tech = null materials = list() +/obj/item/weapon/gun/energy/kinetic_accelerator/suicide_act(mob/user) + if(!suppressed) + playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + user.visible_message("[user] cocks the [src.name] and pretends to blow \his brains out! It looks like \he's trying to commit suicide!") + shoot_live_shot() + return (OXYLOSS) + /obj/item/weapon/gun/energy/plasmacutter name = "plasma cutter" desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off of xenos! Or, you know, mine stuff." icon_state = "plasmacutter" item_state = "plasmacutter" - modifystate = "plasmacutter" + modifystate = -1 origin_tech = "combat=1;materials=3;magnets=2;plasmatech=2;engineering=1" - projectile_type = /obj/item/projectile/plasma + ammo_type = list(/obj/item/ammo_casing/energy/plasma) fire_sound = 'sound/weapons/laser.ogg' flags = CONDUCT | OPENCONTAINER attack_verb = list("attacked", "slashed", "cut", "sliced") - charge_cost = 250 - fire_delay = 15 + force = 12 + sharpness = IS_SHARP can_charge = 0 + heat = 3800 /obj/item/weapon/gun/energy/plasmacutter/examine(mob/user) - ..(user) + ..() if(power_supply) to_chat(user, "[src] is [round(power_supply.percent())]% charged.") -/obj/item/weapon/gun/energy/plasmacutter/attackby(var/obj/item/A, var/mob/user) +/obj/item/weapon/gun/energy/plasmacutter/attackby(obj/item/A, mob/user) if(istype(A, /obj/item/stack/sheet/mineral/plasma)) var/obj/item/stack/sheet/S = A S.use(1) @@ -273,92 +257,34 @@ obj/item/weapon/gun/energy/staff/focus else ..() +/obj/item/weapon/gun/energy/plasmacutter/update_icon() + return + /obj/item/weapon/gun/energy/plasmacutter/adv name = "advanced plasma cutter" icon_state = "adv_plasmacutter" modifystate = "adv_plasmacutter" origin_tech = "combat=3;materials=4;magnets=3;plasmatech=3;engineering=2" - projectile_type = /obj/item/projectile/plasma/adv - fire_delay = 10 - charge_cost = 100 - -/obj/item/weapon/gun/energy/disabler - name = "disabler" - desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." - icon_state = "disabler" - item_state = null - projectile_type = /obj/item/projectile/beam/disabler - fire_sound = 'sound/weapons/taser2.ogg' - cell_type = "/obj/item/weapon/stock_parts/cell" - charge_cost = 500 - -/obj/item/weapon/gun/energy/disabler/cyborg - name = "cyborg disabler" - desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating." - - self_recharge = 1 - use_external_power = 1 - recharge_time = 2.5 - - -/* 3d printer 'pseudo guns' for borgs */ - -/obj/item/weapon/gun/energy/printer - name = "cyborg lmg" - desc = "A machinegun that fires 3d-printed flachettes slowly regenerated using a cyborg's internal power source." - icon_state = "l6closed0" - icon = 'icons/obj/gun.dmi' - fire_sound = 'sound/weapons/Gunshot_smg.ogg' - cell_type = "/obj/item/weapon/stock_parts/cell/secborg" - projectile_type = "/obj/item/projectile/bullet/midbullet3" - charge_cost = 200 //Yeah, let's NOT give them a 300 round clip that recharges, 20 is more reasonable and will actually hurt the borg's battery for overuse. - - self_recharge = 1 - use_external_power = 1 - recharge_time = 5 - -/obj/item/weapon/gun/energy/printer/update_icon() - return + ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv) /obj/item/weapon/gun/energy/wormhole_projector name = "bluespace wormhole projector" desc = "A projector that emits high density quantum-coupled bluespace beams." - projectile_type = "/obj/item/projectile/beam/wormhole" - charge_cost = 0 - fire_sound = "sound/weapons/pulse3.ogg" + ammo_type = list(/obj/item/ammo_casing/energy/wormhole, /obj/item/ammo_casing/energy/wormhole/orange) item_state = null icon_state = "wormhole_projector100" - modifystate = "wormhole_projector" var/obj/effect/portal/blue var/obj/effect/portal/orange - var/mode = 0 //0 = blue 1 = orange +/obj/item/weapon/gun/energy/wormhole_projector/update_icon() + icon_state = "[initial(icon_state)][select]" + item_state = icon_state + return -/obj/item/weapon/gun/energy/wormhole_projector/attack_self(mob/living/user as mob) - switch_modes() - -/obj/item/weapon/gun/energy/wormhole_projector/proc/switch_modes(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - to_chat(user, "[name] is now set to orange.") - projectile_type = "/obj/item/projectile/beam/wormhole/orange" - modifystate = "wormhole_projector_orange" - if(1) - mode = 0 - to_chat(user, "[name] is now set to blue.") - projectile_type = "/obj/item/projectile/beam/wormhole" - modifystate = "wormhole_projector" - update_icon() - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - -/obj/item/weapon/gun/energy/wormhole_projector/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/energy/wormhole_projector/process_chamber() ..() - switch_modes(user) + select_fire() /obj/item/weapon/gun/energy/wormhole_projector/proc/portal_destroyed(obj/effect/portal/P) if(P.icon_state == "portal") @@ -373,7 +299,6 @@ obj/item/weapon/gun/energy/staff/focus /obj/item/weapon/gun/energy/wormhole_projector/proc/create_portal(obj/item/projectile/beam/wormhole/W) var/obj/effect/portal/P = new /obj/effect/portal(get_turf(W), null, src) P.precision = 0 - P.failchance = 0 if(W.name == "bluespace beam") qdel(blue) blue = P @@ -383,4 +308,259 @@ obj/item/weapon/gun/energy/staff/focus orange = P if(orange && blue) blue.target = get_turf(orange) - orange.target = get_turf(blue) \ No newline at end of file + orange.target = get_turf(blue) + +/* 3d printer 'pseudo guns' for borgs */ + +/obj/item/weapon/gun/energy/printer + name = "cyborg lmg" + desc = "A machinegun that fires 3d-printed flachettes slowly regenerated using a cyborg's internal power source." + icon_state = "l6closed0" + icon = 'icons/obj/gun.dmi' + cell_type = "/obj/item/weapon/stock_parts/cell/secborg" + ammo_type = list(/obj/item/ammo_casing/energy/c3dbullet) + can_charge = 0 + +/obj/item/weapon/gun/energy/printer/update_icon() + return + +/obj/item/weapon/gun/energy/printer/emp_act() + return + +/obj/item/weapon/gun/energy/printer/newshot() + ..() + robocharge() + +/obj/item/weapon/gun/energy/laser/instakill + name = "instakill rifle" + icon_state = "instagib" + item_state = "instagib" + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit." + ammo_type = list(/obj/item/ammo_casing/energy/instakill) + force = 60 + origin_tech = null + +/obj/item/weapon/gun/energy/laser/instakill/emp_act() //implying you could stop the instagib + return + +/obj/item/weapon/gun/energy/laser/instakill/red + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design." + icon_state = "instagibred" + item_state = "instagibred" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/red) + +/obj/item/weapon/gun/energy/laser/instakill/blue + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a blue design." + icon_state = "instagibblue" + item_state = "instagibblue" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/blue) + +obj/item/weapon/gun/energy/staff/focus + name = "mental focus" + desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." + icon = 'icons/obj/wizard.dmi' + icon_state = "focus" + item_state = "focus" + ammo_type = list(/obj/item/ammo_casing/forcebolt) + +/obj/item/weapon/gun/energy/clown + name = "HONK Rifle" + desc = "Clown Planet's finest." + icon_state = "energy" + ammo_type = list(/obj/item/ammo_casing/energy/clown) + clumsy_check = 0 + +/obj/item/weapon/gun/energy/toxgun + name = "plasma pistol" + desc = "A specialized firearm designed to fire lethal bolts of toxins." + icon_state = "toxgun" + fire_sound = 'sound/effects/stealthoff.ogg' + w_class = 3 + origin_tech = "combat=4;plasmatech=3" + ammo_type = list(/obj/item/ammo_casing/energy/toxplasma) + +/obj/item/weapon/gun/energy/sniperrifle + name = "L.W.A.P. Sniper Rifle" + desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope." + icon = 'icons/obj/gun.dmi' + icon_state = "esniper" + fire_sound = 'sound/weapons/marauder.ogg' + origin_tech = "combat=6;materials=5;powerstorage=4" + ammo_type = list(/obj/item/ammo_casing/energy/sniper) + slot_flags = SLOT_BACK + w_class = 4 + zoomable = TRUE + zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. + +/obj/item/weapon/gun/energy/temperature + name = "temperature gun" + icon = 'icons/obj/gun_temperature.dmi' + icon_state = "tempgun_4" + item_state = "tempgun_4" + slot_flags = SLOT_BACK + w_class = 4 + fire_sound = 'sound/weapons/pulse3.ogg' + desc = "A gun that changes the body temperature of its targets." + var/temperature = 300 + var/target_temperature = 300 + var/e_cost = 1000 + origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" + + ammo_type = /obj/item/ammo_casing/energy/temp + cell_type = "/obj/item/weapon/stock_parts/cell" + + var/powercost = "" + var/powercostcolor = "" + + var/emagged = 0 //ups the temperature cap from 500 to 1000, targets hit by beams over 500 Kelvin will burst into flames + var/dat = "" + +/obj/item/weapon/gun/energy/temperature/New() + ..() + update_icon() + processing_objects.Add(src) + + +/obj/item/weapon/gun/energy/temperature/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/weapon/gun/energy/temperature/newshot() + ..() + chambered.temperature = temperature + chambered.e_cost = e_cost + +/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) + user.set_machine(src) + update_dat() + user << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x120") + onclose(user, "tempgun") + +/obj/item/weapon/gun/energy/temperature/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/card/emag) && !emagged) + emagged = 1 + to_chat(user, "You double the gun's temperature cap! Targets hit by searing beams will burst into flames!") + desc = "A gun that changes the body temperature of its targets. Its temperature cap has been hacked." + +/obj/item/weapon/gun/energy/temperature/Topic(href, href_list) + if (..()) + return + usr.set_machine(src) + add_fingerprint(usr) + + if(href_list["temp"]) + var/amount = text2num(href_list["temp"]) + if(amount > 0) + target_temperature = min((500 + 500*emagged), target_temperature+amount) + else + target_temperature = max(0, target_temperature+amount) + if (istype(loc, /mob)) + attack_self(loc) + add_fingerprint(usr) + return + + +/obj/item/weapon/gun/energy/temperature/process() + switch(temperature) + if(0 to 100) + charge_cost = 3000 + powercost = "High" + if(100 to 250) + charge_cost = 2000 + powercost = "Medium" + if(251 to 300) + charge_cost = 1000 + powercost = "Low" + if(301 to 400) + charge_cost = 2000 + powercost = "Medium" + if(401 to 1000) + charge_cost = 3000 + powercost = "High" + switch(powercost) + if("High") powercostcolor = "orange" + if("Medium") powercostcolor = "green" + else powercostcolor = "blue" + if(target_temperature != temperature) + var/difference = abs(target_temperature - temperature) + if(difference >= (10 + 40*emagged)) //so emagged temp guns adjust their temperature much more quickly + if(target_temperature < temperature) + temperature -= (10 + 40*emagged) + else + temperature += (10 + 40*emagged) + else + temperature = target_temperature + update_icon() + + if (istype(loc, /mob/living/carbon)) + var /mob/living/carbon/M = loc + if (src == M.machine) + update_dat() + M << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x102") + return + +/obj/item/weapon/gun/energy/temperature/proc/update_dat() + dat = "" + dat += "Current output temperature: " + if(temperature > 500) + dat += "[temperature] ([round(temperature-T0C)]°C)" + dat += " SEARING!" + else if(temperature > (T0C + 50)) + dat += "[temperature] ([round(temperature-T0C)]°C)" + else if(temperature > (T0C - 50)) + dat += "[temperature] ([round(temperature-T0C)]°C)" + else + dat += "[temperature] ([round(temperature-T0C)]°C)" + dat += "
" + dat += "Target output temperature: " //might be string idiocy, but at least it's easy to read + dat += "- " + dat += "- " + dat += "- " + dat += "[target_temperature] " + dat += "+ " + dat += "+ " + dat += "+" + dat += "
" + dat += "Power cost: " + dat += "[powercost]" + +/obj/item/weapon/gun/energy/temperature/proc/update_temperature() + switch(temperature) + if(501 to INFINITY) + item_state = "tempgun_8" + if(400 to 500) + item_state = "tempgun_7" + if(360 to 400) + item_state = "tempgun_6" + if(335 to 360) + item_state = "tempgun_5" + if(295 to 335) + item_state = "tempgun_4" + if(260 to 295) + item_state = "tempgun_3" + if(200 to 260) + item_state = "tempgun_2" + if(120 to 260) + item_state = "tempgun_1" + if(-INFINITY to 120) + item_state = "tempgun_0" + icon_state = item_state + +/obj/item/weapon/gun/energy/temperature/update_icon() + overlays = 0 + update_temperature() + update_charge() + +/obj/item/weapon/gun/energy/temperature/proc/update_charge() + var/charge = power_supply.charge + switch(charge) + if(9000 to INFINITY) overlays += "900" + if(8000 to 9000) overlays += "800" + if(7000 to 8000) overlays += "700" + if(6000 to 7000) overlays += "600" + if(5000 to 6000) overlays += "500" + if(4000 to 5000) overlays += "400" + if(3000 to 4000) overlays += "300" + if(2000 to 3000) overlays += "200" + if(1000 to 2002) overlays += "100" + if(-INFINITY to 1000) overlays += "0" diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 37d22ba5ff7..5e3f5128d6f 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -1,13 +1,11 @@ - /obj/item/weapon/gun/energy/taser name = "taser gun" desc = "A small, low capacity gun used for non-lethal takedowns." icon_state = "taser" item_state = null //so the human update icon uses the icon_state instead. - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" + ammo_type = list(/obj/item/ammo_casing/energy/electrode) + ammo_x_offset = 3 cell_type = "/obj/item/weapon/stock_parts/cell/crap" - fire_delay = 15 /obj/item/weapon/gun/energy/taser/mounted name = "mounted taser gun" @@ -18,67 +16,52 @@ name = "taser gun" desc = "A small, low capacity gun used for non-lethal takedowns." icon_state = "taser" - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" cell_type = "/obj/item/weapon/stock_parts/cell/secborg" - self_recharge = 1 - recharge_time = 10 //Time it takes for shots to recharge (in ticks) +/obj/item/weapon/gun/energy/disabler/cyborg/newshot() + ..() + robocharge() /obj/item/weapon/gun/energy/shock_revolver name = "tesla revolver" desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers." icon_state = "stunrevolver" item_state = "gun" - fire_sound = 'sound/weapons/gunshot.ogg' - projectile_type = "/obj/item/projectile/energy/shock_revolver" - charge_cost = 2000 + ammo_type = list(/obj/item/ammo_casing/energy/shock_revolver) can_flashlight = 0 + shaded_charge = 1 -/obj/item/projectile/energy/shock_revolver - name = "shock bolt" - icon_state = "purple_laser" - var/chain +/obj/item/weapon/gun/energy/gun/advtaser + name = "hybrid taser" + desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams." + icon_state = "advtaser" + ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler) + origin_tech = null + ammo_x_offset = 2 -/obj/item/projectile/energy/shock_revolver/OnFired() - spawn(1) - chain = Beam(firer, icon_state="purple_lightning", icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30) +/obj/item/weapon/gun/energy/gun/advtaser/cyborg + name = "cyborg taser" + desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The weapon contains a limiter to prevent the cyborg's power cell from overheating." + can_flashlight = 0 + can_charge = 0 -/obj/item/projectile/energy/shock_revolver/on_hit(atom/target) - . = ..() - if(isliving(target)) - tesla_zap(src, 3, 10000) - qdel(chain) +/obj/item/weapon/gun/energy/gun/advtaser/cyborg/newshot() + ..() + robocharge() -/obj/item/weapon/gun/energy/crossbow - name = "mini energy-crossbow" - desc = "A weapon favored by many of the syndicates stealth specialists." - icon_state = "crossbow" - w_class = 2.0 - item_state = "crossbow" - materials = list(MAT_METAL=2000) - origin_tech = "combat=2;magnets=2;syndicate=5" - silenced = 1 - fire_sound = 'sound/weapons/Genhit.ogg' - projectile_type = "/obj/item/projectile/energy/bolt" - cell_type = "/obj/item/weapon/stock_parts/cell/crap" - - self_recharge = 1 - -/obj/item/weapon/gun/energy/crossbow/ninja - name = "energy dart thrower" - projectile_type = /obj/item/projectile/energy/dart - -/obj/item/weapon/gun/energy/crossbow/update_icon() - return -/obj/item/weapon/gun/energy/crossbow/largecrossbow - name = "Energy Crossbow" - desc = "A weapon favored by syndicate carp hunters." - icon_state = "crossbowlarge" - silenced = 0 - w_class = 3.0 - force = 10 - materials = list(MAT_METAL=4000) - projectile_type = "/obj/item/projectile/energy/bolt/large" +/obj/item/weapon/gun/energy/disabler + name = "disabler" + desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." + icon_state = "disabler" + item_state = null + ammo_type = list(/obj/item/ammo_casing/energy/disabler) + ammo_x_offset = 3 +/obj/item/weapon/gun/energy/disabler/cyborg + name = "cyborg disabler" + desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating." + can_charge = 0 +/obj/item/weapon/gun/energy/disabler/cyborg/newshot() + ..() + robocharge() diff --git a/code/modules/projectiles/guns/energy/telegun.dm b/code/modules/projectiles/guns/energy/telegun.dm index 3819401e031..e145e2ccbcf 100644 --- a/code/modules/projectiles/guns/energy/telegun.dm +++ b/code/modules/projectiles/guns/energy/telegun.dm @@ -5,11 +5,9 @@ desc = "An extremely high-tech bluespace energy gun capable of teleporting targets to far off locations." icon_state = "telegun" item_state = "ionrifle" - fire_sound = 'sound/weapons/wave.ogg' origin_tech = "combat=6;materials=7;powerstorage=5;bluespace=5;syndicate=4" cell_type = "/obj/item/weapon/stock_parts/cell/crap" - projectile_type = "/obj/item/projectile/energy/teleport" - charge_cost = 1250 + ammo_type = list(/obj/item/ammo_casing/energy/teleport) var/teleport_target = null /obj/item/weapon/gun/energy/telegun/Destroy() @@ -36,4 +34,4 @@ L[tmpname] = R var/desc = input("Please select a location to lock in.", "Telegun Target Interface") in L - teleport_target = L[desc] \ No newline at end of file + teleport_target = L[desc] diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm deleted file mode 100644 index 1e0eb5d08c2..00000000000 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ /dev/null @@ -1,182 +0,0 @@ -/obj/item/weapon/gun/energy/temperature - name = "temperature gun" - icon = 'icons/obj/gun_temperature.dmi' - icon_state = "tempgun_4" - item_state = "tempgun_4" - slot_flags = SLOT_BACK - w_class = 4.0 - fire_sound = 'sound/weapons/pulse3.ogg' - desc = "A gun that changes the body temperature of its targets." - var/temperature = 300 - var/target_temperature = 300 - charge_cost = 90 - origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" - - projectile_type = /obj/item/projectile/temp - cell_type = /obj/item/weapon/stock_parts/cell/temperaturegun - - var/powercost = "" - var/powercostcolor = "" - - var/emagged = 0 //ups the temperature cap from 500 to 1000, targets hit by beams over 500 Kelvin will burst into flames - var/dat = "" - -/obj/item/weapon/gun/energy/temperature/New() - ..() - update_icon() - processing_objects.Add(src) - - -/obj/item/weapon/gun/energy/temperature/Destroy() - processing_objects.Remove(src) - return ..() - - -/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) - user.set_machine(src) - update_dat() - - user << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x120") - onclose(user, "tempgun") - -/obj/item/weapon/gun/energy/temperature/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag) && !emagged) - emagged = 1 - to_chat(user, "You double the gun's temperature cap! Targets hit by searing beams will burst into flames!") - desc = "A gun that changes the body temperature of its targets. Its temperature cap has been hacked." - -/obj/item/weapon/gun/energy/temperature/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - add_fingerprint(usr) - - if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - target_temperature = min((500 + 500*emagged), target_temperature+amount) - else - target_temperature = max(0, target_temperature+amount) - if (istype(loc, /mob)) - attack_self(loc) - add_fingerprint(usr) - return - - -/obj/item/weapon/gun/energy/temperature/process() - switch(temperature) - if(0 to 100) - charge_cost = 300 - powercost = "High" - if(100 to 250) - charge_cost = 180 - powercost = "Medium" - if(251 to 300) - charge_cost = 90 - powercost = "Low" - if(301 to 400) - charge_cost = 180 - powercost = "Medium" - if(401 to 1000) - charge_cost = 300 - powercost = "High" - switch(powercost) - if("High") powercostcolor = "orange" - if("Medium") powercostcolor = "green" - else powercostcolor = "blue" - if(target_temperature != temperature) - var/difference = abs(target_temperature - temperature) - if(difference >= (10 + 40*emagged)) //so emagged temp guns adjust their temperature much more quickly - if(target_temperature < temperature) - temperature -= (10 + 40*emagged) - else - temperature += (10 + 40*emagged) - else - temperature = target_temperature - update_icon() - - if (istype(loc, /mob/living/carbon)) - var /mob/living/carbon/M = loc - if (src == M.machine) - update_dat() - M << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x102") - - - if(power_supply) - power_supply.give(50) - update_icon() - return - -/obj/item/weapon/gun/energy/temperature/proc/update_dat() - dat = "" - dat += "Current output temperature: " - if(temperature > 500) - dat += "[temperature] ([round(temperature-T0C)]°C)" - dat += " SEARING!" - else if(temperature > (T0C + 50)) - dat += "[temperature] ([round(temperature-T0C)]°C)" - else if(temperature > (T0C - 50)) - dat += "[temperature] ([round(temperature-T0C)]°C)" - else - dat += "[temperature] ([round(temperature-T0C)]°C)" - dat += "
" - dat += "Target output temperature: " //might be string idiocy, but at least it's easy to read - dat += "- " - dat += "- " - dat += "- " - dat += "[target_temperature] " - dat += "+ " - dat += "+ " - dat += "+" - dat += "
" - dat += "Power cost: " - dat += "[powercost]" - -/obj/item/weapon/gun/energy/temperature/proc/update_temperature() - switch(temperature) - if(501 to INFINITY) - item_state = "tempgun_8" - if(400 to 500) - item_state = "tempgun_7" - if(360 to 400) - item_state = "tempgun_6" - if(335 to 360) - item_state = "tempgun_5" - if(295 to 335) - item_state = "tempgun_4" - if(260 to 295) - item_state = "tempgun_3" - if(200 to 260) - item_state = "tempgun_2" - if(120 to 260) - item_state = "tempgun_1" - if(-INFINITY to 120) - item_state = "tempgun_0" - icon_state = item_state - -/obj/item/weapon/gun/energy/temperature/proc/update_charge() - var/charge = power_supply.charge - switch(charge) - if(900 to INFINITY) overlays += "900" - if(800 to 900) overlays += "800" - if(700 to 800) overlays += "700" - if(600 to 700) overlays += "600" - if(500 to 600) overlays += "500" - if(400 to 500) overlays += "400" - if(300 to 400) overlays += "300" - if(200 to 300) overlays += "200" - if(100 to 200) overlays += "100" - if(-INFINITY to 100) overlays += "0" - -/obj/item/weapon/gun/energy/temperature/proc/update_user() - if (istype(loc,/mob/living/carbon)) - var/mob/living/carbon/M = loc - M.update_inv_back() - M.update_inv_l_hand() - M.update_inv_r_hand() - -/obj/item/weapon/gun/energy/temperature/update_icon() - overlays = 0 - update_temperature() - update_user() - update_charge() \ No newline at end of file diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm new file mode 100644 index 00000000000..5d883ac7de7 --- /dev/null +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -0,0 +1,54 @@ +/obj/item/weapon/gun/grenadelauncher + name = "grenade launcher" + desc = "a terrible, terrible thing. it's really awful!" + icon = 'icons/obj/gun.dmi' + icon_state = "riotgun" + item_state = "riotgun" + w_class = 4 + throw_speed = 2 + throw_range = 10 + force = 5 + var/list/grenades = new/list() + var/max_grenades = 3 + + materials = list(MAT_METAL=2000) + +/obj/item/weapon/gun/grenadelauncher/examine(mob/user) + if(..(user, 2)) + to_chat(user, "[grenades.len] / [max_grenades] [ammo_name]s.") + +/obj/item/weapon/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params) + if((istype(I, /obj/item/weapon/grenade))) + if(grenades.len < max_grenades) + if(!user.unEquip(I)) + return + I.loc = src + grenades += I + to_chat(user, "You put the [ammo_name] in the [name].") + to_chat(user, "[grenades.len] / [max_grenades] [ammo_name]s.") + else + to_chat(user, "The grenade launcher cannot hold more [ammo_name]s.") + +/obj/item/weapon/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/weapon/gun/grenadelauncher/proc/fire_grenade(atom/target, mob/user) + user.visible_message("[user] fired a grenade!", \ + "You fire the grenade launcher!") + var/obj/item/weapon/grenade/chem_grenade/F = grenades[1] //Now with less copypasta! + grenades -= F + F.loc = 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(icon_state) + "_active" + playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) + spawn(15) + F.prime() diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 13f92bcef86..b64fb37e1c6 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -4,32 +4,25 @@ icon = 'icons/obj/gun.dmi' icon_state = "staffofnothing" item_state = "staff" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' //not really a gun and some toys use these inhands - righthand_file = 'icons/mob/inhands/items_righthand.dmi' fire_sound = 'sound/weapons/emitter.ogg' flags = CONDUCT w_class = 5 - var/projectile_type = /obj/item/projectile/magic var/max_charges = 6 var/charges = 0 var/recharge_rate = 4 var/charge_tick = 0 var/can_charge = 1 + var/ammo_type var/no_den_usage origin_tech = null clumsy_check = 0 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead -/obj/item/weapon/gun/magic/emp_act(severity) - return + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' //not really a gun and some toys use these inhands + righthand_file = 'icons/mob/inhands/items_righthand.dmi' -/obj/item/weapon/gun/magic/process_chambered() - if(in_chamber) return 1 - if(!charges) return 0 - if(!projectile_type) return 0 - in_chamber = new projectile_type(src) - return 1 - -/obj/item/weapon/gun/magic/afterattack(atom/target as mob, mob/living/user as mob, flag) +/obj/item/weapon/gun/magic/afterattack(atom/target, mob/living/user, flag) + newshot() if(no_den_usage) var/area/A = get_area(user) if(istype(A, /area/wizard_station)) @@ -38,22 +31,38 @@ else no_den_usage = 0 ..() - if(charges && !in_chamber && !flag) charges-- + +/obj/item/weapon/gun/magic/can_shoot() + return charges + +/obj/item/weapon/gun/magic/newshot() + if (charges && chambered) + chambered.newshot() + return + +/obj/item/weapon/gun/magic/process_chamber() + if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... + charges--//... drain a charge + return /obj/item/weapon/gun/magic/New() ..() charges = max_charges - if(can_charge) processing_objects.Add(src) + chambered = new ammo_type(src) + if(can_charge) + processing_objects.Add(src) /obj/item/weapon/gun/magic/Destroy() - if(can_charge) processing_objects.Remove(src) + if(can_charge) + processing_objects.Remove(src) return ..() /obj/item/weapon/gun/magic/process() charge_tick++ - if(charge_tick < recharge_rate || charges >= max_charges) return 0 + if(charge_tick < recharge_rate || charges >= max_charges) + return 0 charge_tick = 0 charges++ return 1 @@ -63,4 +72,9 @@ /obj/item/weapon/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "The [name] whizzles quietly.") - return \ No newline at end of file + return + +/obj/item/weapon/gun/magic/suicide_act(mob/user) + user.visible_message("[user] is twisting the [src.name] above \his head, releasing a magical blast! It looks like \he's trying to commit suicide.") + playsound(loc, fire_sound, 50, 1, -1) + return FIRELOSS diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index 16fc552397d..0a52f5ba416 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -4,49 +4,53 @@ obj/item/weapon/gun/magic/staff/ obj/item/weapon/gun/magic/staff/change name = "staff of change" desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" - projectile_type = "/obj/item/projectile/magic/change" + ammo_type = /obj/item/ammo_casing/magic/change icon_state = "staffofchange" item_state = "staffofchange" obj/item/weapon/gun/magic/staff/animate name = "staff of animation" desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." - projectile_type = "/obj/item/projectile/magic/animate" + ammo_type = /obj/item/ammo_casing/magic/animate icon_state = "staffofanimation" item_state = "staffofanimation" obj/item/weapon/gun/magic/staff/healing name = "staff of healing" desc = "An artefact that spits bolts of restoring magic which can remove ailments of all kinds and even raise the dead." - projectile_type = "/obj/item/projectile/magic/resurrection" + ammo_type = /obj/item/ammo_casing/magic/heal icon_state = "staffofhealing" item_state = "staffofhealing" +/obj/item/weapon/gun/magic/staff/healing/handle_suicide() //Stops people trying to commit suicide to heal themselves + return + obj/item/weapon/gun/magic/staff/chaos name = "staff of chaos" desc = "An artefact that spits bolts of chaotic magic that can potentially do anything." - projectile_type = "/obj/item/projectile/magic" + ammo_type = /obj/item/ammo_casing/magic/chaos icon_state = "staffofchaos" item_state = "staffofchaos" max_charges = 10 recharge_rate = 2 - no_den_usage = 1 -/obj/item/weapon/gun/magic/staff/chaos/process_chambered() //Snowflake proc, because this uses projectile_type instead of ammo_casing for whatever reason. - projectile_type = pick(typesof(/obj/item/projectile/magic)) - if(in_chamber) return 1 - if(!charges) return 0 - in_chamber = new projectile_type(src) - return 1 - obj/item/weapon/gun/magic/staff/door name = "staff of door creation" desc = "An artefact that spits bolts of transformative magic that can create doors in walls." - projectile_type = "/obj/item/projectile/magic/door" + ammo_type = /obj/item/ammo_casing/magic/door icon_state = "staffofdoor" item_state = "staffofdoor" max_charges = 10 recharge_rate = 2 + no_den_usage = 1 - no_den_usage = 1 \ No newline at end of file +/obj/item/weapon/gun/magic/staff/honk + name = "staff of the honkmother" + desc = "Honk" + fire_sound = "sound/items/airhorn.ogg" + ammo_type = /obj/item/ammo_casing/magic/honk + icon_state = "honker" + item_state = "honker" + max_charges = 4 + recharge_rate = 8 diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 6be4e0936bf..c6d5bc4bf00 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -1,21 +1,13 @@ /obj/item/weapon/gun/magic/wand/ name = "wand of nothing" desc = "It's not just a stick, it's a MAGIC stick!" - projectile_type = "/obj/item/projectile/magic" + ammo_type = /obj/item/ammo_casing/magic icon_state = "nothingwand" item_state = "wand" w_class = 2 can_charge = 0 max_charges = 100 //100, 50, 50, 34 (max charge distribution by 25%ths) var/variable_charges = 1 - var/drained = 0 - -/obj/item/projectile/magic/fireball/Range() - var/mob/living/L = locate(/mob/living) in (range(src, 1) - firer) - if(L && L.stat != DEAD) - Bump(L) //Magic Bullet #teachthecontroversy - return - ..() /obj/item/weapon/gun/magic/wand/New() if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges @@ -26,26 +18,21 @@ ..() /obj/item/weapon/gun/magic/wand/examine(mob/user) - ..(user) + ..() to_chat(user, "Has [charges] charge\s remaining.") -/obj/item/weapon/gun/magic/wand/attack_self(mob/living/user as mob) - if(charges) - zap_self(user) - else - to_chat(user, "The [name] whizzles quietly.") - ..() +/obj/item/weapon/gun/magic/wand/update_icon() + icon_state = "[initial(icon_state)][charges ? "" : "-drained"]" -/obj/item/weapon/gun/magic/wand/attack(atom/target as mob, mob/living/user as mob) + +/obj/item/weapon/gun/magic/wand/attack(atom/target, mob/living/user) if(target == user) return ..() -/obj/item/weapon/gun/magic/wand/afterattack(atom/target as mob, mob/living/user as mob) - if(!charges && !drained) - to_chat(user, "The [name] whizzles quietly.") - icon_state = "[icon_state]-drained" - drained = 1 +/obj/item/weapon/gun/magic/wand/afterattack(atom/target, mob/living/user) + if(!charges) + shoot_with_empty_chamber(user) return if(target == user) if(no_den_usage) @@ -53,74 +40,83 @@ if(istype(A, /area/wizard_station)) to_chat(user, "You know better than to violate the security of The Den, best wait until you leave to use [src].") return - else - no_den_usage = 0 + else + no_den_usage = 0 zap_self(user) else ..() + update_icon() -/obj/item/weapon/gun/magic/wand/proc/zap_self(mob/living/user as mob) - user.visible_message("[user] zaps \himself with [src]!") +/obj/item/weapon/gun/magic/wand/proc/zap_self(mob/living/user) + user.visible_message("[user] zaps \himself with [src].") + playsound(user, fire_sound, 50, 1) + user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] zapped \himself with a [src]" + +///////////////////////////////////// +//WAND OF DEATH +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/death name = "wand of death" desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail." - projectile_type = "/obj/item/projectile/magic/death" + ammo_type = /obj/item/ammo_casing/magic/death icon_state = "deathwand" max_charges = 3 //3, 2, 2, 1 -/obj/item/weapon/gun/magic/wand/death/zap_self(mob/living/user as mob) - if(alert(user, "You really want to zap yourself with the wand of death?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) - var/message ="You irradiate yourself with pure energy! " - message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") - to_chat(user, message) - user.adjustOxyLoss(500) - charges-- - ..() +/obj/item/weapon/gun/magic/wand/death/zap_self(mob/living/user) + var/message ="You irradiate yourself with pure energy! " + message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") + to_chat(user, message) + user.adjustBurnLoss(500) + charges-- + ..() + +///////////////////////////////////// +//WAND OF HEALING +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/resurrection name = "wand of resurrection" desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason." - projectile_type = "/obj/item/projectile/magic/resurrection" + ammo_type = /obj/item/ammo_casing/magic/heal icon_state = "revivewand" max_charges = 3 //3, 2, 2, 1 -/obj/item/weapon/gun/magic/wand/resurrection/zap_self(mob/living/user as mob) - user.setToxLoss(0) - user.setOxyLoss(0) - user.setCloneLoss(0) - user.SetParalysis(0) - user.SetStunned(0) - user.SetWeakened(0) - user.radiation = 0 - user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss()) - user.reagents.clear_reagents() +/obj/item/weapon/gun/magic/wand/resurrection/zap_self(mob/living/user) + user.revive() to_chat(user, "You feel great!") charges-- ..() +///////////////////////////////////// +//WAND OF POLYMORPH +///////////////////////////////////// + /obj/item/weapon/gun/magic/wand/polymorph name = "wand of polymorph" desc = "This wand is attuned to chaos and will radically alter the victim's form." - projectile_type = "/obj/item/projectile/magic/change" + ammo_type = /obj/item/ammo_casing/magic/change icon_state = "polywand" max_charges = 10 //10, 5, 5, 4 -/obj/item/weapon/gun/magic/wand/polymorph/zap_self(mob/living/user as mob) - if(alert(user, "Your new form might not have arms to zap with... Continue?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) - ..() //because the user mob ceases to exists by the time wabbajack fully resolves - wabbajack(user) - charges-- +/obj/item/weapon/gun/magic/wand/polymorph/zap_self(mob/living/user) + ..() //because the user mob ceases to exists by the time wabbajack fully resolves + wabbajack(user) + charges-- + +///////////////////////////////////// +//WAND OF TELEPORTATION +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/teleport name = "wand of teleportation" desc = "This wand will wrench targets through space and time to move them somewhere else." - projectile_type = "/obj/item/projectile/magic/teleport" + ammo_type = /obj/item/ammo_casing/magic/teleport icon_state = "telewand" max_charges = 10 //10, 5, 5, 4 no_den_usage = 1 -/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user as mob) +/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user) do_teleport(user, user, 10) var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread() smoke.set_up(10, 0, user.loc) @@ -128,25 +124,34 @@ charges-- ..() +///////////////////////////////////// +//WAND OF DOOR CREATION +///////////////////////////////////// + /obj/item/weapon/gun/magic/wand/door name = "wand of door creation" desc = "This particular wand can create doors in any wall for the unscrupulous wizard who shuns teleportation magics." - projectile_type = "/obj/item/projectile/magic/door" + ammo_type = /obj/item/ammo_casing/magic/door icon_state = "doorwand" max_charges = 20 //20, 10, 10, 7 -/obj/item/weapon/gun/magic/wand/door/zap_self() - return +/obj/item/weapon/gun/magic/wand/door/zap_self(mob/living/user) + to_chat(user, "You feel vaguely more open with your feelings.") + charges-- + ..() + +///////////////////////////////////// +//WAND OF FIREBALL +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/fireball name = "wand of fireball" desc = "This wand shoots scorching balls of fire that explode into destructive flames." - projectile_type = "/obj/item/projectile/magic/fireball" + ammo_type = /obj/item/ammo_casing/magic/fireball icon_state = "firewand" max_charges = 8 //8, 4, 4, 3 -/obj/item/weapon/gun/magic/wand/fireball/zap_self(mob/living/user as mob) - if(alert(user, "Zapping yourself with a wand of fireball is probably a bad idea, do it anyway?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) - explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) - charges-- - ..() \ No newline at end of file +/obj/item/weapon/gun/magic/wand/fireball/zap_self(mob/living/user) + explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) + charges-- + ..() diff --git a/code/modules/projectiles/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm similarity index 93% rename from code/modules/projectiles/medbeam.dm rename to code/modules/projectiles/guns/medbeam.dm index 04f8f4b6862..bd5f6b23e79 100644 --- a/code/modules/projectiles/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/chronos.dmi' icon_state = "chronogun" item_state = "chronogun" - w_class = 3.0 + w_class = 3 var/mob/living/current_target var/last_check = 0 @@ -13,7 +13,7 @@ var/active = 0 var/datum/beam/current_beam = null - heavy_weapon = 1 + weapon_weight = WEAPON_MEDIUM /obj/item/weapon/gun/medbeam/New() ..() @@ -34,7 +34,7 @@ on_beam_release(current_target) current_target = null -/obj/item/weapon/gun/medbeam/Fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) +/obj/item/weapon/gun/medbeam/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) add_fingerprint(user) if(current_target) @@ -113,4 +113,4 @@ return /obj/effect/ebeam/medical - name = "medical beam" \ No newline at end of file + name = "medical beam" diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/mounted.dm index d0e023d0d6d..b200dd1d6a7 100644 --- a/code/modules/projectiles/guns/mounted.dm +++ b/code/modules/projectiles/guns/mounted.dm @@ -1,31 +1,31 @@ /obj/item/weapon/gun/energy/advtaser/mounted name = "mounted taser" desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots." - icon_state = "armcannonstun" - item_state = "armcannonstun" - modifystate = "armcannonstun" + icon_state = "taser" + item_state = "armcannonstun4" force = 5 - self_recharge = 1 flags = NODROP - slot_flags = null - w_class = 5.0 + w_class = 5 can_flashlight = 0 + selfcharge = 1 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead /obj/item/weapon/gun/energy/advtaser/mounted/dropped()//if somebody manages to drop this somehow... + ..() src.loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases. /obj/item/weapon/gun/energy/laser/mounted name = "mounted laser" desc = "An arm mounted cannon that fires lethal lasers. Doesn't come with a charge beam." - icon_state = "armcannonlase" + icon_state = "laser" item_state = "armcannonlase" - modifystate = "armcannonlase" force = 5 - self_recharge = 1 flags = NODROP - slot_flags = null - w_class = 5.0 + w_class = 5 materials = null + selfcharge = 1 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL /obj/item/weapon/gun/energy/laser/mounted/dropped() - src.loc = null \ No newline at end of file + ..() + src.loc = null diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index ffe2cd269b5..fddc09349ab 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -1,22 +1,13 @@ -#define SPEEDLOADER 0 -#define FROM_BOX 1 -#define MAGAZINE 2 - /obj/item/weapon/gun/projectile desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason" name = "projectile gun" icon_state = "pistol" origin_tech = "combat=2;materials=2" - w_class = 3.0 + w_class = 3 materials = list(MAT_METAL=1000) -// recoil = 1 - var/mag_type = "/obj/item/ammo_box/magazine/m10mm" //Removes the need for max_ammo and caliber info + + var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine -// var/obj/item/ammo_casing/chambered = null // The round (not bullet) that is in the chamber. - - - - /obj/item/weapon/gun/projectile/New() ..() @@ -26,31 +17,26 @@ update_icon() return +/obj/item/weapon/gun/projectile/update_icon() + ..() + if(reskinned && current_skin) + icon_state = "[current_skin][suppressed ? "-suppressed" : ""]" + else + icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""]" -/obj/item/weapon/gun/projectile/process_chambered(var/eject_casing = 1, var/empty_chamber = 1 ) -// if(in_chamber) -// return 1 - +/obj/item/weapon/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(isnull(AC) || !istype(AC)) - return 0 + chamber_round() + return if(eject_casing) AC.loc = get_turf(src) //Eject casing onto ground. AC.SpinAnimation(10, 1) //next gen special effects + if(empty_chamber) chambered = null chamber_round() - if(AC.BB) - if(AC.reagents && AC.BB.reagents) - var/datum/reagents/casting_reagents = AC.reagents - casting_reagents.trans_to(AC.BB, casting_reagents.total_volume) //For chemical darts/bullets - qdel(casting_reagents) - in_chamber = AC.BB //Load projectile into chamber. - AC.BB.loc = src //Set projectile loc to gun. - AC.update_icon() - return 1 - return 0 - + return /obj/item/weapon/gun/projectile/proc/chamber_round() if(chambered || !magazine) @@ -60,12 +46,16 @@ chambered.loc = src return +/obj/item/weapon/gun/projectile/can_shoot() + if(!magazine || !magazine.ammo_count(0)) + return 0 + return 1 /obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A - if(!magazine && istype(AM, text2path(mag_type))) + if(!magazine && istype(AM, mag_type)) user.remove_from_mob(AM) magazine = AM magazine.loc = src @@ -79,13 +69,11 @@ if(istype(A, /obj/item/weapon/suppressor)) var/obj/item/weapon/suppressor/S = A if(can_suppress) - if(!silenced) - if(user.l_hand != src && user.r_hand != src) - to_chat(user, "You'll need [src] in your hands to do that.") + if(!suppressed) + if(!user.unEquip(A)) return - user.drop_item() to_chat(user, "You screw [S] onto [src].") - silenced = A + suppressed = A S.oldsound = fire_sound S.initial_w_class = w_class fire_sound = 'sound/weapons/Gunshot_silenced.ogg' @@ -101,39 +89,45 @@ return return 0 -/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob) +/obj/item/weapon/gun/projectile/attack_hand(mob/user) if(loc == user) - if(silenced && can_unsuppress) - var/obj/item/weapon/suppressor/S = silenced + if(suppressed && can_unsuppress) + var/obj/item/weapon/suppressor/S = suppressed if(user.l_hand != src && user.r_hand != src) ..() return to_chat(user, "You unscrew [silenced] from [src].") - user.put_in_hands(silenced) + user.put_in_hands(suppressed) fire_sound = S.oldsound w_class = S.initial_w_class - silenced = 0 + suppressed = 0 update_icon() return ..() /obj/item/weapon/gun/projectile/attack_self(mob/living/user as mob) + var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) magazine.loc = get_turf(src.loc) user.put_in_hands(magazine) magazine.update_icon() magazine = null to_chat(user, "You pull the magazine out of \the [src]!") + else if(chambered) + AC.loc = get_turf(src) + AC.SpinAnimation(10, 1) + chambered = null + to_chat(user, "You unload the round from \the [src]'s chamber.") else to_chat(user, "There's no magazine in \the [src].") update_icon() return /obj/item/weapon/gun/projectile/examine(mob/user) - ..(user) + ..() to_chat(user, "Has [get_ammo()] round\s remaining.") -/obj/item/weapon/gun/projectile/proc/get_ammo(var/countchambered = 1) +/obj/item/weapon/gun/projectile/proc/get_ammo(countchambered = 1) var/boolets = 0 //mature var names for mature people if(chambered && countchambered) boolets++ @@ -141,6 +135,22 @@ boolets += magazine.ammo_count() return boolets +/obj/item/weapon/gun/projectile/suicide_act(mob/user) + if (src.chambered && src.chambered.BB && !src.chambered.BB.nodamage) + user.visible_message("[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.") + sleep(25) + if(user.l_hand == src || user.r_hand == src) + process_fire(user, user, 0, zone_override = "head") + user.visible_message("[user] blows \his brains out with the [src.name]!") + return(BRUTELOSS) + else + user.visible_message("[user] panics and starts choking to death!") + return(OXYLOSS) + else + user.visible_message("[user] is pretending to blow \his brains out with the [src.name]! It looks like \he's trying to commit suicide!") + playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + return (OXYLOSS) + /obj/item/weapon/suppressor name = "suppressor" desc = "A universal syndicate small-arms suppressor for maximum espionage." @@ -150,3 +160,9 @@ w_class = 2 var/oldsound = null var/initial_w_class = null + +/obj/item/weapon/suppressor/specialoffer + name = "cheap suppressor" + desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." + icon = 'icons/obj/gun.dmi' + icon_state = "suppressor" diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index b56344ce039..8e700c92cc0 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -15,7 +15,7 @@ name = "\improper Nanotrasen Saber SMG" desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors." icon_state = "saber" - mag_type = "/obj/item/ammo_box/magazine/smgm9mm" + mag_type = /obj/item/ammo_box/magazine/smgm9mm origin_tech = "combat=4;materials=2" /obj/item/weapon/gun/projectile/automatic/update_icon() @@ -25,7 +25,7 @@ overlays += "[initial(icon_state)]semi" if(select == 1) overlays += "[initial(icon_state)]burst" - icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" + icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" return /obj/item/weapon/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params) @@ -34,7 +34,7 @@ return if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A - if(istype(AM, text2path(mag_type))) + if(istype(AM, mag_type)) if(magazine) to_chat(user, "You perform a tactical reload on \the [src], replacing the magazine.") magazine.forceMove(get_turf(src.loc)) @@ -69,6 +69,9 @@ update_icon() return +/obj/item/weapon/gun/projectile/automatic/can_shoot() + return get_ammo() + /obj/item/weapon/gun/projectile/automatic/proc/empty_alarm() if(!chambered && !get_ammo() && !alarmed) playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) @@ -82,7 +85,7 @@ icon_state = "c20r" item_state = "c20r" origin_tech = "combat=5;materials=2;syndicate=8" - mag_type = "/obj/item/ammo_box/magazine/smgm45" + mag_type = /obj/item/ammo_box/magazine/smgm45 fire_sound = 'sound/weapons/Gunshot_smg.ogg' fire_delay = 2 burst_size = 2 @@ -99,7 +102,7 @@ /obj/item/weapon/gun/projectile/automatic/c20r/update_icon() ..() - icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" + icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" return /obj/item/weapon/gun/projectile/automatic/wt550 @@ -107,7 +110,7 @@ desc = "An outdated personal defense weapon utilized by law enforcement. The WT-550 Automatic Rifle fires 4.6x30mm rounds." icon_state = "wt550" item_state = "arg" - mag_type = "/obj/item/ammo_box/magazine/wt550m9" + mag_type = /obj/item/ammo_box/magazine/wt550m9 fire_delay = 2 can_suppress = 0 burst_size = 1 @@ -123,80 +126,16 @@ desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds." icon_state = "mini-uzi" origin_tech = "combat=5;materials=2;syndicate=8" - mag_type = "/obj/item/ammo_box/magazine/uzim9mm" + mag_type = /obj/item/ammo_box/magazine/uzim9mm burst_size = 2 -/obj/item/weapon/gun/projectile/automatic/l6_saw - name = "\improper L6 SAW" - desc = "A heavily modified 7.62 light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the reciever below the designation." - icon_state = "l6closed100" - item_state = "l6closedmag" - w_class = 5 - slot_flags = 0 - origin_tech = "combat=5;materials=1;syndicate=2" - mag_type = "/obj/item/ammo_box/magazine/m762" - fire_sound = 'sound/weapons/Gunshot3.ogg' - - var/cover_open = 0 - can_suppress = 0 - burst_size = 5 - fire_delay = 3 - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob) - cover_open = !cover_open - to_chat(user, "You [cover_open ? "open" : "close"] [src]'s cover.") - update_icon() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() - if(magazine && magazine.caliber != "a762") - icon_state = "l6[cover_open ? "open" : "closed"]0" - icon_state = "l6[cover_open ? "open" : "closed"][magazine ? round(magazine.ammo_count() * 2, 25) : "-empty"]" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays - if(cover_open) - to_chat(user, "[src]'s cover is open! Close it before firing!") - else - ..() - update_icon() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user as mob) - if(loc != user) - ..() - return //let them pick it up - if(!cover_open || (cover_open && !magazine)) - ..() - else if(cover_open && magazine) - //drop the mag - magazine.update_icon() - magazine.loc = get_turf(src.loc) - user.put_in_hands(magazine) - magazine = null - update_icon() - to_chat(user, "You remove the magazine from [src].") - - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob, params) - if(!cover_open && istype(A, mag_type)) - to_chat(user, "[src]'s cover is closed! You can't insert a new mag!") - return - ..() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/devastator - name = "\improper 'Devastator' LMG" - desc = "A heavily modified L6 SAW designed to chamber wide rounds. Commonly used by elite Syndicate boarding teams " - mag_type = "/obj/item/ammo_box/magazine/m762/buckshot" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/devastator/New() - ..() - mag_type = "/obj/item/ammo_box/magazine/m762" // Workaround so it spawns with a shotgun mag loaded, but can still load regular LMG mags. - /obj/item/weapon/gun/projectile/automatic/m90 name = "\improper M-90gl Carbine" desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off." icon_state = "m90" item_state = "m90" origin_tech = "combat=5;materials=2;syndicate=8" - mag_type = "/obj/item/ammo_box/magazine/m556" + mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/Gunshot_smg.ogg' action_button_name = "Toggle Grenade Launcher" can_suppress = 0 @@ -215,12 +154,11 @@ underbarrel.afterattack(target, user, flag, params) else ..() - empty_alarm() return /obj/item/weapon/gun/projectile/automatic/m90/attackby(var/obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_casing)) - if(istype(A, text2path(underbarrel.magazine.ammo_type))) + if(istype(A, underbarrel.magazine.ammo_type)) underbarrel.attack_self() underbarrel.attackby(A, user, params) else @@ -267,11 +205,11 @@ w_class = 5 slot_flags = 0 origin_tech = "combat=5;materials=1;syndicate=2" - mag_type = "/obj/item/ammo_box/magazine/tommygunm45" + mag_type = /obj/item/ammo_box/magazine/tommygunm45 fire_sound = 'sound/weapons/Gunshot_smg.ogg' can_suppress = 0 - fire_delay = 1 burst_size = 4 + fire_delay = 1 /obj/item/weapon/gun/projectile/automatic/ar name = "ARG" @@ -285,3 +223,40 @@ can_suppress = 0 burst_size = 3 fire_delay = 1 + +// Bulldog shotgun // +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog + name = "\improper 'Bulldog' Shotgun" + desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." + icon_state = "bulldog" + item_state = "bulldog" + w_class = 3.0 + origin_tech = "combat=5;materials=4;syndicate=6" + mag_type = /obj/item/ammo_box/magazine/m12g + fire_sound = 'sound/weapons/Gunshot4.ogg' + can_suppress = 0 + burst_size = 1 + fire_delay = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/New() + ..() + update_icon() + return + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine() + if(magazine) + overlays.Cut() + overlays += "[magazine.icon_state]" + return + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/update_icon() + overlays.Cut() + update_magazine() + icon_state = "bulldog[chambered ? "" : "-e"]" + return + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) + ..() + empty_alarm() + return diff --git a/code/modules/projectiles/guns/projectile/crossbow.dm b/code/modules/projectiles/guns/projectile/crossbow.dm deleted file mode 100644 index 3645899ab21..00000000000 --- a/code/modules/projectiles/guns/projectile/crossbow.dm +++ /dev/null @@ -1,323 +0,0 @@ -//AMMUNITION - -/obj/item/weapon/arrow - - name = "bolt" - desc = "It's got a tip for you - get the point?" - icon = 'icons/obj/weapons.dmi' - icon_state = "bolt" - item_state = "bolt" - throwforce = 8 - w_class = 3.0 - sharp = 1 - edge = 0 - -/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart. - return - -/obj/item/weapon/spike - name = "alloy spike" - desc = "It's about a foot of weird silver metal with a wicked point." - sharp = 1 - edge = 0 - throwforce = 5 - w_class = 2 - icon = 'icons/obj/weapons.dmi' - icon_state = "metal-rod" - item_state = "bolt" - -/obj/item/weapon/arrow/quill - - name = "vox quill" - desc = "A wickedly barbed quill from some bizarre animal." - icon_state = "quill" - item_state = "quill" - throwforce = 5 - -/obj/item/weapon/arrow/rod - - name = "metal rod" - desc = "Don't cry for me, Orithena." - icon_state = "metal-rod" - -/obj/item/weapon/arrow/rod/removed(mob/user) - if(throwforce == 15) // The rod has been superheated - we don't want it to be useable when removed from the bow. - to_chat(user, "[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow.") - var/obj/item/weapon/shard/shrapnel/S = new() - S.loc = get_turf(src) - qdel(src) - -/obj/item/weapon/arrow/baguette - name = "baguette" - desc = "Still warm from the oven!" - icon = 'icons/obj/weapons.dmi' - icon_state = "baguette" - item_state = "baguette" - throwforce = 3 - sharp = 0 - -/obj/item/weapon/gun/launcher/crossbow - - name = "powered crossbow" - desc = "A 2557AD twist on an old classic. Pick up that can." - icon_state = "crossbow" - item_state = "crossbow-solid" - fire_sound = 'sound/weapons/punchmiss.ogg' // TODO: Decent THWOK noise. -// ejectshell = 0 // No spent shells. - mouthshoot = 1 // No suiciding with this weapon, causes runtimes. - fire_sound_text = "a solid thunk" - fire_delay = 25 - - var/tension = 0 // Current draw on the bow. - var/max_tension = 5 // Highest possible tension. - var/release_speed = 5 // Speed per unit of tension. - var/obj/item/weapon/stock_parts/cell/cell = null // Used for firing superheated rods. - var/current_user // Used to check if the crossbow has changed hands since being drawn. - -/obj/item/weapon/gun/launcher/crossbow/emp_act(severity) - if(cell && severity) - cell.use(100*severity) - -/obj/item/weapon/gun/launcher/crossbow/special_check(user) - if(tension <= 0) - to_chat(user, "\red \The [src] is not drawn back!") - return 0 - return 1 - -/obj/item/weapon/gun/launcher/crossbow/update_release_force() - release_force = tension*release_speed - -/obj/item/weapon/gun/launcher/crossbow/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if(!..()) return //Only do this on a successful shot. - icon_state = "crossbow" - tension = 0 - -/obj/item/weapon/gun/launcher/crossbow/attack_self(mob/living/user as mob) - if(tension) - if(in_chamber && in_chamber.loc == src) //Just in case they click it the tick after firing. - user.visible_message("[user] relaxes the tension on [src]'s string and removes [in_chamber].","You relax the tension on [src]'s string and remove [in_chamber].") - in_chamber.loc = get_turf(src) - var/obj/item/weapon/arrow/A = in_chamber - in_chamber = null - A.removed(user) - else - user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.") - tension = 0 - icon_state = "crossbow" - else - draw(user) - -/obj/item/weapon/gun/launcher/crossbow/proc/draw(var/mob/user as mob) - - if(!in_chamber) - to_chat(user, "You don't have anything nocked to [src].") - return - - if(user.restrained()) - return - - current_user = user - user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") - tension = 1 - spawn(25) increase_tension(user) //TODO: This needs to be changed to something less shit. - -/obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob) - - if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. - return - - tension++ - icon_state = "crossbow-drawn" - - if(tension>=max_tension) - tension = max_tension - to_chat(usr, "[src] clunks as you draw the string to its maximum tension!") - else - user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") - spawn(25) increase_tension(user) - -/obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob, params) - if(!in_chamber) - if (istype(W,/obj/item/weapon/arrow)) - user.drop_item() - in_chamber = W - in_chamber.loc = src - user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].") - icon_state = "crossbow-nocked" - return - else if(istype(W,/obj/item/stack/rods)) - var/obj/item/stack/rods/R = W - R.use(1) - in_chamber = new /obj/item/weapon/arrow/rod(src) - in_chamber.fingerprintslast = src.fingerprintslast - in_chamber.loc = src - icon_state = "crossbow-nocked" - user.visible_message("[user] jams [in_chamber] into [src].","You jam [in_chamber] into [src].") - superheat_rod(user) - return - - if(istype(W, /obj/item/weapon/stock_parts/cell)) - if(!cell) - user.drop_item() - W.loc = src - cell = W - to_chat(user, "You jam [cell] into [src] and wire it to the firing coil.") - superheat_rod(user) - else - to_chat(user, "[src] already has a cell installed.") - - else if(istype(W, /obj/item/weapon/screwdriver)) - if(cell) - var/obj/item/C = cell - C.loc = get_turf(user) - to_chat(user, "You jimmy [cell] out of [src] with [W].") - cell = null - else - to_chat(user, "[src] doesn't have a cell installed.") - - else - ..() - -/obj/item/weapon/gun/launcher/crossbow/proc/superheat_rod(var/mob/user) - - if(!user || !cell || !in_chamber) return - if(cell.charge < 500) return - if(in_chamber.throwforce >= 15) return - if(!istype(in_chamber,/obj/item/weapon/arrow/rod)) return - - to_chat(user, "[in_chamber] plinks and crackles as it begins to glow red-hot.") - in_chamber.throwforce = 15 - in_chamber.icon_state = "metal-rod-superheated" - cell.use(500) - - -/obj/item/weapon/gun/launcher/crossbow/french - name = "french powered crossbow" - -/obj/item/weapon/gun/launcher/crossbow/french/attackby(obj/item/W as obj, mob/user as mob, params) - if(!in_chamber) - if (istype(W,/obj/item/weapon/reagent_containers/food/snacks/baguette)) - user.drop_item() - in_chamber = W - in_chamber.loc = src - user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].") - icon_state = "crossbow-nocked" - return - - else if (istype(W,/obj/item/weapon/arrow)) - user.visible_message("\The [src] only takes baguettes.") - return - else if(istype(W,/obj/item/stack/rods)) - user.visible_message("\The [src] only takes baguettes.") - return - - if(istype(W, /obj/item/weapon/stock_parts/cell)) - user.visible_message("The [src] is too simple be adapted with a cell.") - return - - else - ..() - -/obj/item/weapon/gun/launcher/crossbow/french/increase_tension(var/mob/user as mob) - - if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. - return - - tension++ - icon_state = "fcrossbow-drawn" - - if(tension>=max_tension) - tension = max_tension - to_chat(usr, "[src] clunks as you draw the string to its maximum tension!") - else - user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") - spawn(25) increase_tension(user) - -// Crossbow construction. -/obj/item/weapon/crossbowframe - name = "crossbow frame" - desc = "A half-finished crossbow." - icon_state = "crossbowframe0" - item_state = "crossbow-solid" - - var/buildstate = 0 - -/obj/item/weapon/crossbowframe/update_icon() - icon_state = "crossbowframe[buildstate]" - -/obj/item/weapon/crossbowframe/examine(mob/user) - ..(user) - switch(buildstate) - if(1) - to_chat(user, "It has a loose rod frame in place.") - if(2) - to_chat(user, "It has a steel backbone welded in place.") - if(3) - to_chat(user, "It has a steel backbone and a cell mount installed.") - if(4) - to_chat(user, "It has a steel backbone, plastic lath and a cell mount installed.") - if(5) - to_chat(user, "It has a steel cable loosely strung across the lath.") - -/obj/item/weapon/crossbowframe/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/stack/rods)) - if(buildstate == 0) - var/obj/item/stack/rods/R = W - if(R.amount >= 3) - R.use(3) - to_chat(user, "\blue You assemble a backbone of rods around the wooden stock.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least three rods to complete this task.") - return - else if(istype(W,/obj/item/weapon/weldingtool)) - if(buildstate == 1) - var/obj/item/weapon/weldingtool/T = W - if(T.remove_fuel(0,user)) - if(!src || !T.isOn()) return - playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) - to_chat(user, "\blue You weld the rods into place.") - buildstate++ - update_icon() - return - else if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(buildstate == 2) - if(C.amount >= 5) - C.use(5) - to_chat(user, "\blue You wire a crude cell mount into the top of the crossbow.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least five segments of cable coil to complete this task.") - return - else if(buildstate == 4) - if(C.amount >= 5) - C.use(5) - to_chat(user, "\blue You string a steel cable across the crossbow's lath.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least five segments of cable coil to complete this task.") - return - else if(istype(W,/obj/item/stack/sheet/mineral/plastic)) - if(buildstate == 3) - var/obj/item/stack/sheet/mineral/plastic/P = W - if(P.amount >= 3) - P.use(3) - to_chat(user, "\blue You assemble and install a heavy plastic lath onto the crossbow.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least three plastic sheets to complete this task.") - return - else if(istype(W,/obj/item/weapon/screwdriver)) - if(buildstate == 5) - to_chat(user, "\blue You secure the crossbow's various parts.") - new /obj/item/weapon/gun/launcher/crossbow(get_turf(src)) - qdel(src) - return - else - ..() diff --git a/code/modules/projectiles/guns/projectile/grenade launcher.dm b/code/modules/projectiles/guns/projectile/grenade launcher.dm deleted file mode 100644 index 28dc0c3a4b9..00000000000 --- a/code/modules/projectiles/guns/projectile/grenade launcher.dm +++ /dev/null @@ -1,91 +0,0 @@ -/obj/item/weapon/gun/launcher - - name = "launcher" - desc = "A device that launches things." - icon = 'icons/obj/weapons.dmi' - w_class = 5.0 - flags = CONDUCT - slot_flags = SLOT_BACK - - var/release_force = 0 - var/fire_sound_text = "a launcher firing" - -//Check if we're drawing and if the bow is loaded. -/obj/item/weapon/gun/launcher/proc/chamber_round() - return (!isnull(in_chamber)) - -//This should not fit in a combat belt or holster. -/obj/item/weapon/gun/launcher/isHandgun() - return 0 - -//Launchers are mechanical, no other impact. -/obj/item/weapon/gun/launcher/emp_act(severity) - return - -//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile. -/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return - -//Override this to avoid a runtime with suicide handling. -/obj/item/weapon/gun/launcher/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - if (M == user && user.zone_sel.selecting == "mouth") - to_chat(user, "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it.") - return - ..() - -/obj/item/weapon/gun/launcher/proc/update_release_force() - return 0 - -/obj/item/weapon/gun/launcher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if (!user.IsAdvancedToolUser()) - to_chat(user, "\red You don't have the dexterity to do this!") - return 0 - - add_fingerprint(user) - - //Make sure target turfs both exist. - var/turf/curloc = get_turf(user) - var/turf/targloc = get_turf(target) - if (!istype(targloc) || !istype(curloc)) - return 0 - - if(!special_check(user)) - return 0 - - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - to_chat(user, "[src] is not ready to fire again!") - return 0 - - if(!chamber_round()) //CHECK - return click_empty(user) - - if(!in_chamber) - return 0 - - update_release_force() - - playsound(user, fire_sound, 50, 1) - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear [fire_sound_text]!") - - in_chamber.loc = get_turf(user) - in_chamber.throw_at(target,10,release_force) - - sleep(1) - - in_chamber = null - - update_icon() - - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - - return 1 - -/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob) - return \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/launchers.dm b/code/modules/projectiles/guns/projectile/launchers.dm index 6bcca0cdf68..635ab22cc8c 100644 --- a/code/modules/projectiles/guns/projectile/launchers.dm +++ b/code/modules/projectiles/guns/projectile/launchers.dm @@ -1,44 +1,12 @@ //KEEP IN MIND: These are different from gun/grenadelauncher. These are designed to shoot premade rocket and grenade projectiles, not flashbangs or chemistry casings etc. //Put handheld rocket launchers here if someone ever decides to make something so hilarious ~Paprika - -/obj/item/weapon/gun/projectile/automatic/gyropistol - name = "gyrojet pistol" - desc = "A prototype pistol designed to fire self propelled rockets." - icon_state = "gyropistol" - fire_sound = 'sound/effects/Explosion1.ogg' - origin_tech = "combat=3" - mag_type = "/obj/item/ammo_box/magazine/m75" - burst_size = 1 - fire_delay = 0 - -/obj/item/weapon/gun/projectile/automatic/gyropistol/isHandgun() - return 1 - -/obj/item/weapon/gun/projectile/automatic/gyropistol/New() - ..() - update_icon() - return - -/obj/item/weapon/gun/projectile/automatic/gyropistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!chambered && !get_ammo() && !alarmed) - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - alarmed = 1 - return - -/obj/item/weapon/gun/projectile/automatic/gyropistol/update_icon() - ..() - icon_state = "[initial(icon_state)][magazine ? "loaded" : ""]" - return - /obj/item/weapon/gun/projectile/revolver/grenadelauncher//this is only used for underbarrel grenade launchers at the moment, but admins can still spawn it if they feel like being assholes desc = "A break-operated grenade launcher." name = "grenade launcher" icon_state = "dshotgun-sawn" item_state = "gun" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher fire_sound = 'sound/weapons/grenadelaunch.ogg' w_class = 3 @@ -52,7 +20,7 @@ name = "multi grenade launcher" icon_state = "bulldog" item_state = "bulldog" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher/multi" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher/multi /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg desc = "A 6-shot grenade launcher." @@ -60,4 +28,57 @@ icon_state = "mecha_grenadelnchr" /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg/attack_self() - return \ No newline at end of file + return + +/obj/item/weapon/gun/projectile/automatic/gyropistol + name = "gyrojet pistol" + desc = "A prototype pistol designed to fire self propelled rockets." + icon_state = "gyropistol" + fire_sound = 'sound/effects/Explosion1.ogg' + origin_tech = "combat=3" + mag_type = /obj/item/ammo_box/magazine/m75 + burst_size = 1 + fire_delay = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/gyropistol/isHandgun() + return 1 + +/obj/item/weapon/gun/projectile/automatic/gyropistol/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/gyropistol/update_icon() + ..() + icon_state = "[initial(icon_state)][magazine ? "loaded" : ""]" + return + +/obj/item/weapon/gun/projectile/automatic/speargun + name = "kinetic speargun" + desc = "A weapon favored by carp hunters. Fires specialized spears using kinetic energy." + icon_state = "speargun" + item_state = "speargun" + w_class = 4 + force = 10 + can_suppress = 0 + mag_type = /obj/item/ammo_box/magazine/internal/speargun + fire_sound = 'sound/weapons/grenadelaunch.ogg' + burst_size = 1 + fire_delay = 0 + select = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/speargun/update_icon() + return + +/obj/item/weapon/gun/projectile/automatic/speargun/attack_self() + return + +/obj/item/weapon/gun/projectile/automatic/speargun/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/speargun/attackby(obj/item/A, mob/user, params) + var/num_loaded = magazine.attackby(A, user, params, 1) + if(num_loaded) + to_chat(user, "You load [num_loaded] spear\s into \the [src].") + update_icon() + chamber_round() diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 99aded2663b..1a37a97ad7a 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -4,18 +4,18 @@ icon_state = "pistol" w_class = 2 origin_tech = "combat=2;materials=2;syndicate=2" - mag_type = "/obj/item/ammo_box/magazine/m10mm" + mag_type = /obj/item/ammo_box/magazine/m10mm can_suppress = 1 burst_size = 1 fire_delay = 0 action_button_name = null - + /obj/item/weapon/gun/projectile/automatic/pistol/isHandgun() return 1 /obj/item/weapon/gun/projectile/automatic/pistol/update_icon() ..() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" + icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" return /obj/item/weapon/gun/projectile/automatic/pistol/m2411 @@ -24,7 +24,7 @@ icon_state = "m2411" w_class = 3.0 origin_tech = "combat=3;materials=2" - mag_type = "/obj/item/ammo_box/magazine/m45" + mag_type = /obj/item/ammo_box/magazine/m45 can_suppress = 0 /obj/item/weapon/gun/projectile/automatic/pistol/deagle @@ -32,7 +32,7 @@ desc = "A robust .50 AE handgun." icon_state = "deagle" force = 14.0 - mag_type = "/obj/item/ammo_box/magazine/m50" + mag_type = /obj/item/ammo_box/magazine/m50 can_suppress = 0 /obj/item/weapon/gun/projectile/automatic/pistol/deagle/update_icon() @@ -47,4 +47,16 @@ /obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo." icon_state = "deaglecamo" - item_state = "deagleg" \ No newline at end of file + item_state = "deagleg" + +/obj/item/weapon/gun/projectile/automatic/pistol/APS + name = "stechkin APS pistol" + desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo." + icon_state = "aps" + w_class = 3 + origin_tech = "combat=3;materials=2;syndicate=3" + mag_type = /obj/item/ammo_box/magazine/pistolm9mm + can_suppress = 0 + burst_size = 3 + fire_delay = 2 + action_button_name = "Toggle Firemode" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 2cb3c849e4b..66e404a7de8 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -2,57 +2,80 @@ name = "\improper .357 revolver" desc = "A suspicious revolver. Uses .357 ammo." icon_state = "revolver" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder -/obj/item/weapon/gun/projectile/revolver/chamber_round() - if (chambered || !magazine) - return - else if (magazine.ammo_count()) +/obj/item/weapon/gun/projectile/revolver/New() + ..() + if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) + verbs -= /obj/item/weapon/gun/projectile/revolver/verb/spin + +/obj/item/weapon/gun/projectile/revolver/chamber_round(var/spin = 1) + if(spin) chambered = magazine.get_round(1) + else + chambered = magazine.stored_ammo[1] return -/obj/item/weapon/gun/projectile/revolver/process_chambered() +/obj/item/weapon/gun/projectile/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj) + ..() + chamber_round(1) + +/obj/item/weapon/gun/projectile/revolver/process_chamber() return ..(0, 1) -/obj/item/weapon/gun/projectile/revolver/attackby(var/obj/item/A as obj, mob/user as mob, params) - var/num_loaded = 0 - 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/didload = magazine.give_round(AC) - if(didload) - AM.stored_ammo -= AC - num_loaded++ - if(!didload || !magazine.multiload) - break - if(istype(A, /obj/item/ammo_casing)) - var/obj/item/ammo_casing/AC = A - if(magazine.give_round(AC)) - user.drop_item() - AC.loc = src - num_loaded++ +/obj/item/weapon/gun/projectile/revolver/attackby(obj/item/A, mob/user, params) + . = ..() + if(.) + return + var/num_loaded = magazine.attackby(A, user, params, 1) if(num_loaded) - to_chat(user, "You load [num_loaded] shell\s into \the [src]!") + to_chat(user, "You load [num_loaded] shell\s into \the [src].") A.update_icon() update_icon() - chamber_round() + chamber_round(0) -/obj/item/weapon/gun/projectile/revolver/attack_self(mob/living/user as mob) + if(unique_rename) + if(istype(A, /obj/item/weapon/pen)) + rename_gun(user) + +/obj/item/weapon/gun/projectile/revolver/attack_self(mob/living/user) var/num_unloaded = 0 + chambered = null while (get_ammo() > 0) var/obj/item/ammo_casing/CB CB = magazine.get_round(0) - chambered = null - CB.loc = get_turf(src.loc) - CB.SpinAnimation(10, 1) - CB.update_icon() - num_unloaded++ + if(CB) + CB.loc = get_turf(src.loc) + CB.SpinAnimation(10, 1) + CB.update_icon() + num_unloaded++ if (num_unloaded) - to_chat(user, "You unload [num_unloaded] shell\s from [src]!") + to_chat(user, "You unload [num_unloaded] shell\s from [src].") else - to_chat(user, "[src] is empty.") + to_chat(user, "[src] is empty!") -/obj/item/weapon/gun/projectile/revolver/get_ammo(var/countchambered = 0, var/countempties = 1) +/obj/item/weapon/gun/projectile/revolver/verb/spin() + set name = "Spin Chamber" + set category = "Object" + set desc = "Click to spin your revolver's chamber." + + var/mob/M = usr + + if(M.stat || !in_range(M,src)) + return + + if(istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) + var/obj/item/ammo_box/magazine/internal/cylinder/C = magazine + C.spin() + chamber_round(0) + usr.visible_message("[usr] spins [src]'s chamber.", "You spin [src]'s chamber.") + else + verbs -= /obj/item/weapon/gun/projectile/revolver/verb/spin + +/obj/item/weapon/gun/projectile/revolver/can_shoot() + return get_ammo(0,0) + +/obj/item/weapon/gun/projectile/revolver/get_ammo(countchambered = 0, countempties = 1) var/boolets = 0 //mature var names for mature people if (chambered && countchambered) boolets++ @@ -61,119 +84,66 @@ return boolets /obj/item/weapon/gun/projectile/revolver/examine(mob/user) - ..(user) + ..() to_chat(user, "[get_ammo(0,0)] of those are live rounds.") -/obj/item/weapon/gun/projectile/revolver/verb/spin_revolver() - set name = "Spin cylinder" - set desc = "Fun when you're bored out of your skull." - set category = "Object" - - usr.visible_message("[usr] spins the chamber of the revolver.", "You spin the revolver's chamber.") - playsound(src.loc, 'sound/weapons/revolver_spin.ogg', 100, 1) - Spin() - -/obj/item/weapon/gun/projectile/revolver/proc/Spin() - chambered = null - var/random = rand(1, magazine.max_ammo) - if(random <= get_ammo(0,0)) - chamber_round() - update_icon() - -/obj/item/weapon/gun/projectile/revolver/capgun - name = "cap gun" - desc = "Looks almost like the real thing! Ages 8 and up." - origin_tech = "combat=1;materials=1" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/cap" - /obj/item/weapon/gun/projectile/revolver/detective desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds." name = "\improper .38 Mars Special" icon_state = "detective" origin_tech = "combat=2;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/rev38" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 + unique_rename = 1 + unique_reskin = 1 - -/obj/item/weapon/gun/projectile/revolver/detective/special_check(var/mob/living/carbon/human/M) - if(!ghettomodded) - return 1 - if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 - to_chat(M, "[src] blows up in your face!") - M.take_organ_damage(0,20) - M.drop_item() - qdel(src) - return 0 - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun() - set name = "Name Gun" - set category = "Object" - set desc = "Click to rename your gun." - - var/mob/M = usr - var/input = stripped_input(M,"What do you want to name the gun?", ,"", MAX_NAME_LEN) - - if(src && input && !M.stat && in_range(M,src)) - name = input - to_chat(M, "You name the gun [input]. Say hello to your new friend.") - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/verb/reskin_gun() - set name = "Reskin gun" - set category = "Object" - set desc = "Click to reskin your gun." - - var/mob/M = usr - var/list/options = list() +/obj/item/weapon/gun/projectile/revolver/detective/New() + ..() options["The Original"] = "detective" options["Leopard Spots"] = "detective_leopard" options["Black Panther"] = "detective_panther" options["Gold Trim"] = "detective_gold" options["The Peacemaker"] = "detective_peacemaker" - var/choice = input(M,"What do you want to skin the gun to?","Reskin Gun") in options + options["Cancel"] = null - if(src && choice && !M.stat && in_range(M,src)) - icon_state = options[choice] - to_chat(M, "Your gun is now skinned as [choice]. Say hello to your new friend.") - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/weapon/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "") + if(magazine.caliber != initial(magazine.caliber)) + if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 + playsound(user, fire_sound, 50, 1) + to_chat(user, "[src] blows up in your face!") + user.take_organ_damage(0,20) + user.unEquip(src) + return 0 ..() - if(istype(A, /obj/item/weapon/screwdriver) || istype(A, /obj/item/weapon/conversion_kit)) + +/obj/item/weapon/gun/projectile/revolver/detective/attackby(obj/item/A, mob/user, params) + ..() + if(istype(A, /obj/item/weapon/screwdriver)) if(magazine.caliber == "38") - to_chat(user, "You begin to reinforce the barrel of [src].") + to_chat(user, "You begin to reinforce the barrel of [src]...") if(magazine.ammo_count()) afterattack(user, user) //you know the drill - user.visible_message("[src] goes off!", "[src] goes off in your face!") + user.visible_message("[src] goes off!", "[src] goes off in your face!") return - if(do_after(user, 30, target = src)) + if(do_after(user, 30/A.toolspeed, target = src)) if(magazine.ammo_count()) - to_chat(user, "You can't modify it!") + to_chat(user, "You can't modify it!") return - if (istype(A, /obj/item/weapon/conversion_kit)) - ghettomodded = 0 - else - ghettomodded = 1 magazine.caliber = "357" - desc = "[initial(desc)] The barrel and chamber assembly seems to have been modified." - to_chat(user, "You reinforce the barrel of [src]! Now it will fire .357 rounds.") + desc = "The barrel and chamber assembly seems to have been modified." + to_chat(user, "You reinforce the barrel of [src]. Now it will fire .357 rounds.") else - to_chat(user, "You begin to revert the modifications to [src].") + to_chat(user, "You begin to revert the modifications to [src]...") if(magazine.ammo_count()) afterattack(user, user) //and again - user.visible_message("[src] goes off!", "[src] goes off in your face!") + user.visible_message("[src] goes off!", "[src] goes off in your face!") return if(do_after(user, 30, target = src)) if(magazine.ammo_count()) - to_chat(user, "You can't modify it!") + to_chat(user, "You can't modify it!") return - ghettomodded = 0 magazine.caliber = "38" desc = initial(desc) - to_chat(user, "You remove the modifications on [src]! Now it will fire .38 rounds.") - - - + to_chat(user, "You remove the modifications on [src]. Now it will fire .38 rounds.") /obj/item/weapon/gun/projectile/revolver/mateba name = "\improper Unica 6 auto-revolver" @@ -181,6 +151,21 @@ icon_state = "mateba" origin_tech = "combat=2;materials=2" +/obj/item/weapon/gun/projectile/revolver/golden + name = "\improper Golden revolver" + desc = "This ain't no game, ain't never been no show, And I'll gladly gun down the oldest lady you know. Uses .357 ammo." + icon_state = "goldrevolver" + fire_sound = 'sound/weapons/resonator_blast.ogg' + recoil = 8 + +/obj/item/weapon/gun/projectile/revolver/nagant + name = "nagant revolver" + desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo." + icon_state = "nagant" + origin_tech = "combat=3" + can_suppress = 1 + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762 + // A gun to play Russian Roulette! // You can spin the chamber to randomize the position of the bullet. @@ -188,35 +173,95 @@ name = "\improper Russian Revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull." origin_tech = "combat=2;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/rus357" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357 + var/spun = 0 /obj/item/weapon/gun/projectile/revolver/russian/New() ..() Spin() + update_icon() -/obj/item/weapon/gun/projectile/revolver/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj) +/obj/item/weapon/gun/projectile/revolver/russian/proc/Spin() + chambered = null + var/random = rand(1, magazine.max_ammo) + if(random <= get_ammo(0,0)) + chamber_round() + spun = 1 - if(!chambered && target == user) - user.visible_message("\red *click*", "\red *click*") - return +/obj/item/weapon/gun/projectile/revolver/russian/attackby(obj/item/A, mob/user, params) + var/num_loaded = ..() + if(num_loaded) + user.visible_message("[user] loads a single bullet into the revolver and spins the chamber.", "You load a single bullet into the chamber and spin it.") + else + user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") + if(get_ammo() > 0) + Spin() + update_icon() + A.update_icon() + return - if(isliving(target) && isliving(user)) - if(target == user) - var/obj/item/organ/external/affecting = user.zone_sel.selecting - if(affecting == "head") - var/obj/item/ammo_casing/AC = chambered - if(!process_chambered()) - user.visible_message("\red *click*", "\red *click*") - return - if(!in_chamber) - return - var/obj/item/projectile/P = new AC.projectile_type - playsound(user, fire_sound, 50, 1) - user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - if(!P.nodamage) - user.apply_damage(300, BRUTE, affecting, sharp=1) // You are dead, dead, dead. +/obj/item/weapon/gun/projectile/revolver/russian/attack_self(mob/user) + if(!spun && can_shoot()) + user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") + Spin() + else + var/num_unloaded = 0 + while (get_ammo() > 0) + var/obj/item/ammo_casing/CB + CB = magazine.get_round() + chambered = null + CB.loc = get_turf(src.loc) + CB.update_icon() + num_unloaded++ + if (num_unloaded) + to_chat(user, "You unload [num_unloaded] shell\s from [src].") + else + to_chat(user, "[src] is empty.") + +/obj/item/weapon/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) + if(flag) + if(!(target in user.contents) && ismob(target)) + if(user.a_intent == "harm") // Flogging action return - ..() + if(isliving(user)) + if(!can_trigger_gun(user)) + return + if(target != user) + if(ismob(target)) + to_chat(user, "A mechanism prevents you from shooting anyone but yourself!") + return + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(!spun) + to_chat(user, "You need to spin the revolver's chamber first!") + return + + spun = 0 + + if(chambered) + var/obj/item/ammo_casing/AC = chambered + if(AC.fire(user, user)) + playsound(user, fire_sound, 50, 1) + var/zone = check_zone(user.zone_selected) + var/obj/item/bodypart/affecting = H.get_bodypart(zone) + if(zone == "head" || zone == "eyes" || zone == "mouth") + shoot_self(user, affecting) + else + user.visible_message("[user.name] cowardly fires [src] at \his [affecting.name]!", "You cowardly fire [src] at your [affecting.name]!", "You hear a gunshot!") + return + + user.visible_message("*click*") + playsound(user, 'sound/weapons/empty.ogg', 100, 1) + +/obj/item/weapon/gun/projectile/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") + user.apply_damage(300, BRUTE, affecting) + user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a gunshot!") + +/obj/item/weapon/gun/projectile/revolver/capgun + name = "cap gun" + desc = "Looks almost like the real thing! Ages 8 and up." + origin_tech = "combat=1;materials=1" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/cap diff --git a/code/modules/projectiles/guns/projectile/rocket.dm b/code/modules/projectiles/guns/projectile/rocket.dm index e667d9323ce..a82caddeba1 100644 --- a/code/modules/projectiles/guns/projectile/rocket.dm +++ b/code/modules/projectiles/guns/projectile/rocket.dm @@ -10,7 +10,6 @@ force = 5.0 flags = CONDUCT origin_tech = "combat=8;materials=5" - projectile = /obj/item/missile var/missile_speed = 2 var/missile_range = 30 var/max_rockets = 1 @@ -18,7 +17,12 @@ /obj/item/weapon/gun/rocketlauncher/examine(mob/user) if(..(user, 2)) - to_chat(user, "\blue [rockets.len] / [max_rockets] rockets.") + to_chat(user, "[rockets.len] / [max_rockets] rockets.") + +/obj/item/weapon/gun/rocketlauncher/Destroy() + for(var/datum/D in rockets) + qdel(D) + rockets = null /obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/ammo_casing/rocket)) @@ -26,15 +30,15 @@ user.drop_item() I.loc = src rockets += I - to_chat(user, "\blue You put the rocket in [src].") - to_chat(user, "\blue [rockets.len] / [max_rockets] rockets.") + to_chat(user, "You put the rocket in [src].") + to_chat(user, "[rockets.len] / [max_rockets] rockets.") else - to_chat(usr, "\red [src] cannot hold more rockets.") + to_chat(usr, "[src] cannot hold more rockets.") -/obj/item/weapon/gun/rocketlauncher/can_fire() +/obj/item/weapon/gun/rocketlauncher/can_shoot() return rockets.len -/obj/item/weapon/gun/rocketlauncher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/rocketlauncher/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "") if(rockets.len) var/obj/item/ammo_casing/rocket/I = rockets[1] var/obj/item/missile/M = new projectile(user.loc) @@ -47,4 +51,4 @@ qdel(I) return else - to_chat(usr, "\red [src] is empty.") + to_chat(usr, "[src] is empty.") diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm new file mode 100644 index 00000000000..5c4856d2503 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -0,0 +1,179 @@ +/obj/item/weapon/gun/projectile/automatic/l6_saw + name = "\improper L6 SAW" + desc = "A heavily modified 7.62 light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the reciever below the designation." + icon_state = "l6closed100" + item_state = "l6closedmag" + w_class = 5 + slot_flags = 0 + origin_tech = "combat=5;materials=1;syndicate=2" + mag_type = /obj/item/ammo_box/magazine/mm556x45 + weapon_weight = WEAPON_MEDIUM + fire_sound = 'sound/weapons/Gunshot3.ogg' + var/cover_open = 0 + can_suppress = 0 + burst_size = 3 + fire_delay = 1 + +/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user) + cover_open = !cover_open + to_chat(user, "You [cover_open ? "open" : "close"] [src]'s cover.") + update_icon() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() + icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"][suppressed ? "-suppressed" : ""]" + item_state = "l6[cover_open ? "openmag" : "closedmag"]" + +/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays + if(cover_open) + to_chat(user, "[src]'s cover is open! Close it before firing!") + else + ..() + update_icon() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user) + if(loc != user) + ..() + return //let them pick it up + if(!cover_open || (cover_open && !magazine)) + ..() + else if(cover_open && magazine) + //drop the mag + magazine.update_icon() + magazine.loc = get_turf(src.loc) + user.put_in_hands(magazine) + magazine = null + update_icon() + to_chat(user, "You remove the magazine from [src].") + + +/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(obj/item/A, mob/user, params) + . = ..() + if(.) + return + if(!cover_open) + to_chat(user, "[src]'s cover is closed! You can't insert a new mag.") + return + ..() + +//ammo// + +/obj/item/projectile/bullet/saw + damage = 45 + armour_penetration = 5 + +/obj/item/projectile/bullet/saw/bleeding + damage = 20 + armour_penetration = 0 + +/obj/item/projectile/bullet/saw/bleeding/on_hit(atom/target, blocked = 0, hit_zone) + . = ..() + if((blocked != 100) && istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + H.drip(35) + +/obj/item/projectile/bullet/saw/hollow + damage = 60 + armour_penetration = -10 + +/obj/item/projectile/bullet/saw/ap + damage = 40 + armour_penetration = 75 + +/obj/item/projectile/bullet/saw/incen + damage = 7 + armour_penetration = 0 + +obj/item/projectile/bullet/saw/incen/Move() + ..() + var/turf/location = get_turf(src) + if(location) + PoolOrNew(/obj/effect/hotspot, location) + location.hotspot_expose(700, 50, 1) + +/obj/item/projectile/bullet/saw/incen/on_hit(atom/target, blocked = 0) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(3) + M.IgniteMob() + +//magazines// + +/obj/item/ammo_box/magazine/mm556x45 + name = "box magazine (5.56x45mm)" + icon_state = "a762-50" + origin_tech = "combat=2" + ammo_type = /obj/item/ammo_casing/mm556x45 + caliber = "mm55645" + max_ammo = 50 + +/obj/item/ammo_box/magazine/mm556x45/bleeding + name = "box magazine (Bleeding 5.56x45mm)" + origin_tech = "combat=3" + ammo_type = /obj/item/ammo_casing/mm556x45/bleeding + +/obj/item/ammo_box/magazine/mm556x45/hollow + name = "box magazine (Hollow-Point 5.56x45mm)" + origin_tech = "combat=3" + ammo_type = /obj/item/ammo_casing/mm556x45/hollow + +/obj/item/ammo_box/magazine/mm556x45/ap + name = "box magazine (Armor Penetrating 5.56x45mm)" + origin_tech = "combat=4" + ammo_type = /obj/item/ammo_casing/mm556x45/ap + +/obj/item/ammo_box/magazine/mm556x45/incen + name = "box magazine (Incendiary 5.56x45mm)" + origin_tech = "combat=4" + ammo_type = /obj/item/ammo_casing/mm556x45/incen + +/obj/item/ammo_box/magazine/mm556x45/update_icon() + ..() + icon_state = "a762-[round(ammo_count(),10)]" + +/obj/item/ammo_box/magazine/mm556x45/buckshot //adminbus + name = "box magazine (buckshot)" + icon_state = "b762" + caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + max_ammo = 300 + +/obj/item/ammo_box/magazine/mm556x45/buckshot/update_icon() + ..() + icon_state = "b762-[round(ammo_count(),10)]" + +/obj/item/ammo_box/magazine/m556x45/he // also adminbus + name = "box magazine (40mm high explosive)" + icon_state = "g762" + caliber = "40mm" + ammo_type =/obj/item/ammo_casing/a40mm + max_ammo = 25 + +/obj/item/ammo_box/magazine/mm556x45/he/update_icon() + ..() + icon_state = "g762-[round(ammo_count(),5)]" + +//casings// + +/obj/item/ammo_casing/mm556x45 + desc = "A 556x45mm bullet casing." + icon_state = "762-casing" + caliber = "mm55645" + projectile_type = /obj/item/projectile/bullet/saw + +/obj/item/ammo_casing/mm556x45/bleeding + desc = "A 556x45mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding." + icon_state = "762-casing" + projectile_type = /obj/item/projectile/bullet/saw/bleeding + +/obj/item/ammo_casing/mm556x45/hollow + desc = "A 556x45mm bullet casing designed to cause more damage to unarmored targets." + projectile_type = /obj/item/projectile/bullet/saw/hollow + +/obj/item/ammo_casing/mm556x45/ap + desc = "A 556x45mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." + projectile_type = /obj/item/projectile/bullet/saw/ap + +/obj/item/ammo_casing/mm556x45/incen + desc = "A 556x45mm 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/saw/incen diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 7ae951ad908..1119a795505 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -8,26 +8,14 @@ flags = CONDUCT slot_flags = SLOT_BACK origin_tech = "combat=4;materials=2" + mag_type = /obj/item/ammo_box/magazine/internal/shot var/recentpump = 0 // to prevent spammage - mag_type = "/obj/item/ammo_box/magazine/internal/shot" -/obj/item/weapon/gun/projectile/shotgun/attackby(var/obj/item/A as obj, mob/user as mob, params) - var/num_loaded = 0 - 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/didload = magazine.give_round(AC) - if(didload) - AM.stored_ammo -= AC - num_loaded++ - if(!didload || !magazine.multiload) - break - if(istype(A, /obj/item/ammo_casing)) - var/obj/item/ammo_casing/AC = A - if(magazine && magazine.give_round(AC)) - user.drop_item() - AC.loc = src - num_loaded++ +/obj/item/weapon/gun/projectile/shotgun/attackby(obj/item/A, mob/user, params) + . = ..() + if(.) + return + var/num_loaded = magazine.attackby(A, user, params, 1) if(num_loaded) to_chat(user, "You load [num_loaded] shell\s into \the [src]!") A.update_icon() @@ -40,8 +28,14 @@ /obj/item/weapon/gun/projectile/shotgun/chamber_round() return -/obj/item/weapon/gun/projectile/shotgun/attack_self(mob/living/user as mob) - if(recentpump) return +/obj/item/weapon/gun/projectile/shotgun/can_shoot() + if(!chambered) + return 0 + return (chambered.BB ? 1 : 0) + +/obj/item/weapon/gun/projectile/shotgun/attack_self(mob/living/user) + if(recentpump) + return pump(user) recentpump = 1 spawn(10) @@ -49,7 +43,7 @@ return -/obj/item/weapon/gun/projectile/shotgun/proc/pump(mob/M as mob) +/obj/item/weapon/gun/projectile/shotgun/proc/pump(mob/M) playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) pump_unload(M) pump_reload(M) @@ -61,36 +55,41 @@ chambered.loc = get_turf(src)//Eject casing chambered.SpinAnimation(5, 1) chambered = null - if(in_chamber) - in_chamber = null /obj/item/weapon/gun/projectile/shotgun/proc/pump_reload(mob/M) - if(!magazine.ammo_count()) return 0 + if(!magazine.ammo_count()) + return 0 var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing. chambered = AC /obj/item/weapon/gun/projectile/shotgun/examine(mob/user) - ..(user) + ..() if (chambered) to_chat(user, "A [chambered.BB ? "live" : "spent"] one is in the chamber.") /obj/item/weapon/gun/projectile/shotgun/isHandgun() //You cannot, in fact, holster a shotgun. return 0 +/obj/item/weapon/gun/projectile/shotgun/lethal + mag_type = /obj/item/ammo_box/magazine/internal/shot/lethal + // RIOT SHOTGUN // /obj/item/weapon/gun/projectile/shotgun/riot //for spawn in the armory name = "riot shotgun" desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control." icon_state = "riotshotgun" - mag_type = "/obj/item/ammo_box/magazine/internal/shotriot" + mag_type = /obj/item/ammo_box/magazine/internal/shotriot sawn_desc = "Come with me if you want to live." -/obj/item/weapon/gun/projectile/shotgun/riot/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/weapon/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params) ..() - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) sawoff(user) - + if(istype(A, /obj/item/weapon/melee/energy)) + var/obj/item/weapon/melee/energy/W = A + if(W.active) + sawoff(user) /////////////////////// // BOLT ACTION RIFLE // @@ -102,7 +101,7 @@ icon_state = "moistnugget" item_state = "moistnugget" slot_flags = 0 //no SLOT_BACK sprite, alas - mag_type = "/obj/item/ammo_box/magazine/internal/boltaction" + mag_type = /obj/item/ammo_box/magazine/internal/boltaction var/bolt_open = 0 /obj/item/weapon/gun/projectile/shotgun/boltaction/pump(mob/M) @@ -115,21 +114,21 @@ update_icon() //I.E. fix the desc return 1 -/obj/item/weapon/gun/projectile/shotgun/boltaction/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/shotgun/boltaction/attackby(obj/item/A, mob/user, params) if(!bolt_open) to_chat(user, "The bolt is closed!") return . = ..() /obj/item/weapon/gun/projectile/shotgun/boltaction/examine(mob/user) - ..(user) + ..() to_chat(user, "The bolt is [bolt_open ? "open" : "closed"].") /obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted name = "enchanted bolt action rifle" desc = "Careful not to lose your head." var/guns_left = 30 - mag_type = "/obj/item/ammo_box/magazine/internal/boltaction/enchanted" + mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted /obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/New() ..() @@ -137,9 +136,10 @@ pump() /obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/dropped() + ..() guns_left = 0 -/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/Fire(atom/target as mob|obj|turf|area, mob/living/carbon/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) ..() if(guns_left) var/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/GUN = new @@ -156,6 +156,7 @@ /obj/item/ammo_box/magazine/internal/boltaction/enchanted max_ammo =1 + ammo_type = /obj/item/ammo_casing/a762/enchanted ///////////////////////////// // DOUBLE BARRELED SHOTGUN // @@ -166,22 +167,38 @@ desc = "A true classic." icon_state = "dshotgun" item_state = "shotgun" - w_class = 4.0 + w_class = 4 force = 10 flags = CONDUCT slot_flags = SLOT_BACK origin_tech = "combat=3;materials=1" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/dualshot" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/dual sawn_desc = "Omar's coming!" + unique_rename = 1 + unique_reskin = 1 -/obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/weapon/gun/projectile/revolver/doublebarrel/New() + ..() + options["Default"] = "dshotgun" + options["Dark Red Finish"] = "dshotgun-d" + options["Ash"] = "dshotgun-f" + options["Faded Grey"] = "dshotgun-g" + options["Maple"] = "dshotgun-l" + options["Rosewood"] = "dshotgun-p" + options["Cancel"] = null + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) ..() if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) chamber_round() - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) + if(istype(A, /obj/item/weapon/melee/energy)) + var/obj/item/weapon/melee/energy/W = A + if(W.active) + sawoff(user) + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) sawoff(user) -/obj/item/weapon/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user as mob) +/obj/item/weapon/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user) var/num_unloaded = 0 while (get_ammo() > 0) var/obj/item/ammo_casing/CB @@ -205,14 +222,17 @@ desc = "Essentially a tube that aims shotgun shells." icon_state = "ishotgun" item_state = "shotgun" - w_class = 4.0 + w_class = 4 force = 10 slot_flags = null origin_tech = "combat=2;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/improvised" + mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised sawn_desc = "I'm just here for the gasoline." + unique_rename = 0 + unique_reskin = 0 + var/slung = 0 -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) ..() if(istype(A, /obj/item/stack/cable_coil) && !sawn_state) var/obj/item/stack/cable_coil/C = A @@ -220,21 +240,34 @@ slot_flags = SLOT_BACK icon_state = "ishotgunsling" to_chat(user, "You tie the lengths of cable to the shotgun, making a sling.") + slung = 1 update_icon() else to_chat(user, "You need at least ten lengths of cable if you want to make a sling.") return +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/update_icon() + ..() + if (slung && (slot_flags & SLOT_BELT) ) + slung = 0 + icon_state = "ishotgun-sawn" + // Sawing guns related procs // -/obj/item/weapon/gun/projectile/proc/blow_up(mob/user as mob) - if(get_ammo()) - afterattack(user, user) - playsound(user, fire_sound, 50, 1) - user.visible_message("The [src] goes off!", "The [src] goes off in your face!") - return +/obj/item/weapon/gun/projectile/proc/blow_up(mob/user) + . = 0 + for(var/obj/item/ammo_casing/AC in magazine.stored_ammo) + if(AC.BB) + process_fire(user, user,0) + . = 1 -/obj/item/weapon/gun/projectile/proc/sawoff(mob/user as mob) +/obj/item/weapon/gun/projectile/shotgun/blow_up(mob/user) + . = 0 + if(chambered && chambered.BB) + process_fire(user, user,0) + . = 1 + +/obj/item/weapon/gun/projectile/proc/sawoff(mob/user) if(sawn_state == SAWN_OFF) to_chat(user, "\The [src] is already shortened.") return @@ -256,7 +289,7 @@ name = "sawn-off [src.name]" desc = sawn_desc icon_state = "[icon_state]-sawn" - w_class = 3.0 + w_class = 3 item_state = "gun" slot_flags &= ~SLOT_BACK //you can't sling it on your back slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) @@ -266,56 +299,64 @@ else sawn_state = SAWN_INTACT -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog - name = "\improper 'Bulldog' Shotgun" - desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." - icon_state = "bulldog" - item_state = "bulldog" - w_class = 3.0 - origin_tech = "combat=5;materials=4;syndicate=6" - mag_type = "/obj/item/ammo_box/magazine/m12g" - fire_sound = 'sound/weapons/Gunshot4.ogg' - can_suppress = 0 - burst_size = 1 - fire_delay = 0 - action_button_name = null +// Automatic Shotguns// -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/New() +/obj/item/weapon/gun/projectile/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj) ..() - update_icon() - return - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine() - if(magazine) - overlays.Cut() - overlays += "[magazine.icon_state]" - return - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/update_icon() - overlays.Cut() - update_magazine() - icon_state = "bulldog[chambered ? "" : "-e"]" - return - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - empty_alarm() - return - -/obj/item/weapon/gun/projectile/shotgun/automatic/Fire(mob/living/user as mob|obj) - ..() - pump(user) - -// COMBAT SHOTGUN // + src.pump(user) /obj/item/weapon/gun/projectile/shotgun/automatic/combat name = "combat shotgun" desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath." icon_state = "cshotgun" origin_tech = "combat=5;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/shotcom" + mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = 5 +//Dual Feed Shotgun + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube + name = "cycler shotgun" + desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types." + icon_state = "cycler" + origin_tech = "combat=4;materials=2" + mag_type = /obj/item/ammo_box/magazine/internal/shot/tube + w_class = 5 + var/toggled = 0 + var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/New() + ..() + if (!alternate_magazine) + alternate_magazine = new mag_type(src) + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/attack_self(mob/living/user) + if(!chambered && magazine.contents.len) + pump() + else + toggle_tube(user) + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/proc/toggle_tube(mob/living/user) + var/current_mag = magazine + var/alt_mag = alternate_magazine + magazine = alt_mag + alternate_magazine = current_mag + toggled = !toggled + if(toggled) + to_chat(user, "You switch to tube B.") + else + to_chat(user, "You switch to tube A.") + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/AltClick(mob/living/user) + if(user.incapacitated() || !Adjacent(user) || !istype(user)) + return + pump() + +/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 + //caneshotgun /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane @@ -330,7 +371,7 @@ can_unsuppress = 0 slot_flags = null origin_tech = "" // NO GIVAWAYS - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/improvised" + mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised sawn_desc = "I'm sorry, but why did you saw your cane in the first place?" attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") fire_sound = 'sound/weapons/Gunshot_silenced.ogg' @@ -354,4 +395,4 @@ to_chat(user, "\icon[src] That's [f_name]") if(desc) - to_chat(user, desc) \ No newline at end of file + to_chat(user, desc) diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index ee70bb3f80b..5033d0f8a0e 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -5,7 +5,7 @@ item_state = "sniper" recoil = 2 heavy_weapon = 1 - mag_type = "/obj/item/ammo_box/magazine/sniper_rounds" + mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 40 origin_tech = "combat=8" can_unsuppress = 1 @@ -35,18 +35,18 @@ max_ammo = 6 caliber = ".50" -/obj/item/ammo_casing/point50 - desc = "A .50 bullet casing." - caliber = ".50" - projectile_type = /obj/item/projectile/bullet/sniper - icon_state = ".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_casing/point50 + desc = "A .50 bullet casing." + caliber = ".50" + projectile_type = /obj/item/projectile/bullet/sniper + icon_state = ".50" + /obj/item/projectile/bullet/sniper damage = 70 stun = 5 @@ -69,8 +69,6 @@ origin_tech = "combat=6;syndicate=3" ammo_type = /obj/item/ammo_casing/soporific max_ammo = 3 - caliber = ".50" - icon_state = ".50" /obj/item/ammo_casing/soporific desc = "A .50 bullet casing, specialised in sending the target to sleep, instead of hell." @@ -79,10 +77,10 @@ icon_state = ".50" /obj/item/projectile/bullet/sniper/soporific + armour_penetration = 0 nodamage = 1 stun = 0 weaken = 0 - armour_penetration = 0 breakthings = FALSE /obj/item/projectile/bullet/sniper/soporific/on_hit(atom/target, blocked = 0, hit_zone) @@ -102,8 +100,6 @@ origin_tech = "combat=7;syndicate=5" ammo_type = /obj/item/ammo_casing/haemorrhage max_ammo = 5 - caliber = ".50" - icon_state = ".50" /obj/item/ammo_casing/haemorrhage desc = "A .50 bullet casing, specialised in causing massive bloodloss" @@ -112,16 +108,16 @@ icon_state = ".50" /obj/item/projectile/bullet/sniper/haemorrhage + armour_penetration = 15 damage = 15 stun = 0 weaken = 0 breakthings = FALSE - armour_penetration = 15 /obj/item/projectile/bullet/sniper/haemorrhage/on_hit(atom/target, blocked = 0, hit_zone) if((blocked != 100) && istype(target, /mob/living/carbon/human)) var/mob/living/carbon/human/H = target - H.drip(1000) + H.drip(100) return ..() @@ -145,4 +141,4 @@ forcedodge = 1 stun = 0 weaken = 0 - breakthings = FALSE \ No newline at end of file + breakthings = FALSE diff --git a/code/modules/projectiles/guns/projectile/toy.dm b/code/modules/projectiles/guns/projectile/toy.dm index 7bb290f4f46..e533710b604 100644 --- a/code/modules/projectiles/guns/projectile/toy.dm +++ b/code/modules/projectiles/guns/projectile/toy.dm @@ -4,7 +4,8 @@ icon = 'icons/obj/toyguns.dmi' icon_state = "saber" item_state = "gun" - mag_type = "/obj/item/ammo_box/magazine/toy/smg" + mag_type = /obj/item/ammo_box/magazine/toy/smg + fire_sound = 'sound/weapons/Gunshot_smg.ogg' force = 0 throwforce = 0 burst_size = 3 @@ -12,15 +13,15 @@ clumsy_check = 0 needs_permit = 0 -/obj/item/weapon/gun/projectile/automatic/toy/process_chambered() - return ..(0, 1) +/obj/item/weapon/gun/projectile/automatic/toy/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() /obj/item/weapon/gun/projectile/automatic/toy/pistol name = "foam force pistol" desc = "A small, easily concealable toy handgun. Ages 8 and up." icon_state = "pistol" w_class = 2 - mag_type = "/obj/item/ammo_box/magazine/toy/pistol" + mag_type = /obj/item/ammo_box/magazine/toy/pistol fire_sound = 'sound/weapons/Gunshot.ogg' can_suppress = 0 burst_size = 1 @@ -34,35 +35,12 @@ /obj/item/weapon/gun/projectile/automatic/toy/pistol/riot name = "foam force riot pistol" desc = "RIOT! Ages 8 and up." + mag_type = /obj/item/ammo_box/magazine/toy/pistol/riot /obj/item/weapon/gun/projectile/automatic/toy/pistol/riot/New() magazine = new /obj/item/ammo_box/magazine/toy/pistol/riot(src) ..() -/obj/item/weapon/gun/projectile/automatic/c20r/toy - name = "donksoft SMG" - desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up." - icon = 'icons/obj/toyguns.dmi' - can_suppress = 0 - needs_permit = 0 - mag_type = "/obj/item/ammo_box/magazine/toy/smgm45" - -/obj/item/weapon/gun/projectile/automatic/c20r/toy/process_chambered() - return ..(0, 1) - -/obj/item/weapon/gun/projectile/automatic/l6_saw/toy - name = "donksoft LMG" - desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up." - icon = 'icons/obj/toyguns.dmi' - can_suppress = 0 - needs_permit = 0 - mag_type = "/obj/item/ammo_box/magazine/toy/m762" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/toy/process_chambered() - return ..(0, 1) - - - /obj/item/weapon/gun/projectile/shotgun/toy name = "foam force shotgun" desc = "A toy shotgun with wood furniture and a four-shell capacity underneath. Ages 8 and up." @@ -70,31 +48,52 @@ force = 0 throwforce = 0 origin_tech = null - mag_type = "/obj/item/ammo_box/magazine/internal/shot/toy" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy clumsy_check = 0 needs_permit = 0 -/obj/item/weapon/gun/projectile/shotgun/toy/pump_unload() - if(chambered)//We have a shell in the chamber - chambered = null - if(in_chamber) - in_chamber = null +/obj/item/weapon/gun/projectile/shotgun/toy/process_chamber() + ..() + if(chambered && !chambered.BB) + qdel(chambered) /obj/item/weapon/gun/projectile/shotgun/toy/crossbow name = "foam force crossbow" desc = "A weapon favored by many overactive children. Ages 8 and up." icon_state = "crossbow" item_state = "crossbow" - mag_type = "/obj/item/ammo_box/magazine/internal/shot/toy/crossbow" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/crossbow fire_sound = 'sound/items/syringeproj.ogg' slot_flags = SLOT_BELT w_class = 2 +/obj/item/weapon/gun/projectile/automatic/c20r/toy + name = "donksoft SMG" + desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up." + icon = 'icons/obj/toyguns.dmi' + can_suppress = 0 + needs_permit = 0 + mag_type = /obj/item/ammo_box/magazine/toy/smgm45 + +/obj/item/weapon/gun/projectile/automatic/c20r/toy/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/toy + name = "donksoft LMG" + desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up." + icon = 'icons/obj/toyguns.dmi' + can_suppress = 0 + needs_permit = 0 + mag_type = /obj/item/ammo_box/magazine/toy/m762 + +/obj/item/weapon/gun/projectile/automatic/l6_saw/toy/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + /obj/item/weapon/gun/projectile/shotgun/toy/tommygun name = "tommy gun" desc = "Looks almost like the real thing! Great for practicing Drive-bys. Ages 8 and up." icon = 'icons/obj/gun.dmi' icon_state = "tommy" item_state = "shotgun" - mag_type = "/obj/item/ammo_box/magazine/internal/shot/toy/tommygun" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/tommygun w_class = 2 diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 0e43d550c85..45a590bd420 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -13,25 +13,41 @@ var/list/syringes = list() var/max_syringes = 1 -/obj/item/weapon/gun/syringe/process_chambered() - if(!syringes.len) return 0 +/obj/item/weapon/gun/syringe/New() + ..() + chambered = new /obj/item/ammo_casing/syringegun(src) + +/obj/item/weapon/gun/syringe/newshot() + if(!syringes.len) + return var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] - if(!S) return 0 + if(!S) + return + + chambered.BB = new S.projectile_type (src) - in_chamber = new /obj/item/projectile/bullet/dart/syringe(src) S.reagents.trans_to(in_chamber, S.reagents.total_volume) - in_chamber.name = S.name + chambered.BB.name = S.name syringes.Remove(S) qdel(S) - return 1 + return + +/obj/item/weapon/gun/syringe/process_chamber() + return + +/obj/item/weapon/gun/syringe/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) + if(target == loc) + return + newshot() + ..() /obj/item/weapon/gun/syringe/examine(mob/user) - ..(user) + ..() to_chat(user, "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining.") - + /obj/item/weapon/gun/syringe/attack_self(mob/living/user as mob) if(!syringes.len) to_chat(user, "[src] is empty.") @@ -47,16 +63,17 @@ return 1 -/obj/item/weapon/gun/syringe/attackby(var/obj/item/A as obj, mob/user as mob, var/show_msg = 1, params) +/obj/item/weapon/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = 1) if(istype(A, /obj/item/weapon/reagent_containers/syringe)) if(syringes.len < max_syringes) - user.drop_item() + if(!user.unEquip(A)) + return to_chat(user, "You load [A] into \the [src]!") syringes.Add(A) A.forceMove(src) return 1 else - to_chat(usr, "[src] cannot hold more syringes.") + to_chat(user, "[src] cannot hold more syringes.") return 0 /obj/item/weapon/gun/syringe/rapidsyringe @@ -64,7 +81,7 @@ 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/weapon/gun/syringe/syndicate name = "dart pistol" desc = "A small spring-loaded sidearm that functions identically to a syringe gun." diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 5a028a1084a..0cba3aa5fbf 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1,353 +1,224 @@ -/* -#define BRUTE "brute" -#define BURN "burn" -#define TOX "tox" -#define OXY "oxy" -#define CLONE "clone" - -#define ADD "add" -#define SET "set" -*/ - /obj/item/projectile name = "projectile" icon = 'icons/obj/projectiles.dmi' icon_state = "bullet" - density = 1 + density = 0 unacidable = 1 anchored = 1 //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots. + flags = ABSTRACT pass_flags = PASSTABLE mouse_opacity = 0 hitsound = 'sound/weapons/pierce.ogg' - animate_movement = 0 - var/bumped = 0 //Prevents it from hitting more than one guy at once + var/hitsound_wall = "" + pressure_resistance = INFINITY var/def_zone = "" //Aiming at var/mob/firer = null//Who shot it - var/silenced = 0 //Attack message + var/obj/item/ammo_casing/ammo_casing = null + var/suppressed = 0 //Attack message var/yo = null var/xo = null var/current = null - var/obj/shot_from = null // the object which shot us var/atom/original = null // the original target clicked var/turf/starting = null // the projectile's starting turf var/list/permutated = list() // we've passed through these atoms, don't try to hit them again var/paused = FALSE //for suspending the projectile midair - var/p_x = 16 var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center + var/speed = 1 //Amount of deciseconds it takes for projectile to travel + var/Angle = 0 + var/spread = 0 //amount (in degrees) of projectile spread + var/legacy = 0 //legacy projectile system + animate_movement = 0 var/damage = 10 var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = 0 //Determines if the projectile will skip any damage inflictions var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid var/projectile_type = "/obj/item/projectile" - var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile. - //Effects + var/range = 50 //This will de-increment every step. When 0, it will delete the projectile. + //Effects var/stun = 0 var/weaken = 0 var/paralyze = 0 var/irradiate = 0 - var/slur = 0 var/stutter = 0 + var/slur = 0 var/eyeblur = 0 var/drowsy = 0 var/stamina = 0 var/jitter = 0 var/embed = 0 // whether or not the projectile can embed itself in the mob - var/forcedodge = 0 + var/forcedodge = 0 //to pass through everything - var/range = 0 - var/proj_hit = 0 +/obj/item/projectile/New() + permutated = list() + return ..() - var/chatlog_attacks = 1 +/obj/item/projectile/proc/Range() + range-- + if(range <= 0 && loc) + on_range() - var/speed = 1 //Amount of deciseconds it takes for projectile to travel. Animation is adjusted accordingly. - var/Angle = 0 //For new projectiles - var/spread = 0 //Amount of degrees by which the projectiles will be spread DURING MOVEMENT. It exists for chaotic types of projectiles, like bees or something. - var/legacy = 0 //Use the legacy projectile system or new pixel movement? +/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range + qdel(src) - proc/delete() - // Garbage collect the projectiles - loc = null - - proc/Range() - if(range) - range-- - if(range <= 0) - on_range() - else - return - - proc/on_range() //if we want there to be effects when they reach the end of their range - proj_hit = 1 - del(src) - - proc/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) - if(!isliving(target)) return 0 - if(isanimal(target)) return 0 - var/mob/living/L = target - return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) - - proc/OnFired() //if assigned, allows for code when the projectile gets fired - return 1 - - proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. - if(!istype(target) || !istype(user)) - return 0 - var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test.... - in_chamber.target = target - in_chamber.flags = flags //Set the flags... - in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile... - in_chamber.firer = user - var/output = in_chamber.process() //Test it! - del(in_chamber) //No need for it anymore - return output //Send it back to the gun! - - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return 0 //cannot shoot yourself - - if(bumped) - return 1 - bumped = 1 - if(firer && istype(A, /mob)) - var/mob/M = A - if(!istype(A, /mob/living)) - loc = A.loc - return 0// nope.avi - - var/reagent_note - if(reagents && reagents.reagent_list) - reagent_note = " REAGENTS:" - for(var/datum/reagent/R in reagents.reagent_list) - reagent_note += R.id + " (" - reagent_note += num2text(R.volume) + ") " - //Lower accurancy/longer range tradeoff. Distance matters a lot here, so at - // close distance, actually RAISE the chance to hit. - var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. - def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. - /* - if(!def_zone) - visible_message("\blue \The [src] misses [M] narrowly!") - forcedodge = -1 - else - */ - if(ishuman(A)) - var/mob/living/carbon/human/H = A - var/obj/item/organ/external/organ = H.get_organ(check_zone(def_zone)) - if(isnull(organ)) - return - if(silenced) - playsound(loc, hitsound, 5, 1, -1) - to_chat(M, "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!") - else - playsound(loc, hitsound, 20, 1, -1) - visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter - if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [key_name(firer)] shot [M]/[M.ckey] with a [src.type][reagent_note]" - firer.attack_log += "\[[time_stamp()]\] [key_name(firer)] shot [M]/[M.ckey] with a [src.type][reagent_note]" - if(M.ckey && chatlog_attacks) - msg_admin_attack("[key_name_admin(firer)] shot [key_name_admin(M)] with a [src][reagent_note]") //BS12 EDIT ALG - if(!iscarbon(firer)) - M.LAssailant = null - else - M.LAssailant = firer - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [key_name(M)] with a [src][reagent_note]" - if(M.ckey && chatlog_attacks) - msg_admin_attack("UNKNOWN shot [key_name_admin(M)] with a [src][reagent_note] (JMP)") //BS12 EDIT ALG - - spawn(0) - if(A) - var/turf/new_loc = get_turf(A) - var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null - if(permutation == -1 || forcedodge)// the bullet passes through a dense object! - spawn(1) - bumped = 0 // reset bumped variable... after a delay. We don't want the projectile to hit AGAIN. Fixes deflecting projectiles. - loc = new_loc - permutated.Add(A) - return 0 - if(istype(A,/turf)) - for(var/obj/O in A) - O.bullet_act(src) - for(var/mob/M in A) - M.bullet_act(src, def_zone) - if(!istype(src, /obj/item/projectile/beam/lightning)) - density = 0 - invisibility = 101 - del(src) - return 1 - - - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if(istype(mover, /obj/item/projectile)) - return prob(95) - else - return 1 - - - Process_Spacemove(var/movement_dir = 0) - return 1 //Bullets don't drift in space - - - - process(var/setAngle) - if(setAngle) Angle = setAngle - if(!legacy) - spawn() //New projectile system - while(loc) - if(kill_count < 1) - del(src) - return - if(!paused) - kill_count-- - if((!( current ) || loc == current)) - current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) - - if(!Angle) - Angle=round(Get_Angle(src,current)) -// to_chat(world, "[Angle] angle") - //overlays.Cut() - //var/icon/I=new(initial(icon),icon_state) //using initial(icon) makes sure that the angle for that is reset as well - //I.Turn(Angle) - //I.DrawBox(rgb(255,0,0,50),1,1,32,32) - //icon = I - if(spread) //Chaotic spread - Angle += (rand() - 0.5) * spread - var/matrix/M = new//matrix(transform) - M.Turn(Angle) - transform = M - - var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2) - var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2) - var/pixel_x_offset = pixel_x + Pixel_x - var/pixel_y_offset = pixel_y + Pixel_y - var/new_x = x - var/new_y = y - //Not sure if using whiles for this is good - while(pixel_x_offset > 16) -// to_chat(world, "Pre-adjust coords (x++): xy [pixel_x] xy offset [pixel_x_offset]") - pixel_x_offset -= 32 - pixel_x -= 32 - new_x++// x++ - while(pixel_x_offset < -16) -// to_chat(world, "Pre-adjust coords (x--): xy [pixel_x] xy offset [pixel_x_offset]") - pixel_x_offset += 32 - pixel_x += 32 - new_x-- - - while(pixel_y_offset > 16) -// to_chat(world, "Pre-adjust coords (y++): py [pixel_y] py offset [pixel_y_offset]") - pixel_y_offset -= 32 - pixel_y -= 32 - new_y++ - while(pixel_y_offset < -16) -// to_chat(world, "Pre-adjust coords (y--): py [pixel_y] py offset [pixel_y_offset]") - pixel_y_offset += 32 - pixel_y += 32 - new_y-- - - speed = round(speed) //Just in case. - step_towards(src, locate(new_x, new_y, z)) //Original projectiles stepped towards 'current' - if(speed <= 1) //We should really only animate at speed 2 - pixel_x = pixel_x_offset - pixel_y = pixel_y_offset - else - animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed))) - - /* - var/turf/T = get_turf(src) - if(T) - T.color = "#6666FF" - spawn(10) - T.color = initial(T.color) - */ - - if(!bumped && ((original && original.layer>=2.75) || ismob(original))) - if(loc == get_turf(original)) - if(!(original in permutated)) - Bump(original) - Range() - sleep(max(1, speed)) - else - spawn() //Old projectile system - while(loc) - if(kill_count < 1) - del(src) - return - if(!paused) - kill_count-- - if((!( current ) || loc == current)) - current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) - if(!Angle) - Angle=round(Get_Angle(src,current)) - var/matrix/M = new//matrix(transform) - M.Turn(Angle) - transform = M //So there's no need to give icons directions again - step_towards(src, current) - if(!bumped && ((original && original.layer>=2.75) || ismob(original))) - if(loc == get_turf(original)) - if(!(original in permutated)) - Bump(original) - Range() - sleep(1) - - proc/dumbfire(var/dir) - current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. - process() - -/obj/item/projectile/test //Used to see if you can hit them. - invisibility = 101 //Nope! Can't see me! - yo = null - xo = null - var/target = null - var/result = 0 //To pass the message back to the gun. - - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return //cannot shoot yourself - if(istype(A, /obj/item/projectile)) - return - if(istype(A, /mob/living) || istype(A, /obj/mecha) || istype(A, /obj/spacepod) || istype(A, /obj/vehicle)) - result = 2 //We hit someone, return 1! - return - result = 1 - return - - process() - var/turf/curloc = get_turf(src) - var/turf/targloc = get_turf(target) - if(!curloc || !targloc) - return 0 - yo = targloc.y - curloc.y - xo = targloc.x - curloc.x - target = targloc - while(src) //Loop on through! - if(result) - return (result - 1) - if((!( target ) || loc == target)) - target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge - step_towards(src, target) - var/mob/living/M = locate() in get_turf(src) - if(istype(M)) //If there is someting living... - return 1 //Return 1 - else - M = locate() in get_step(src,target) - if(istype(M)) - return 1 - -/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null) //Checks if you can hit them or not. - if(!istype(target) || !istype(firer)) +/obj/item/projectile/proc/on_hit(atom/target, blocked = 0, hit_zone) + if(!isliving(target)) return 0 - var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_turf(firer)) //Making the test.... - trace.target = target - if(!isnull(flags)) - trace.flags = flags //Set the flags... - trace.pass_flags = pass_flags //And the pass flags to that of the real projectile... - var/output = trace.process() //Test it! - qdel(trace) //No need for it anymore - return output //Send it back to the gun! + var/mob/living/L = target + if(blocked < 100) // not completely blocked + var/organ_hit_text = "" + if(L.has_limbs) + organ_hit_text = " in \the [parse_zone(def_zone)]" + if(suppressed) + playsound(loc, hitsound, 5, 1, -1) + to_chat(L, "You're shot by \a [src][organ_hit_text]!") + else + if(hitsound) + var/volume = vol_by_damage() + playsound(loc, hitsound, volume, 1, -1) + L.visible_message("[L] is hit by \a [src][organ_hit_text]!", \ + "[L] is hit by \a [src][organ_hit_text]!") //X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter + L.on_hit(type) + + var/reagent_note + if(reagents && reagents.reagent_list) + reagent_note = " REAGENTS:" + for(var/datum/reagent/R in reagents.reagent_list) + reagent_note += R.id + " (" + reagent_note += num2text(R.volume) + ") " + add_logs(L, firer, "shot", src, reagent_note) + return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) + +/obj/item/projectile/proc/vol_by_damage() + if(src.damage) + return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 + else + return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume + +/obj/item/projectile/Bump(atom/A, yes) + if(!yes) //prevents double bumps. + return + if(firer) + if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech + loc = A.loc + return 0 + + var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. + def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. + + if(ishuman(A)) + var/mob/living/carbon/human/H = A + var/obj/item/organ/external/organ = H.get_organ(check_zone(def_zone)) + if(isnull(organ)) + return + else if(isturf(A) && hitsound_wall) + var/volume = Clamp(vol_by_damage() + 20, 0, 100) + if(suppressed) + volume = 5 + playsound(loc, hitsound_wall, volume, 1, -1) + + var/turf/target_turf = get_turf(A) + + var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null + if(permutation == -1 || forcedodge)// the bullet passes through a dense object! + loc = target_turf + if(A) + permutated.Add(A) + return 0 + else + if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile. + var/list/mobs_list = list() + for(var/mob/living/L in target_turf) + mobs_list += L + if(mobs_list.len) + var/mob/living/picked_mob = pick(mobs_list) + picked_mob.bullet_act(src, def_zone) + qdel(src) + +/obj/item/projectile/Process_Spacemove(var/movement_dir = 0) + return 1 //Bullets don't drift in space + +/obj/item/projectile/proc/fire(var/setAngle) + if(setAngle) + Angle = setAngle + if(!legacy) //new projectiles + set waitfor = 0 + while(loc) + if(!paused) + if((!( current ) || loc == current)) + current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) + + if(!Angle) + Angle=round(Get_Angle(src,current)) + if(spread) + Angle += (rand() - 0.5) * spread + var/matrix/M = new + M.Turn(Angle) + transform = M + + var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2) + var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2) + var/pixel_x_offset = pixel_x + Pixel_x + var/pixel_y_offset = pixel_y + Pixel_y + var/new_x = x + var/new_y = y + + while(pixel_x_offset > 16) + pixel_x_offset -= 32 + pixel_x -= 32 + new_x++// x++ + while(pixel_x_offset < -16) + pixel_x_offset += 32 + pixel_x += 32 + new_x-- + + while(pixel_y_offset > 16) + pixel_y_offset -= 32 + pixel_y -= 32 + new_y++ + while(pixel_y_offset < -16) + pixel_y_offset += 32 + pixel_y += 32 + new_y-- + + speed = round(speed) + step_towards(src, locate(new_x, new_y, z)) + if(speed <= 1) + pixel_x = pixel_x_offset + pixel_y = pixel_y_offset + else + animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed))) + + if(original && (original.layer>=2.75) || ismob(original)) + if(loc == get_turf(original)) + if(!(original in permutated)) + Bump(original, 1) + Range() + sleep(max(1, speed)) + else //old projectile system + set waitfor = 0 + while(loc) + if(!paused) + if((!( current ) || loc == current)) + current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) + step_towards(src, current) + if(original && (original.layer>=2.75) || ismob(original)) + if(loc == get_turf(original)) + if(!(original in permutated)) + Bump(original, 1) + Range() + sleep(1) + +obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. + ..() + if(isliving(AM) && AM.density && !checkpass(PASSMOB)) + Bump(AM, 1) + +/obj/item/projectile/Destroy() + ammo_casing = null + return ..() + +/obj/item/projectile/proc/dumbfire(var/dir) + current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. + fire() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index e86d8e7a739..b11c4f66961 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -5,50 +5,27 @@ damage = 20 damage_type = BURN hitsound = 'sound/weapons/sear.ogg' + hitsound_wall = 'sound/weapons/effects/searwall.ogg' flag = "laser" eyeblur = 2 -/obj/item/projectile/practice - name = "laser" - icon_state = "laser" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE +/obj/item/projectile/beam/laser + +/obj/item/projectile/beam/laser/heavylaser + name = "heavy laser" + icon_state = "heavylaser" + damage = 40 + +/obj/item/projectile/beam/practice + name = "practice laser" damage = 0 - hitsound = null - damage_type = BURN - flag = "laser" - eyeblur = 2 - chatlog_attacks = 0 + nodamage = 1 /obj/item/projectile/beam/scatter name = "laser pellet" icon_state = "scatterlaser" damage = 5 - -/obj/item/projectile/beam/heavylaser - name = "heavy laser" - icon_state = "heavylaser" - damage = 40 - -/obj/item/projectile/beam/sniper - name = "sniper beam" - icon_state = "sniperlaser" - damage = 60 - stun = 5 - weaken = 5 - stutter = 5 - - -/obj/item/projectile/beam/immolator - name = "immolation beam" - -/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0) - . = ..() - if(istype(target, /mob/living/carbon)) - var/mob/living/carbon/M = target - M.adjust_fire_stacks(1) - M.IgniteMob() - /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" @@ -82,41 +59,80 @@ name = "emitter beam" icon_state = "emitter" damage = 30 + legacy = 1 + animate_movement = SLIDE_STEPS /obj/item/projectile/beam/emitter/singularity_pull() return //don't want the emitters to miss -/obj/item/projectile/lasertag +/obj/item/projectile/beam/lasertag name = "laser tag beam" icon_state = "omnilaser" hitsound = null damage = 0 damage_type = STAMINA flag = "laser" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) - chatlog_attacks = 0 -/obj/item/projectile/lasertag/on_hit(var/atom/target, var/blocked = 0) - if(istype(target, /mob/living/carbon/human)) +/obj/item/projectile/beam/lasertag/on_hit(atom/target, blocked = 0) + . = ..() + if(ishuman(target)) var/mob/living/carbon/human/M = target if(istype(M.wear_suit)) if(M.wear_suit.type in suit_types) M.adjustStaminaLoss(34) return 1 -/obj/item/projectile/lasertag/omni +/obj/item/projectile/beam/lasertag/omni name = "laser tag beam" icon_state = "omnilaser" -/obj/item/projectile/lasertag/red +/obj/item/projectile/beam/lasertag/red icon_state = "laser" suit_types = list(/obj/item/clothing/suit/bluetag) -/obj/item/projectile/lasertag/blue +/obj/item/projectile/beam/lasertag/blue icon_state = "bluelaser" suit_types = list(/obj/item/clothing/suit/redtag) +/obj/item/projectile/beam/sniper + name = "sniper beam" + icon_state = "sniperlaser" + damage = 60 + stun = 5 + weaken = 5 + stutter = 5 + +/obj/item/projectile/beam/immolator + name = "immolation beam" + +/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0) + . = ..() + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(1) + M.IgniteMob() + +/obj/item/projectile/beam/instakill + name = "instagib laser" + icon_state = "purple_laser" + damage = 200 + damage_type = BURN + +/obj/item/projectile/beam/instakill/blue + icon_state = "blue_laser" + +/obj/item/projectile/beam/instakill/red + icon_state = "red_laser" + +/obj/item/projectile/beam/instakill/on_hit(atom/target) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.visible_message("[M] explodes into a shower of gibs!") + M.gib() + +/* //THIS CODE MAKES ME WANT TO STAB MY EYES OUT /obj/item/projectile/beam/lightning invisibility = 101 name = "lightning" @@ -133,12 +149,12 @@ kill_count = 6 var/bullet_acted = 0 - Bump(var/atom/A) +/obj/item/projectile/beam/lightning/Bump(var/atom/A) if((A != firer) && !bullet_acted) A.bullet_act(src) bullet_acted = 1 - proc/adjustAngle(angle) +/obj/item/projectile/beam/lightning/proc/adjustAngle(angle) angle = round(angle) + 45 if(angle > 180) angle -= 180 @@ -146,14 +162,9 @@ angle += 180 if(!angle) angle = 1 - /*if(angle < 0) - //angle = (round(abs(get_angle(A, user))) + 45) - 90 - angle = round(angle) + 45 + 180 - else - angle = round(angle) + 45*/ return angle - process() +/obj/item/projectile/beam/lightning/process() var/first = 1 //So we don't make the overlay in the same tile as the firer var/broke = 0 var/broken @@ -239,16 +250,11 @@ f.break_tile() f.hotspot_expose(1000,CELL_VOLUME) if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) -// to_chat(world, "deleting") - //qdel(src) //Delete if it passes the world edge broken = 1 return if(kill_count < 1) -// to_chat(world, "deleting") - //qdel(src) broken = 1 kill_count-- -// to_chat(world, "[x] [y]") if(!bumped && !isturf(original)) if(loc == get_turf(original)) if(!(original in permutated)) @@ -263,7 +269,6 @@ Bump(original) first = 0 if(broken) -// to_chat(world, "breaking") break else last = get_turf(src.loc) @@ -273,13 +278,9 @@ icon_state = "[tang]" qdel(src) return - /*cleanup(reference) //Waits .3 seconds then removes the overlay. -// to_chat(world, "setting invisibility") - sleep(50) - src.invisibility = 101 - return*/ - on_hit(atom/target, blocked = 0) +/obj/item/projectile/beam/lightning/on_hit(atom/target, blocked = 0) if(istype(target, /mob/living)) var/mob/living/M = target M.playsound_local(src, "explosion", 50, 1) - ..() \ No newline at end of file + ..() +*/ diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 879bbf7fad0..f3a676d962f 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -3,21 +3,10 @@ icon_state = "bullet" damage = 60 damage_type = BRUTE - nodamage = 0 flag = "bullet" embed = 1 sharp = 1 - -/obj/item/projectile/bullet/cap - name = "cap" - damage = 0 - nodamage = 1 - embed = 0 - sharp = 0 - -/obj/item/projectile/bullet/cap/process() - loc = null - del(src) + hitsound_wall = "ricochet" /obj/item/projectile/bullet/weakbullet //beanbag, heavy stamina damage damage = 5 @@ -27,6 +16,26 @@ embed = 0 sharp = 0 +/obj/item/projectile/bullet/weakbullet/booze + embed = 0 + +/obj/item/projectile/bullet/weakbullet/booze/on_hit(atom/target, blocked = 0) + if(..(target, blocked)) + var/mob/living/M = target + M.dizziness += 20 + M.slurring += 20 + M.confused += 20 + M.eye_blurry += 20 + M.drowsyness += 20 + for(var/datum/reagent/ethanol/A in M.reagents.reagent_list) + M.AdjustParalysis(2) + M.dizziness += 10 + M.slurring += 10 + M.confused += 10 + M.eye_blurry += 10 + M.drowsyness += 10 + A.volume += 5 //Because we can + /obj/item/projectile/bullet/weakbullet2 //detective revolver instastuns, but multiple shots are better for keeping punks down damage = 5 weaken = 3 @@ -44,6 +53,15 @@ damage = 15 damage_type = TOX +/obj/item/projectile/bullet/incendiary + +/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0) + ..() + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(1) + M.IgniteMob() + /obj/item/projectile/bullet/incendiary/firebullet damage = 10 @@ -55,15 +73,34 @@ name = "pellet" damage = 15 -/obj/item/projectile/bullet/blank - name = "blankshot" - nodamage = 1 - /obj/item/projectile/bullet/pellet/weak + damage = 6 + +/obj/item/projectile/bullet/pellet/weak/New() + range = rand(8) + +/obj/item/projectile/bullet/pellet/weak/on_range() + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + sparks.set_up(1, 1, src) + sparks.start() + ..() + +/obj/item/projectile/bullet/pellet/overload damage = 3 -/obj/item/projectile/bullet/pellet/random/New() - damage = rand(10) +/obj/item/projectile/bullet/pellet/overload/New() + range = rand(10) + +/obj/item/projectile/bullet/pellet/overload/on_hit(atom/target, blocked = 0) + ..() + explosion(target, 0, 0, 2) + +/obj/item/projectile/bullet/pellet/overload/on_range() + explosion(src, 0, 0, 2) + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + sparks.set_up(3, 3, src) + sparks.start() + ..() /obj/item/projectile/bullet/midbullet damage = 20 @@ -89,39 +126,11 @@ weaken = 5 stutter = 5 jitter = 20 - icon_state = "spark" range = 7 embed = 0 sharp = 0 - - -/obj/item/projectile/bullet/weakbullet/booze - embed = 0 - on_hit(var/atom/target, var/blocked = 0) - if(..(target, blocked)) - var/mob/living/M = target - M.dizziness += 20 - M.slurring += 20 - M.confused += 20 - M.eye_blurry += 20 - M.drowsyness += 20 - for(var/datum/reagent/ethanol/A in M.reagents.reagent_list) - M.AdjustParalysis(2) - M.dizziness += 10 - M.slurring += 10 - M.confused += 10 - M.eye_blurry += 10 - M.drowsyness += 10 - A.volume += 5 //Because we can - -/obj/item/projectile/bullet/incendiary - -/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0) - ..() - if(istype(target, /mob/living/carbon)) - var/mob/living/carbon/M = target - M.adjust_fire_stacks(1) - M.IgniteMob() + icon_state = "spark" + color = "#FFFF00" /obj/item/projectile/bullet/incendiary/shell name = "incendiary slug" @@ -130,8 +139,9 @@ /obj/item/projectile/bullet/incendiary/shell/Move() ..() var/turf/location = get_turf(src) - new /obj/effect/hotspot(location) - location.hotspot_expose(700, 50, 1) + if(location) + new /obj/effect/hotspot(location) + location.hotspot_expose(700, 50, 1) /obj/item/projectile/bullet/incendiary/shell/dragonsbreath name = "dragonsbreath round" @@ -157,7 +167,25 @@ ..() SpinAnimation() +/obj/item/projectile/bullet/meteorshot/weak + damage = 10 + weaken = 4 + stun = 4 +/obj/item/projectile/bullet/honker + damage = 0 + weaken = 5 + stun = 5 + forcedodge = 1 + nodamage = 1 + hitsound = 'sound/items/bikehorn.ogg' + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "banana" + range = 200 + +/obj/item/projectile/bullet/honker/New() + ..() + SpinAnimation() /obj/item/projectile/bullet/mime damage = 0 @@ -168,7 +196,7 @@ /obj/item/projectile/bullet/mime/on_hit(var/atom/target, var/blocked = 0) ..(target, blocked) - if(istype(target, /mob/living/carbon)) + if(iscarbon(target)) var/mob/living/carbon/M = target M.silent = max(M.silent, 10) else if(istype(target, /obj/mecha/combat/honker)) @@ -184,32 +212,38 @@ damage = 6 embed = 0 sharp = 0 + var/piercing = 0 - New() - ..() - flags |= NOREACT - create_reagents(50) +/obj/item/projectile/bullet/dart/New() + ..() + flags |= NOREACT + create_reagents(50) - on_hit(var/atom/target, var/blocked = 0, var/hit_zone) - if(istype(target, /mob/living/carbon)) - var/mob/living/carbon/M = target +/obj/item/projectile/bullet/dart/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) if(M.can_inject(null,0,hit_zone)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..() reagents.reaction(M, INGEST) reagents.trans_to(M, reagents.total_volume) return 1 else + blocked = 100 target.visible_message("The [name] was deflected!", \ - "You were protected against the [name]!") - flags &= ~NOREACT - reagents.handle_reactions() - return 1 + "You were protected against the [name]!") + ..(target, blocked, hit_zone) + flags &= ~NOREACT + reagents.handle_reactions() + return 1 /obj/item/projectile/bullet/dart/metalfoam - New() - ..() - reagents.add_reagent("aluminum", 15) - reagents.add_reagent("fluorosurfactant", 5) - reagents.add_reagent("sacid", 5) + +/obj/item/projectile/bullet/dart/metalfoam/New() + ..() + reagents.add_reagent("aluminum", 15) + reagents.add_reagent("fluorosurfactant", 5) + reagents.add_reagent("sacid", 5) //This one is for future syringe guns update /obj/item/projectile/bullet/dart/syringe @@ -218,9 +252,9 @@ icon_state = "syringeproj" /obj/item/projectile/bullet/dart/syringe/tranquilizer - New() - ..() - reagents.add_reagent("haloperidol", 15) +/obj/item/projectile/bullet/dart/syringe/tranquilizer/New() + ..() + reagents.add_reagent("haloperidol", 15) /obj/item/projectile/bullet/neurotoxin name = "neurotoxin spit" @@ -231,5 +265,17 @@ /obj/item/projectile/bullet/neurotoxin/on_hit(var/atom/target, var/blocked = 0) if(isalien(target)) - return 0 - ..() // Execute the rest of the code. + weaken = 0 + nodamage = 1 + . = ..() // Execute the rest of the code. + +/obj/item/projectile/bullet/cap + name = "cap" + damage = 0 + nodamage = 1 + embed = 0 + sharp = 0 + +/obj/item/projectile/bullet/cap/fire() + loc = null + qdel(src) diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index b5665a6af1c..b023d77de52 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -5,7 +5,6 @@ damage_type = BURN flag = "energy" - /obj/item/projectile/energy/electrode name = "electrode" icon_state = "spark" @@ -20,26 +19,23 @@ //Damage will be handled on the MOB side, to prevent window shattering. /obj/item/projectile/energy/electrode/on_hit(var/atom/target, var/blocked = 0) - if(!proj_hit) - if(!ismob(target) || blocked >= 2) //Fully blocked by mob or collided with dense object - burst into sparks! - var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread - sparks.set_up(1, 1, src) - sparks.start() - proj_hit = 1 - else if(iscarbon(target)) - var/mob/living/carbon/C = target - if(HULK in C.mutations) - C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - else if(C.status_flags & CANWEAKEN) - C.do_jitter_animation(jitter) - ..() - -/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 - if(!proj_hit) - var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread + . = ..() + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks! + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread sparks.set_up(1, 1, src) sparks.start() - proj_hit = 1 + else if(iscarbon(target)) + var/mob/living/carbon/C = target + if(HULK in C.mutations) + C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else if(C.status_flags & CANWEAKEN) + spawn(5) + C.do_jitter_animation(jitter) + +/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 + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + sparks.set_up(1, 1, src) + sparks.start() ..() /obj/item/projectile/energy/declone @@ -49,7 +45,6 @@ damage_type = CLONE irradiate = 10 - /obj/item/projectile/energy/dart name = "dart" icon_state = "toxin" @@ -63,7 +58,6 @@ icon_state = "toxin" damage = 10 damage_type = TOX - nodamage = 0 weaken = 5 stutter = 5 @@ -77,12 +71,28 @@ stutter = 5 /obj/item/projectile/energy/bolt/large - name = "largebolt" damage = 20 -/obj/item/projectile/energy/plasma +/obj/item/projectile/energy/shock_revolver + name = "shock bolt" + icon_state = "purple_laser" + var/chain + +/obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/projectile/hook/P = BB + spawn(1) + P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30) + +/obj/item/projectile/energy/shock_revolver/on_hit(atom/target) + . = ..() + if(isliving(target)) + tesla_zap(src, 3, 10000) + qdel(chain) + +/obj/item/projectile/energy/toxplasma name = "plasma bolt" icon_state = "energy" damage = 20 damage_type = TOX - irradiate = 20 \ No newline at end of file + irradiate = 20 diff --git a/code/modules/projectiles/projectile/force.dm b/code/modules/projectiles/projectile/force.dm index 2fab1a4da18..4e5c6d27700 100644 --- a/code/modules/projectiles/projectile/force.dm +++ b/code/modules/projectiles/projectile/force.dm @@ -10,21 +10,8 @@ name = "force bolt" /obj/item/projectile/forcebolt/on_hit(var/atom/target, var/blocked = 0) - - var/obj/T = target - var/throwdir = get_dir(firer,target) - T.throw_at(get_edge_target_turf(target, throwdir),10,10) - return 1 - -/* -/obj/item/projectile/forcebolt/strong/on_hit(var/atom/target, var/blocked = 0) - - // NONE OF THIS WORKS. DO NOT USE. - var/throwdir = null - - for(var/mob/M in hearers(2, src)) - if(M.loc != src.loc) - throwdir = get_dir(src,target) - M.throw_at(get_edge_target_turf(M, throwdir),15,1) - return ..() -*/ \ No newline at end of file + . = ..() + if(blocked < 100) + var/obj/T = target + var/throwdir = get_dir(firer,target) + T.throw_at(get_edge_target_turf(target, throwdir),10,10) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index ecbbfb530f8..74eff57d98d 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -4,15 +4,14 @@ damage = 0 damage_type = OXY nodamage = 1 + armour_penetration = 100 flag = "magic" /obj/item/projectile/magic/death name = "bolt of death" icon_state = "pulse1_bl" - damage = 9001 - damage_type = OXY - nodamage = 0 - flag = "magic" + damage_type = BURN //OXY does not kill IPCs + damage = 50000 /obj/item/projectile/magic/fireball name = "bolt of fireball" @@ -20,9 +19,22 @@ damage = 10 damage_type = BRUTE nodamage = 0 - flag = "magic" + +/obj/item/projectile/magic/fireball/Range() + var/turf/T1 = get_step(src,turn(dir, -45)) + var/turf/T2 = get_step(src,turn(dir, 45)) + var/mob/living/L = locate(/mob/living) in T1 //if there's a mob alive in our front right diagonal, we hit it. + if(L && L.stat != DEAD) + Bump(L) //Magic Bullet #teachthecontroversy + return + L = locate(/mob/living) in T2 + if(L && L.stat != DEAD) + Bump(L) + return + ..() /obj/item/projectile/magic/fireball/on_hit(var/target) + . = ..() var/turf/T = get_turf(target) explosion(T, -1, 0, 2, 3, 0, flame_range = 2) if(ismob(target)) //multiple flavors of pain @@ -32,35 +44,13 @@ /obj/item/projectile/magic/resurrection name = "bolt of resurrection" icon_state = "ion" - damage = 0 - damage_type = OXY - nodamage = 1 - flag = "magic" /obj/item/projectile/magic/resurrection/on_hit(var/mob/living/carbon/target) - - if(istype(target,/mob)) - var/old_stat = target.stat - if(isanimal(target) && target.stat == DEAD) - var/mob/living/simple_animal/O = target - var/mob/living/simple_animal/A = new O.type(O.loc) - A.real_name = O.real_name - A.name = O.name - if(iscorgi(O)) - var/mob/living/simple_animal/pet/corgi/C = O - if(C.inventory_head) - C.inventory_head.loc = C.loc - if(C.inventory_back) - C.inventory_back.loc = C.loc - if(O.mind) - O.mind.transfer_to(A) - else - A.key = O.key - qdel(O) - target = A - else - target.revive() - target.suiciding = 0 + . = ..() + if(ismob(target)) + var/old_stat = stat + target.suiciding = 0 + target.revive() if(!target.ckey) for(var/mob/dead/observer/ghost in player_list) if(target.real_name == ghost.real_name) @@ -74,14 +64,11 @@ /obj/item/projectile/magic/teleport name = "bolt of teleportation" icon_state = "bluespace" - damage = 0 - damage_type = OXY - nodamage = 1 - flag = "magic" var/inner_tele_radius = 0 var/outer_tele_radius = 6 /obj/item/projectile/magic/teleport/on_hit(var/mob/target) + . = ..() var/teleammount = 0 var/teleloc = target if(!isturf(target)) @@ -97,37 +84,40 @@ /obj/item/projectile/magic/door name = "bolt of door creation" icon_state = "energy" - damage = 0 - damage_type = OXY - nodamage = 1 - flag = "magic" + var/list/door_types = list(/obj/structure/mineral_door/wood,/obj/structure/mineral_door/iron,/obj/structure/mineral_door/silver,\ + /obj/structure/mineral_door/gold,/obj/structure/mineral_door/uranium,/obj/structure/mineral_door/sandstone,/obj/structure/mineral_door/transparent/plasma,\ + /obj/structure/mineral_door/transparent/diamond) /obj/item/projectile/magic/door/on_hit(var/atom/target) + . = ..() var/atom/T = target.loc - if(isturf(target)) - if(target.density) - new /obj/structure/mineral_door/wood(target) - target:ChangeTurf(/turf/simulated/floor/plating) - else if (isturf(T)) - if(T.density) - new /obj/structure/mineral_door/wood(T) - T:ChangeTurf(/turf/simulated/floor/plating) + if(isturf(target) && target.density) + CreateDoor(target) + else if (isturf(T) && T.density) + CreateDoor(T + else if(istype(target, /obj/machinery/door)) + OpenDoor(target)) + +/obj/item/projectile/magic/door/proc/CreateDoor(turf/T) + var/door_type = pick(door_types) + var/obj/structure/mineral_door/D = new door_type(T) + T.ChangeTurf(/turf/open/floor/plating) + D.Open() /obj/item/projectile/magic/change name = "bolt of change" icon_state = "ice_1" - damage = 0 damage_type = BURN - nodamage = 1 - flag = "magic" /obj/item/projectile/magic/change/on_hit(var/atom/change) + . = ..() wabbajack(change) proc/wabbajack(mob/living/M) if(istype(M)) if(istype(M, /mob/living) && M.stat != DEAD) - if(M.notransform) return + if(M.notransform) + return M.notransform = 1 M.canmove = 0 M.icon = null @@ -136,7 +126,9 @@ proc/wabbajack(mob/living/M) if(istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) qdel(Robot.mmi) + if(Robot.mmi) + qdel(Robot.mmi) + Robot.notify_ai(1) else if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -146,7 +138,8 @@ proc/wabbajack(mob/living/M) for(var/i in H.internal_organs) qdel(i) for(var/obj/item/W in M) - M.unEquip(W) + M.unEquip(W, 1) + qdel(W) var/mob/living/new_mob @@ -166,8 +159,6 @@ proc/wabbajack(mob/living/M) Robot.mmi.transfer_identity(M) //Does not transfer key/client. if("slime") new_mob = new /mob/living/carbon/slime(M.loc) -/* if(prob(50)) - new_mob.is_adult = 1*/ new_mob.universal_speak = 1 if("xeno") if(prob(50)) @@ -175,14 +166,6 @@ proc/wabbajack(mob/living/M) else new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) new_mob.universal_speak = 1 - - /*var/alien_caste = pick("Hunter","Sentinel","Drone","Larva") - switch(alien_caste) - if("Hunter") new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc) - if("Sentinel") new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) - if("Drone") new_mob = new /mob/living/carbon/alien/humanoid/drone(M.loc) - else new_mob = new /mob/living/carbon/alien/larva(M.loc) - new_mob.universal_speak = 1*/ if("animal") if(prob(50)) var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato") @@ -225,7 +208,6 @@ proc/wabbajack(mob/living/M) randomize = picked_species var/datum/preferences/A = new() //Randomize appearance for the human A.copy_to(new_mob) - else return @@ -246,13 +228,10 @@ proc/wabbajack(mob/living/M) /obj/item/projectile/magic/animate name = "bolt of animation" icon_state = "red_1" - damage = 0 damage_type = BURN - nodamage = 1 - flag = "magic" /obj/item/projectile/magic/animate/Bump(var/atom/change) - . = ..() + ..() if(istype(change, /obj/item) || istype(change, /obj/structure) && !is_type_in_list(change, protected_objects)) if(istype(change, /obj/structure/closet/statue)) for(var/mob/living/carbon/human/H in change.contents) @@ -273,4 +252,4 @@ proc/wabbajack(mob/living/M) else if(istype(change, /mob/living/simple_animal/hostile/mimic/copy)) // Change our allegiance! var/mob/living/simple_animal/hostile/mimic/copy/C = change - C.ChangeOwner(firer) \ No newline at end of file + C.ChangeOwner(firer) diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 81defd55743..9f4e36bc1b4 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -1,42 +1,63 @@ /obj/item/projectile/bullet/reusable name = "reusable bullet" desc = "How do you even reuse a bullet?" - var/obj/item/ammo_casing/caseless/ammo_type = /obj/item/ammo_casing/caseless/ - var/hit = 0 + ammo_type = /obj/item/ammo_casing/caseless/ + var/dropped = 0 -/obj/item/projectile/bullet/reusable/on_hit(var/atom/target, var/blocked = 0) - if(!proj_hit) - proj_hit = 1 - if (src.contents.len) - var/obj/content - for(content in src.contents) - content.loc = src.loc - else - new ammo_type(src.loc) - ..() +/obj/item/projectile/bullet/reusable/on_hit(atom/target, blocked = 0) + . = ..() + handle_drop() /obj/item/projectile/bullet/reusable/on_range() - if(!proj_hit) - if (src.contents.len) - var/obj/content - for(content in src.contents) - content.loc = src.loc - else - new ammo_type(src.loc) + handle_drop() ..() +/obj/item/projectile/bullet/reusable/proc/handle_drop() + if(!dropped) + new ammo_type(src.loc) + 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 - edge = 0 - embed = 0 icon = 'icons/obj/toyguns.dmi' icon_state = "foamdart" ammo_type = /obj/item/ammo_casing/caseless/foam_dart - range = 10 + range = 10 + var/obj/item/weapon/pen/pen = null + edge = 0 + embed = 0 + +/obj/item/projectile/bullet/reusable/foam_dart/handle_drop() + if(dropped) + return + dropped = 1 + var/obj/item/ammo_casing/caseless/foam_dart/newdart = new ammo_type(src.loc) + var/obj/item/ammo_casing/caseless/foam_dart/old_dart = ammo_casing + newdart.modified = old_dart.modified + if(pen) + var/obj/item/projectile/bullet/reusable/foam_dart/newdart_FD = newdart.BB + newdart_FD.pen = pen + pen.loc = newdart_FD + pen = null + newdart.BB.damage = damage + newdart.BB.nodamage = nodamage + newdart.BB.damage_type = damage_type + 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" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index ed64d73df4e..851f23bcdd7 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -6,15 +6,15 @@ nodamage = 1 flag = "energy" - - on_hit(var/atom/target, var/blocked = 0) - empulse(target, 1, 1) - return 1 - +/obj/item/projectile/ion/on_hit(var/atom/target, var/blocked = 0) + ..() + empulse(target, 1, 1) + return 1 /obj/item/projectile/ion/weak /obj/item/projectile/ion/weak/on_hit(atom/target, blocked = 0) + ..() empulse(target, 0, 0) return 1 @@ -26,9 +26,10 @@ sharp = 1 edge = 1 - on_hit(var/atom/target, var/blocked = 0) - explosion(target, -1, 0, 2) - return 1 +/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0) + ..() + explosion(target, -1, 0, 2) + return 1 /obj/item/projectile/bullet/a40mm name ="40mm grenade" @@ -43,18 +44,17 @@ return 1 /obj/item/projectile/temp - name = "freeze beam" + name = "temperature beam" icon_state = "temp_4" damage = 0 damage_type = BURN nodamage = 1 flag = "energy" - var/temperature = 300 - var/obj/item/weapon/gun/energy/temperature/T = null + var/temperature = null + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - OnFired() - T = shot_from - temperature = T.temperature +/obj/item/projectile/temp/New() + spawn(1) switch(temperature) if(501 to INFINITY) name = "searing beam" //if emagged @@ -86,17 +86,19 @@ else name = "temperature beam"//failsafe icon_state = "temp_4" + ..() - on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob - if(istype(target, /mob/living)) - var/mob/living/M = target - M.bodytemperature = temperature - if(temperature > 500)//emagged - M.adjust_fire_stacks(0.5) - M.IgniteMob() - playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0) - return 1 +/obj/item/projectile/temp/on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob + ..() + if(isliving(target)) + var/mob/living/M = target + M.bodytemperature = temperature + if(temperature > 500)//emagged + M.adjust_fire_stacks(0.5) + M.IgniteMob() + playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0) + return 1 /obj/item/projectile/meteor name = "meteor" @@ -107,26 +109,17 @@ nodamage = 1 flag = "bullet" - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return - - sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits - - if(src)//Do not add to this if() statement, otherwise the meteor won't delete them - if(A) - - A.ex_act(2) - playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) - - for(var/mob/M in range(10, src)) - if(!M.stat && !istype(M, /mob/living/silicon/ai))\ - shake_camera(M, 3, 1) - qdel(src) - return 1 - else - return 0 +/obj/item/projectile/meteor/Bump(atom/A, yes) + if(yes) + return + if(A == firer) + loc = A.loc + return + 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" @@ -136,36 +129,31 @@ nodamage = 1 flag = "energy" - on_hit(var/atom/target, var/blocked = 0) - var/mob/living/M = target - if(ishuman(target)) - var/mob/living/carbon/human/H = M - if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) - if(prob(15)) - M.apply_effect((rand(30,80)),IRRADIATE) - M.Weaken(5) - for (var/mob/V in viewers(src)) - V.show_message("\red [M] writhes in pain as \his vacuoles boil.", 3, "\red You hear the crunching of leaves.", 2) - if(prob(35)) - // for (var/mob/V in viewers(src)) //Public messages commented out to prevent possible metaish genetics experimentation and stuff. - Cheridan - // V.show_message("\red [M] is mutated by the radiation beam.", 3, "\red You hear the snapping of twigs.", 2) - if(prob(80)) - randmutb(M) - domutcheck(M,null) - else - randmutg(M) - domutcheck(M,null) +/obj/item/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0) + ..() + var/mob/living/M = target + if(ishuman(target)) + var/mob/living/carbon/human/H = M + if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) + if(prob(15)) + M.apply_effect((rand(30,80)),IRRADIATE) + M.Weaken(5) + for (var/mob/V in viewers(src)) + V.show_message("[M] writhes in pain as \his vacuoles boil.", 3, "You hear the crunching of leaves.", 2) + if(prob(35)) + if(prob(80)) + randmutb(M) + domutcheck(M,null) else - M.adjustFireLoss(rand(5,15)) - M.show_message("\red The radiation beam singes you!") - // for (var/mob/V in viewers(src)) - // V.show_message("\red [M] is singed by the radiation beam.", 3, "\red You hear the crackle of burning leaves.", 2) - else if(istype(target, /mob/living/carbon/)) - // for (var/mob/V in viewers(src)) - // V.show_message("The radiation beam dissipates harmlessly through [M]", 3) - M.show_message("\blue The radiation beam dissipates harmlessly through your body.") - else - return 1 + randmutg(M) + domutcheck(M,null) + else + M.adjustFireLoss(rand(5,15)) + M.show_message("The radiation beam singes you!") + else if(istype(target, /mob/living/carbon/)) + M.show_message("The radiation beam dissipates harmlessly through your body.") + else + return 1 /obj/item/projectile/energy/florayield name = "beta somatoray" @@ -175,40 +163,42 @@ nodamage = 1 flag = "energy" - on_hit(var/atom/target, var/blocked = 0) - var/mob/M = target - if(ishuman(target)) //These rays make plantmen fat. - var/mob/living/carbon/human/H = M - if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) - M.nutrition += 30 - else if (istype(target, /mob/living/carbon/)) - M.show_message("\blue The radiation beam dissipates harmlessly through your body.") - else - return 1 +/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0) + ..() + var/mob/M = target + if(ishuman(target)) //These rays make plantmen fat. + var/mob/living/carbon/human/H = M + if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) + M.nutrition += 30 + else if (istype(target, /mob/living/carbon/)) + M.show_message("The radiation beam dissipates harmlessly through your body.") + else + return 1 /obj/item/projectile/beam/mindflayer name = "flayer ray" - on_hit(var/atom/target, var/blocked = 0) - if(ishuman(target)) - var/mob/living/carbon/human/M = target - M.adjustBrainLoss(20) - M.hallucination += 20 +/obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0) + . = ..() + if(ishuman(target)) + var/mob/living/carbon/human/M = target + M.adjustBrainLoss(20) + M.hallucination += 20 /obj/item/projectile/clown name = "snap-pop" icon = 'icons/obj/toy.dmi' icon_state = "snappop" - Bump(atom/A as mob|obj|turf|area) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("\red The [src.name] explodes!","\red You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) +/obj/item/projectile/clown/Bump(atom/A as mob|obj|turf|area) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + src.visible_message("The [src.name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) /obj/item/projectile/kinetic name = "kinetic force" @@ -239,11 +229,9 @@ obj/item/projectile/kinetic/New() damage *= 4 ..() -/obj/item/projectile/kinetic/Range() - range-- - if(range <= 0) - new /obj/item/effect/kinetic_blast(src.loc) - qdel(src) +/obj/item/projectile/kinetic/on_range() + new /obj/effect/kinetic_blast(src.loc) + ..() /obj/item/projectile/kinetic/on_hit(atom/target) . = ..() @@ -268,6 +256,40 @@ obj/item/projectile/kinetic/New() spawn(4) qdel(src) +/obj/item/projectile/beam/wormhole + name = "bluespace beam" + icon_state = "spark" + hitsound = "sparks" + damage = 3 + var/obj/item/weapon/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/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) + +/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) + /obj/item/projectile/bullet/frag12 name ="explosive slug" damage = 25 @@ -278,25 +300,6 @@ obj/item/projectile/kinetic/New() explosion(target, -1, 0, 1) return 1 -/obj/item/projectile/energy/teleport - name = "teleportation burst" - icon_state = "bluespace" - damage = 0 - nodamage = 1 - var/obj/item/weapon/gun/energy/telegun/T = null - var/teleport_target = null - - OnFired() - T = shot_from - teleport_target = T.teleport_target - -/obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0) - if(isliving(target)) - if(teleport_target) - do_teleport(target, teleport_target, 0)//teleport what's in the tile to the beacon - else - do_teleport(target, target, 15) //Otherwise it just warps you off somewhere. - /obj/item/projectile/plasma name = "plasma blast" icon_state = "plasmacutter" @@ -321,8 +324,9 @@ obj/item/projectile/kinetic/New() if(istype(target, /turf/simulated/mineral)) var/turf/simulated/mineral/M = target M.gets_drilled(firer) - range = max(range - 1, 1) - return -1 + Range() + if(range > 0) + return -1 /obj/item/projectile/plasma/adv range = 5 @@ -331,29 +335,24 @@ obj/item/projectile/kinetic/New() damage = 10 range = 6 -/obj/item/projectile/beam/wormhole - name = "bluespace beam" - icon_state = "spark" - hitsound = "sparks" - damage = 3 - var/obj/item/weapon/gun/energy/wormhole_projector/gun = null - color = "#33CCFF" +/obj/item/projectile/energy/teleport + name = "teleportation burst" + icon_state = "bluespace" + damage = 0 + nodamage = 1 + var/obj/item/weapon/gun/energy/telegun/T = null + var/teleport_target = null -/obj/item/projectile/beam/wormhole/orange - name = "orange bluespace beam" - color = "#FF6600" + OnFired() + T = shot_from + teleport_target = T.teleport_target -/obj/item/projectile/beam/wormhole/OnFired() - gun = shot_from - -/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) +/obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0) + if(isliving(target)) + if(teleport_target) + do_teleport(target, teleport_target, 0)//teleport what's in the tile to the beacon + else + do_teleport(target, target, 15) //Otherwise it just warps you off somewhere. /obj/item/projectile/snowball name = "snowball" @@ -363,6 +362,7 @@ obj/item/projectile/kinetic/New() damage_type = BURN /obj/item/projectile/snowball/on_hit(atom/target) //chilling + . = ..() if(istype(target, /mob/living)) var/mob/living/M = target M.bodytemperature = max(0, M.bodytemperature - 50) //each hit will drop your body temp, so don't get surrounded! @@ -380,9 +380,10 @@ obj/item/projectile/kinetic/New() ..() /obj/item/projectile/ornament/on_hit(atom/target) //knockback + ..() if(istype(target, /turf)) return 0 var/obj/T = target var/throwdir = get_dir(firer,target) T.throw_at(get_edge_target_turf(target, throwdir),10,10) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/reagents/grenade_launcher.dm b/code/modules/reagents/grenade_launcher.dm deleted file mode 100644 index 9b9484ba60e..00000000000 --- a/code/modules/reagents/grenade_launcher.dm +++ /dev/null @@ -1,111 +0,0 @@ - - -/obj/item/weapon/gun/grenadelauncher - name = "grenade launcher" - icon = 'icons/obj/gun.dmi' - icon_state = "riotgun" - item_state = "riotgun" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - var/list/grenades = new/list() - var/max_grenades = 3 - var/ammo_name = "grenade" - var/ammo_type = /obj/item/weapon/grenade - var/unloaded - - materials = list(MAT_METAL=2000) - -/obj/item/weapon/gun/grenadelauncher/examine(mob/user) - if(..(user, 2)) - to_chat(user, "\blue [grenades.len] / [max_grenades] [ammo_name]s.") - -/obj/item/weapon/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params) - - if((istype(I, ammo_type))) - if(grenades.len < max_grenades) - user.drop_item() - I.loc = src - grenades += I - to_chat(user, "\blue You put the [ammo_name] in the [name].") - to_chat(user, "\blue [grenades.len] / [max_grenades] [ammo_name]s.") - else - to_chat(usr, "\red The grenade launcher cannot hold more [ammo_name]s.") - -/obj/item/weapon/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) - - if (istype(target, /obj/item/weapon/storage/backpack )) - return - - else if (locate (/obj/structure/table, src.loc)) - return - - else if(target == user) - return - - if(grenades.len) - spawn(0) fire_grenade(target,user) - else - to_chat(usr, "\red The [name] is empty.") - -/obj/item/weapon/gun/grenadelauncher/proc/fire_grenade(atom/target, mob/user) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] fired a [ammo_name]!", user), 1) - to_chat(user, "\red You fire the [name]!") - var/obj/item/weapon/grenade/chem_grenade/F = grenades[1] //Now with less copypasta! - grenades -= F - F.loc = user.loc - F.throw_at(target, 30, 2, user) - message_admins("[key_name_admin(user)] fired a [ammo_name] ([F.name]) from a launcher ([name]).") - log_game("[key_name_admin(user)] used a [ammo_name] ([name]).") - F.active = 1 - F.icon_state = initial(icon_state) + "_active" - playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - spawn(15) - F.prime() - - -/obj/item/weapon/gun/grenadelauncher/piecannon - name = "pie cannon" - icon = 'icons/obj/gun.dmi' - icon_state = "piecannon1" - item_state = "piecannon1" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - clumsy_check = 0 - grenades = new/list() - max_grenades = 5 - ammo_name = "cream pie" - ammo_type = /obj/item/weapon/reagent_containers/food/snacks/pie - -/obj/item/weapon/gun/grenadelauncher/piecannon/New() - ..() - for(var/i=0, i < max_grenades, i++) - var/obj/item/weapon/reagent_containers/food/snacks/pie/P = new /obj/item/weapon/reagent_containers/food/snacks/pie(src) - grenades += P - -/obj/item/weapon/gun/grenadelauncher/piecannon/attackby(obj/item/I as obj, mob/user as mob, params) - if((istype(I, ammo_type))) - if(grenades.len < max_grenades) - user.drop_item() - I.loc = src - grenades += I - to_chat(user, "\blue You put the [ammo_name] in the [name].") - to_chat(user, "\blue [grenades.len] / [max_grenades] [ammo_name]s.") - icon_state = "piecannon1" - else - to_chat(usr, "\red The grenade launcher cannot hold more [ammo_name]s.") - -/obj/item/weapon/gun/grenadelauncher/piecannon/fire_grenade(atom/target, mob/user) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] fired a [ammo_name]!", user), 1) - to_chat(user, "\red You fire the [name]!") - var/obj/item/weapon/reagent_containers/food/snacks/pie/P = grenades[1] //Now with less copypasta! - grenades -= P - P.loc = user.loc - P.throw_at(target, 30, 2, user) - if(!grenades.len) - icon_state = "piecannon0" diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index bd8a22cd06f..332375dae8d 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -17,6 +17,7 @@ w_class = 1 sharp = 1 var/mode = SYRINGE_DRAW + var/projectile_type = /obj/item/projectile/bullet/dart/syringe /obj/item/weapon/reagent_containers/syringe/on_reagent_change() update_icon() @@ -533,4 +534,4 @@ reagents.add_reagent("capulettium_plus", 5) reagents.add_reagent("sodium_thiopental", 5) mode = SYRINGE_INJECT - update_icon() \ No newline at end of file + update_icon() diff --git a/paradise.dme b/paradise.dme index bf55518d633..97f182a3d3a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1748,37 +1748,36 @@ #include "code\modules\procedural_mapping\mapGenerators\nature.dm" #include "code\modules\procedural_mapping\mapGenerators\syndicate.dm" #include "code\modules\projectiles\ammunition.dm" +#include "code\modules\projectiles\firing.dm" #include "code\modules\projectiles\gun.dm" -#include "code\modules\projectiles\medbeam.dm" #include "code\modules\projectiles\projectile.dm" #include "code\modules\projectiles\ammunition\ammo_casings.dm" #include "code\modules\projectiles\ammunition\boxes.dm" +#include "code\modules\projectiles\ammunition\energy.dm" #include "code\modules\projectiles\ammunition\magazines.dm" +#include "code\modules\projectiles\ammunition\special.dm" #include "code\modules\projectiles\guns\alien.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\projectile.dm" #include "code\modules\projectiles\guns\syringe_gun.dm" -#include "code\modules\projectiles\guns\energy\advtaser.dm" -#include "code\modules\projectiles\guns\energy\blueshield.dm" -#include "code\modules\projectiles\guns\energy\hos.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\nuclear.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\energy\telegun.dm" -#include "code\modules\projectiles\guns\energy\temperature.dm" #include "code\modules\projectiles\guns\magic\staff.dm" #include "code\modules\projectiles\guns\magic\wand.dm" #include "code\modules\projectiles\guns\projectile\automatic.dm" -#include "code\modules\projectiles\guns\projectile\crossbow.dm" -#include "code\modules\projectiles\guns\projectile\grenade launcher.dm" #include "code\modules\projectiles\guns\projectile\launchers.dm" #include "code\modules\projectiles\guns\projectile\pistol.dm" #include "code\modules\projectiles\guns\projectile\revolver.dm" #include "code\modules\projectiles\guns\projectile\rocket.dm" +#include "code\modules\projectiles\guns\projectile\saw.dm" #include "code\modules\projectiles\guns\projectile\shotgun.dm" #include "code\modules\projectiles\guns\projectile\sniper.dm" #include "code\modules\projectiles\guns\projectile\toy.dm" @@ -1794,7 +1793,6 @@ #include "code\modules\reagents\Chemistry-Machinery.dm" #include "code\modules\reagents\Chemistry-Readme.dm" #include "code\modules\reagents\dartgun.dm" -#include "code\modules\reagents\grenade_launcher.dm" #include "code\modules\reagents\pandemic.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" From a4e950d21a9a366f7785261913c014f4ee75f4ea Mon Sep 17 00:00:00 2001 From: TheDZD Date: Sat, 28 May 2016 14:28:23 -0400 Subject: [PATCH 02/10] =?UTF-8?q?Compiles,=20and=20guns=20work=E2=84=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MetaStation/MetaStation.v41A.II.dmm | 2 +- _maps/map_files/RandomZLevels/beach.dmm | 2 +- _maps/map_files/cyberiad/cyberiad.dmm | 2 +- _maps/map_files/cyberiad/z2.dmm | 4 +- _maps/map_files/cyberiad/z6.dmm | 2 +- code/__DEFINES/misc.dm | 6 +- code/_onclick/click.dm | 56 +------ code/datums/uplink_item.dm | 6 +- .../gamemodes/malfunction/Malf_Modules.dm | 2 +- .../miniantags/abduction/abduction_gear.dm | 6 +- code/game/gamemodes/steal_items.dm | 4 +- code/game/machinery/portable_turret.dm | 8 +- code/game/machinery/rechargestation.dm | 3 +- code/game/machinery/turrets.dm | 6 +- code/game/mecha/equipment/weapons/weapons.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 6 +- code/game/objects/items/shooting_range.dm | 4 +- .../items/stacks/sheets/sheet_types.dm | 2 +- .../objects/items/weapons/chrono_eraser.dm | 23 ++- .../crates_lockers/closets/secure/security.dm | 2 +- code/modules/admin/verbs/honksquad.dm | 6 +- .../admin/verbs/striketeam_syndicate.dm | 4 +- code/modules/admin/verbs/vox_raiders.dm | 6 +- .../clothing/spacesuits/rig/modules/combat.dm | 4 +- code/modules/mob/living/carbon/human/human.dm | 19 ++- .../mob/living/carbon/human/human_defense.dm | 5 +- .../carbon/human/interactive/functions.dm | 17 +- code/modules/mob/living/living.dm | 6 + code/modules/mob/living/living_defense.dm | 4 - .../mob/living/simple_animal/bot/ed209bot.dm | 10 +- code/modules/mob/living/simple_animal/vox.dm | 8 +- code/modules/projectiles/ammunition.dm | 10 +- .../projectiles/ammunition/ammo_casings.dm | 12 +- code/modules/projectiles/ammunition/energy.dm | 12 +- .../projectiles/ammunition/magazines.dm | 2 +- code/modules/projectiles/firing.dm | 20 +-- code/modules/projectiles/gun.dm | 16 +- code/modules/projectiles/guns/alien.dm | 84 +--------- code/modules/projectiles/guns/energy.dm | 26 +-- code/modules/projectiles/guns/energy/laser.dm | 6 +- .../projectiles/guns/energy/nuclear.dm | 37 +---- code/modules/projectiles/guns/energy/pulse.dm | 2 +- .../projectiles/guns/energy/special.dm | 32 ++-- code/modules/projectiles/guns/energy/stun.dm | 2 +- .../projectiles/guns/energy/telegun.dm | 4 + .../projectiles/guns/grenade_launcher.dm | 12 +- code/modules/projectiles/guns/magic.dm | 3 +- code/modules/projectiles/guns/magic/wand.dm | 2 +- code/modules/projectiles/guns/medbeam.dm | 2 +- code/modules/projectiles/guns/mounted.dm | 4 +- code/modules/projectiles/guns/projectile.dm | 12 +- .../projectiles/guns/projectile/automatic.dm | 7 +- .../projectiles/guns/projectile/revolver.dm | 16 +- .../projectiles/guns/projectile/rocket.dm | 4 +- .../projectiles/guns/projectile/saw.dm | 4 +- .../projectiles/guns/projectile/shotgun.dm | 18 +- .../projectiles/guns/projectile/sniper.dm | 4 +- code/modules/projectiles/guns/syringe_gun.dm | 11 +- code/modules/projectiles/projectile.dm | 18 +- code/modules/projectiles/projectile/beams.dm | 157 +----------------- .../modules/projectiles/projectile/bullets.dm | 6 +- code/modules/projectiles/projectile/energy.dm | 6 +- code/modules/projectiles/projectile/magic.dm | 14 +- .../projectiles/projectile/reusable.dm | 6 +- .../modules/projectiles/projectile/special.dm | 17 +- code/modules/reagents/dartgun.dm | 9 +- .../xenoarchaeology/machinery/coolant.dm | 2 +- code/modules/spacepods/equipment.dm | 2 - sound/weapons/effects/ric1.ogg | Bin 0 -> 7937 bytes sound/weapons/effects/ric2.ogg | Bin 0 -> 6359 bytes sound/weapons/effects/ric3.ogg | Bin 0 -> 7430 bytes sound/weapons/effects/ric4.ogg | Bin 0 -> 7072 bytes sound/weapons/effects/ric5.ogg | Bin 0 -> 8545 bytes sound/weapons/effects/searwall.ogg | Bin 0 -> 7213 bytes 74 files changed, 288 insertions(+), 550 deletions(-) create mode 100644 sound/weapons/effects/ric1.ogg create mode 100644 sound/weapons/effects/ric2.ogg create mode 100644 sound/weapons/effects/ric3.ogg create mode 100644 sound/weapons/effects/ric4.ogg create mode 100644 sound/weapons/effects/ric5.ogg create mode 100644 sound/weapons/effects/searwall.ogg diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index b50efa38848..61c46bad876 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -583,7 +583,7 @@ "alk" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "all" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/turf/space,/area/shuttle/vox) "alm" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) -"aln" = (/obj/structure/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) +"aln" = (/obj/structure/rack,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "alo" = (/obj/machinery/door/poddoor{id_tag = "trash"; name = "disposal bay door"},/turf/simulated/floor/plating,/area/maintenance/disposal) "alp" = (/obj/machinery/mass_driver{dir = 8; id_tag = "trash"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/disposal) "alq" = (/obj/machinery/conveyor_switch/oneway{convdir = -1; id = "garbage"; name = "disposal coveyor"},/turf/simulated/floor/plating,/area/maintenance/disposal) diff --git a/_maps/map_files/RandomZLevels/beach.dmm b/_maps/map_files/RandomZLevels/beach.dmm index 0a5cd703fc0..04512b660bf 100644 --- a/_maps/map_files/RandomZLevels/beach.dmm +++ b/_maps/map_files/RandomZLevels/beach.dmm @@ -19,7 +19,7 @@ "as" = (/obj/structure/boulder,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) "at" = (/obj/item/flag/cult,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) "au" = (/obj/structure/mineral_door/sandstone,/obj/structure/barricade/wooden,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) -"av" = (/obj/item/weapon/crossbowframe,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"av" = (/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) "aw" = (/obj/item/toy/eight_ball/conch,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) "ax" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) "ay" = (/obj/structure/closet/cabinet,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 6eef766fd9b..a2f06af2b25 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -8497,7 +8497,7 @@ "dhv" = (/obj/structure/rack,/obj/item/weapon/pneumatic_cannon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhw" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/turf/space,/area/shuttle/vox) "dhx" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) -"dhy" = (/obj/structure/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) +"dhy" = (/obj/structure/rack,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhz" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhA" = (/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (NORTH)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 1},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "dhB" = (/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 2},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 46b1662d8d6..65b00ea2f84 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -1136,7 +1136,7 @@ "EY" = (/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/turf/unsimulated/wall{dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5"; name = "window"; opacity = 0; tag = "icon-window5 (EAST)"},/area/admin) "EZ" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/turf/unsimulated/wall{dir = 2; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5"; name = "window"; opacity = 0; tag = "icon-window5"},/area/admin) "Fa" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "ADMINCHEMLOCKDOWN"; name = "Security Doors"; opacity = 0},/obj/machinery/door/airlock/hatch{name = "Chem Lab"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) -"Fb" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/weapon/gun/projectile/automatic/l6_saw,/obj/item/weapon/gun/projectile/automatic/l6_saw{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"Fb" = (/obj/structure/rack,/obj/item/ammo_box/magazine/mm556x45,/obj/item/ammo_box/magazine/mm556x45,/obj/item/ammo_box/magazine/mm556x45,/obj/item/ammo_box/magazine/mm556x45,/obj/item/weapon/gun/projectile/automatic/l6_saw,/obj/item/weapon/gun/projectile/automatic/l6_saw{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Fc" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/automatic/proto,/obj/item/weapon/gun/projectile/automatic/proto{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Fd" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/a40mm,/obj/item/ammo_box/a40mm,/obj/item/ammo_box/a40mm,/obj/item/ammo_box/a40mm,/obj/item/weapon/gun/projectile/automatic/m90,/obj/item/weapon/gun/projectile/automatic/m90{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Fe" = (/obj/structure/mirror{dir = 4; pixel_x = 0; pixel_y = -32},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -1174,7 +1174,7 @@ "FL" = (/turf/simulated/wall/r_wall,/area/adminconstruction) "FM" = (/obj/structure/rack,/obj/item/weapon/gun/energy/meteorgun,/obj/item/weapon/gun/energy/meteorgun{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "FN" = (/obj/structure/rack,/obj/item/weapon/twohanded/knighthammer{pixel_x = -3; pixel_y = 3},/obj/item/weapon/twohanded/mjollnir,/obj/item/weapon/twohanded/singularityhammer{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"FO" = (/obj/structure/rack,/obj/item/weapon/gun/energy/crossbow,/obj/item/weapon/gun/energy/crossbow{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"FO" = (/obj/structure/rack,/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow,/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "FP" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse_rifle,/obj/item/weapon/gun/energy/pulse_rifle{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "FQ" = (/obj/structure/table,/obj/random/tool,/obj/item/clothing/gloves/color/yellow,/obj/item/weapon/pinpointer/advpinpointer,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "FR" = (/obj/structure/table,/obj/item/weapon/grenade/syndieminibomb{pixel_x = 4; pixel_y = 2; pixel_z = 0},/obj/item/weapon/grenade/syndieminibomb{pixel_x = -1},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index 104c590cccc..da5594a4405 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -648,7 +648,7 @@ "mx" = (/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "my" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/engine,/area/syndicate_depot) "mz" = (/turf/simulated/floor/engine,/area/syndicate_depot) -"mA" = (/obj/structure/closet/crate{name = "munitions crate"},/obj/item/weapon/storage/box/donkpockets,/obj/item/ammo_box/magazine/m762,/obj/item/weapon/gun/projectile/automatic/m90,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) +"mA" = (/obj/structure/closet/crate{name = "munitions crate"},/obj/item/weapon/storage/box/donkpockets,/obj/item/ammo_box/magazine/mm556x45,/obj/item/weapon/gun/projectile/automatic/m90,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mB" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Telepad"; req_access_txt = "0"},/turf/simulated/floor/engine,/area/syndicate_depot) "mC" = (/obj/machinery/telepad,/turf/simulated/floor/engine,/area/syndicate_depot) "mD" = (/obj/structure/closet/crate{name = "munitions crate"},/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate,/obj/item/weapon/storage/firstaid/tactical,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 99918eccbc8..d36405db5d1 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -250,4 +250,8 @@ #define MATRIX_GREYSCALE list(0.3, 0.3, 0.3, 0,\ 0.3, 0.3, 0.3, 0,\ 0.3, 0.3, 0.3, 0,\ - 0, 0, 0, 1)//Gun trigger guards #define TRIGGER_GUARD_ALLOW_ALL -1 #define TRIGGER_GUARD_NONE 0 #define TRIGGER_GUARD_NORMAL 1 \ No newline at end of file + 0, 0, 0, 1) +//Gun trigger guards +#define TRIGGER_GUARD_ALLOW_ALL -1 +#define TRIGGER_GUARD_NONE 0 +#define TRIGGER_GUARD_NORMAL 1 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index d135e62ae69..35274d2102d 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -167,8 +167,6 @@ animals lunging, etc. */ /mob/proc/RangedAttack(var/atom/A, var/params) - if(ishuman(src) && (istype(src:gloves, /obj/item/clothing/gloves/color/yellow/power)) && a_intent == I_HARM) - PowerGlove(A) if(!mutations.len) return if((LASER in mutations) && a_intent == I_HARM) LaserEyes(A) // moved into a proc below @@ -322,58 +320,6 @@ spawn(1) LE.process() -/mob/proc/PowerGlove(atom/A) - return - -/mob/living/carbon/human/PowerGlove(atom/A) - var/obj/item/clothing/gloves/color/yellow/power/G = src:gloves - var/time = 100 - var/turf/T = get_turf(src) - var/turf/U = get_turf(A) - var/obj/structure/cable/cable = locate() in T - if(!cable || !istype(cable)) - to_chat(src, "There is no cable here to power the gloves.") - return - if(world.time < G.next_shock) - to_chat(src, "[G] aren't ready to shock again!") - return - src.visible_message("[name] fires an arc of electricity!", \ - "You fire an arc of electricity!", \ - "You hear the loud crackle of electricity!") - var/datum/powernet/PN = cable.get_powernet() - var/available = 0 - var/obj/item/projectile/beam/lightning/L = new /obj/item/projectile/beam/lightning/(get_turf(src)) - if(PN) - available = PN.avail - L.damage = PN.get_electrocute_damage() - if(available >= 5000000) - L.damage = 205 - if(L.damage >= 200) - time = 200 - else if(L.damage >= 100) - time = 150 - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - if(L.damage <= 0) - qdel(L) - if(L) - playsound(get_turf(src), 'sound/effects/eleczap.ogg', 75, 1) - L.tang = L.adjustAngle(get_angle(U,T)) - L.icon = midicon - L.icon_state = "[L.tang]" - L.firer = usr - L.def_zone = get_organ_target() - L.original = src - L.current = U - L.starting = U - L.yo = U.y - T.y - L.xo = U.x - T.x - spawn( 1 ) - L.process() - - next_move = world.time + 12 - G.next_shock = world.time + time // Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(var/atom/A) @@ -419,4 +365,4 @@ else var/turf/T = screen_loc2turf(modifiers["screen-loc"], get_turf(usr)) T.Click(location, control, params) - return 1 \ No newline at end of file + return 1 diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 08c418778a3..d9daba46e40 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -605,10 +605,10 @@ var/list/uplink_items = list() gamemodes = list(/datum/game_mode/nuclear) /datum/uplink_item/ammo/machinegun - name = "Box Magazine - 7.62x51mm" - desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses." + name = "Box Magazine - 5.56x45mm" + desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses." reference = "762" - item = /obj/item/ammo_box/magazine/m762 + item = /obj/item/ammo_box/magazine/mm556x45 cost = 12 gamemodes = list(/datum/game_mode/nuclear) surplus = 0 diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 803a7ba0d80..3c8b96935ec 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -72,7 +72,7 @@ rcd light flash thingy on matter drain if(T.z in config.station_levels) // Increase health by 37.5% of original max, decrease delays between shots to 66% turret.health += initial(turret.health) * 3 / 8 - turret.eprojectile = /obj/item/projectile/beam/heavylaser //Once you see it, you will know what it means to FEAR. + turret.eprojectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR. turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg' to_chat(src, "Turrets upgraded.") /datum/AI_Module/large/destroy_rcd diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 5107ff7cab4..d1c5428d093 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -309,7 +309,9 @@ item_state = "alienpistol" origin_tech = "combat=5;materials=4;powerstorage=3;abductor=3" -/obj/item/weapon/gun/energy/decloner/alien/special_check(user) +/obj/item/weapon/gun/energy/decloner/alien/can_trigger_gun(user) + if(!..()) + return 0 if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user if(H.get_species() != "Abductor") @@ -631,4 +633,4 @@ Congratulations! You are now trained for xenobiology research!"} icon_state = "abductor" icon_closed = "abductor" icon_opened = "abductoropen" - material_drop = /obj/item/stack/sheet/mineral/abductor \ No newline at end of file + material_drop = /obj/item/stack/sheet/mineral/abductor diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm index fd648b05c7d..25d2807432e 100644 --- a/code/game/gamemodes/steal_items.dm +++ b/code/game/gamemodes/steal_items.dm @@ -35,7 +35,7 @@ /datum/theft_objective/hoslaser name = "the head of security's recreated antique laser gun" - typepath = /obj/item/weapon/gun/energy/hos + typepath = /obj/item/weapon/gun/energy/gun/hos protected_jobs = list("Head Of Security") /datum/theft_objective/hand_tele @@ -244,4 +244,4 @@ datum/theft_objective/ai/check_special_completion(var/obj/item/device/aicard/C) typepath = /obj/item/stack/sheet/mineral/uranium min=10 max=30 - step=5 \ No newline at end of file + step=5 diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index eab12bb22d5..7378cae2b85 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -100,10 +100,9 @@ /obj/machinery/porta_turret/proc/setup() var/obj/item/weapon/gun/energy/E = installation //All energy-based weapons are applicable - if(istext(installation)) E = text2path(installation) - //var/obj/item/ammo_casing/shottype = E.projectile_type + var/obj/item/ammo_casing/shottype = E.ammo_type[1] - projectile = initial(E.projectile_type) + projectile = shottype.projectile_type eprojectile = projectile shot_sound = initial(E.fire_sound) eshot_sound = shot_sound @@ -561,9 +560,6 @@ var/list/turret_icons if(get_dist(src, L) > 7) //if it's too far away, why bother? return TURRET_NOT_TARGET - if(!check_trajectory(L, src)) //check if we have true line of sight - return TURRET_NOT_TARGET - if(emagged) // If emagged not even the dead get a rest return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 92bca16c5b7..a1559c4fb3a 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -203,7 +203,8 @@ if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg)) var/obj/item/weapon/gun/energy/disabler/cyborg/D = O if(D.power_supply.charge < D.power_supply.maxcharge) - D.power_supply.give(D.charge_cost) + var/obj/item/ammo_casing/energy/E = D.ammo_type[D.select] + D.power_supply.give(E.e_cost) D.update_icon() else D.charge_tick = 0 diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 82060d47bc2..ff24aa01027 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -227,15 +227,15 @@ if(1) A = new /obj/item/projectile/beam(loc) if(2) - A = new /obj/item/projectile/beam/heavylaser(loc) + A = new /obj/item/projectile/beam/laser/heavylaser(loc) if(3) A = new /obj/item/projectile/beam/pulse(loc) if(4) A = new /obj/item/projectile/magic/change(loc) if(5) - A = new /obj/item/projectile/lasertag/blue(loc) + A = new /obj/item/projectile/beam/lasertag/bluetag(loc) if(6) - A = new /obj/item/projectile/lasertag/red(loc) + A = new /obj/item/projectile/beam/lasertag/redtag(loc) A.original = target use_power(500) else diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index d95cbaff799..a92e949bafc 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -56,7 +56,7 @@ name = "CH-LC \"Solaris\" Laser Cannon" icon_state = "mecha_laser" energy_drain = 40 - projectile = /obj/item/projectile/beam/heavylaser + projectile = /obj/item/projectile/beam/laser/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index bfb90de8cac..512baa30703 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -125,13 +125,13 @@ to_chat(usr, "This robot has had its disabler removed!") return 0 - if(T.recharge_time <= 2) + if(T.charge_delay <= 2) to_chat(R, "Maximum cooling achieved for this hardpoint!") to_chat(usr, "There's no room for another cooling unit!") return 0 else - T.recharge_time = max(2 , T.recharge_time - 4) + T.charge_delay = max(2 , T.charge_delay - 4) return 1 @@ -214,4 +214,4 @@ return 0 R.emagged = 1 - return 1 \ No newline at end of file + return 1 diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index c71f2e14182..fd3f5505f4f 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -114,7 +114,7 @@ bmark.pixel_x-- bmark.pixel_y-- - if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/practice)) + if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/beam/practice)) bmark.icon_state = "scorch" bmark.dir = pick(NORTH,SOUTH,EAST,WEST) // random scorch design @@ -178,4 +178,4 @@ b2y1 = pixel_y + pick(1,1,1,1,2,2,3,3,4) b2y2 = pixel_y - pick(1,1,1,1,2,2,3,3,4) - Target.bulletholes.Add(src) \ No newline at end of file + Target.bulletholes.Add(src) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 3fe6dc7102f..c4c5d3cea4c 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -140,7 +140,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \ - new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0), \ + /*new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0), \ */ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("easel", /obj/structure/easel, 3, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index e0ac96c4feb..b0a1c45622d 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -41,12 +41,11 @@ icon = 'icons/obj/chronos.dmi' icon_state = "chronogun" item_state = "chronogun" - w_class = 3.0 - projectile_type = "/obj/item/projectile/energy/chrono_beam" - fire_sound = 'sound/weapons/Laser.ogg' - charge_cost = 0 - fire_delay = 50 + w_class = 3 flags = NODROP + ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam) + can_charge = 0 + fire_delay = 50 var/obj/item/weapon/chrono_eraser/TED = null var/obj/effect/chrono_field/field = null var/turf/startpos = null @@ -60,12 +59,13 @@ qdel(src) /obj/item/weapon/gun/energy/chrono_gun/dropped() + ..() qdel(src) /obj/item/weapon/gun/energy/chrono_gun/update_icon() return -/obj/item/weapon/gun/energy/chrono_gun/Fire() +/obj/item/weapon/gun/energy/chrono_gun/process_fire() if(field) field_disconnect(field) ..() @@ -125,18 +125,23 @@ nodamage = 1 var/obj/item/weapon/gun/energy/chrono_gun/gun = null -/obj/item/projectile/energy/chrono_beam/process() +/obj/item/projectile/energy/chrono_beam/fire() gun = firer.get_active_hand() if(istype(gun)) return ..() else return 0 -/obj/item/projectile/energy/chrono_beam/on_hit(var/atom/target) +/obj/item/projectile/energy/chrono_beam/on_hit(atom/target) if(target && gun && isliving(target)) var/obj/effect/chrono_field/F = new(target.loc, target, gun) gun.field_connect(F) +/obj/item/ammo_casing/energy/chrono_beam + name = "eradication beam" + projectile_type = /obj/item/projectile/energy/chrono_beam + icon_state = "chronobolt" + e_cost = 0 /obj/effect/chrono_field name = "eradication field" @@ -256,4 +261,4 @@ #undef CHRONO_BEAM_RANGE -#undef CHRONO_FRAME_COUNT \ No newline at end of file +#undef CHRONO_FRAME_COUNT diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 4a2ced79339..1cadbfbd14a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -115,7 +115,7 @@ new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/weapon/storage/belt/security/sec(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/energy/hos(src) + new /obj/item/weapon/gun/energy/gun/hos(src) new /obj/item/weapon/door_remote/head_of_security(src) diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm index 75fc6af84d9..4afbeaa4f15 100644 --- a/code/modules/admin/verbs/honksquad.dm +++ b/code/modules/admin/verbs/honksquad.dm @@ -120,8 +120,8 @@ var/global/sent_honksquad = 0 equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/spray/waterflower(src), slot_in_backpack) if(prob(50)) equip_to_slot_or_del(new /obj/item/weapon/gun/energy/clown(src), slot_in_backpack) - else - equip_to_slot_or_del(new /obj/item/weapon/gun/grenadelauncher/piecannon(src), slot_in_backpack) + //else + //equip_to_slot_or_del(new /obj/item/weapon/gun/grenadelauncher/piecannon(src), slot_in_backpack) src.mutations.Add(CLUMSY) @@ -134,4 +134,4 @@ var/global/sent_honksquad = 0 W.registered_name = real_name equip_to_slot_or_del(W, slot_wear_id) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index 6131962b881..0b84e6d065a 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -144,7 +144,7 @@ var/global/sent_syndicate_strike_team = 0 equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses) equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back) - equip_to_slot_or_del(new /obj/item/ammo_box/magazine/m762, slot_in_backpack) + equip_to_slot_or_del(new /obj/item/ammo_box/magazine/mm556x45) equip_to_slot_or_del(new /obj/item/ammo_box/magazine/m45(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack) @@ -173,4 +173,4 @@ var/global/sent_syndicate_strike_team = 0 W.registered_name = real_name equip_to_slot_or_del(W, slot_wear_id) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm index c5e370f06f7..0f6f3dda06e 100644 --- a/code/modules/admin/verbs/vox_raiders.dm +++ b/code/modules/admin/verbs/vox_raiders.dm @@ -18,8 +18,8 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store) - var/obj/item/weapon/gun/launcher/spikethrower/W = new(src) - equip_to_slot_or_del(W, slot_r_hand) + //var/obj/item/weapon/gun/launcher/spikethrower/W = new(src) + //equip_to_slot_or_del(W, slot_r_hand) if(2) // Vox engineer! @@ -77,4 +77,4 @@ var/global/vox_tick = 1 vox_tick++ if (vox_tick > 4) vox_tick = 1 - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 2473fd24eb8..16ddf2bdd69 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -119,7 +119,7 @@ gun.attack_self(holder.wearer) return 1 - gun.Fire(target,holder.wearer) + gun.process_fire(target,holder.wearer) return 1 /obj/item/rig_module/mounted/egun @@ -168,7 +168,7 @@ active_power_cost = 10 passive_power_cost = 0 - gun_type = /obj/item/weapon/gun/energy/crossbow/ninja + gun_type = /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/ninja /obj/item/rig_module/mounted/energy_blade/process() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 7775830b4a0..cb067591904 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1982,4 +1982,21 @@ . |= A.GetAccess() /mob/living/carbon/human/is_mechanical() - return ..() || (species.flags & ALL_RPARTS) != 0 \ No newline at end of file + return ..() || (species.flags & ALL_RPARTS) != 0 + +/mob/living/carbon/human/can_use_guns(var/obj/item/weapon/gun/G) + . = ..() + + if(G.trigger_guard == TRIGGER_GUARD_NORMAL) + if(HULK in mutations) + to_chat(src, "Your meaty finger is much too large for the trigger guard!") + return 0 + if(species.flags & NOGUNS) + to_chat(src, "Your fingers don't fit in the trigger guard!") + return 0 + + if(martial_art && martial_art.name == "The Sleeping Carp") //great dishonor to famiry + to_chat(src, "Use of ranged weaponry would bring dishonor to the clan.") + return 0 + + return . diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 835f741be3d..c30e02f5881 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -46,7 +46,10 @@ emp_act if((P.embed && prob(20 + max(P.damage - armor, -10)))) var/obj/item/weapon/shard/shrapnel/SP = new() (SP.name) = "[P.name] shrapnel" - (SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]." + if(P.ammo_casing && P.ammo_casing.caliber) + (SP.desc) = "[SP.desc] It looks like it is a [P.ammo_casing.caliber] caliber round." + else + (SP.desc) = "[SP.desc] The round's caliber is unidentifiable." (SP.loc) = organ organ.embed(SP) diff --git a/code/modules/mob/living/carbon/human/interactive/functions.dm b/code/modules/mob/living/carbon/human/interactive/functions.dm index 0a220accc98..b0806e66241 100644 --- a/code/modules/mob/living/carbon/human/interactive/functions.dm +++ b/code/modules/mob/living/carbon/human/interactive/functions.dm @@ -693,7 +693,7 @@ best = R if(istype(R, /obj/item/weapon/gun)) var/obj/item/weapon/gun/G = R - if(G.can_fire()) + if(G.can_shoot()) best = R break // gun with ammo? screw the rest if(best && best != main_hand) @@ -727,22 +727,23 @@ if(main_hand.force != 0) if(istype(main_hand,/obj/item/weapon/gun)) var/obj/item/weapon/gun/G = main_hand - if(G.special_check(src)) + if(G.can_trigger_gun(src)) var/shouldFire = 1 if(istype(main_hand, /obj/item/weapon/gun/energy)) var/obj/item/weapon/gun/energy/P = main_hand var/stunning = 0 - if(ispath(text2path(P.projectile_type), /obj/item/projectile/energy/electrode)) - stunning = 1 + for(var/A in P.ammo_type) + if(ispath(A,/obj/item/ammo_casing/energy/electrode)) + stunning = 1 var/mob/stunCheck = TARGET if(stunning && stunCheck.stunned) shouldFire = 0 if(shouldFire) - if(!G.process_chambered()) - G.click_empty(src) + if(!G.can_shoot()) + G.shoot_with_empty_chamber(src) npcDrop(G, 1) else - G.Fire(TARGET, src) + G.process_fire(TARGET, src) else if(get_dist(src,TARGET) > 6) if(!walk2derpless(TARGET)) @@ -871,4 +872,4 @@ else A.stamp(S) custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")] as they stamp \the [A] with \a [S]!") - return \ No newline at end of file + return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f28e884f92f..f3c48bce39a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -855,3 +855,9 @@ tally += 10 return tally + +/mob/living/proc/can_use_guns(var/obj/item/weapon/gun/G) + if (G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser()) + to_chat(src, "You don't have the dexterity to do this!") + return 0 + return 1 diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 4d994436489..cc50408148e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -47,10 +47,6 @@ proj_sharp = 0 proj_edge = 0 - if(istype(P, /obj/item/projectile/beam/lightning)) //Stupid snowflake lightning gun. - if(P.damage >= 200) - src.dust() - if(!P.nodamage) apply_damage(P.damage, P.damage_type, def_zone, armor) return P.on_hit(src, armor, def_zone) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 12dd032ba49..23b87eb0c51 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -403,7 +403,7 @@ Auto Patrol[]"}, shoot_sound = 'sound/weapons/laser.ogg' if(emagged == 2) if(lasercolor) - projectile = /obj/item/projectile/lasertag + projectile = /obj/item/projectile/beam/lasertag else projectile = /obj/item/projectile/beam else @@ -411,9 +411,9 @@ Auto Patrol[]"}, shoot_sound = 'sound/weapons/Taser.ogg' projectile = /obj/item/projectile/energy/electrode else if(lasercolor == "b") - projectile = /obj/item/projectile/lasertag/blue + projectile = /obj/item/projectile/beam/lasertag/bluetag else if(lasercolor == "r") - projectile = /obj/item/projectile/lasertag/red + projectile = /obj/item/projectile/beam/lasertag/redtag /mob/living/simple_animal/bot/ed209/proc/shootAt(mob/target) if(lastfired && world.time - lastfired < shot_delay) @@ -491,10 +491,10 @@ Auto Patrol[]"}, if(!disabled) var/lasertag_check = 0 if((lasercolor == "b")) - if(istype(Proj, /obj/item/projectile/lasertag/red)) + if(istype(Proj, /obj/item/projectile/beam/lasertag/redtag)) lasertag_check++ else if((lasercolor == "r")) - if(istype(Proj, /obj/item/projectile/lasertag/blue)) + if(istype(Proj, /obj/item/projectile/beam/lasertag/bluetag)) lasertag_check++ if(lasertag_check) icon_state = "[lasercolor]ed2090" diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm index 3b34ddaf143..0ca934739d5 100644 --- a/code/modules/mob/living/simple_animal/vox.dm +++ b/code/modules/mob/living/simple_animal/vox.dm @@ -65,9 +65,9 @@ if ((O.client && !( O.blinded ))) to_chat(O, "\red [src] launches a razor-sharp quill at [target]!") - var/obj/item/weapon/arrow/quill/Q = new(loc) - Q.fingerprintslast = src.ckey - Q.throw_at(target,10,30) + //var/obj/item/weapon/arrow/quill/Q = new(loc) + //Q.fingerprintslast = src.ckey + //Q.throw_at(target,10,30) quills-- spawn(100) @@ -155,4 +155,4 @@ desc = "A series of metallic lenses and chains." icon = 'icons/obj/clothing/hats.dmi' icon_state = "amp" - item_state = "amp" \ No newline at end of file + item_state = "amp" diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 169e968afaf..ab3c224ac08 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -17,7 +17,6 @@ var/randomspread = 0 //Randomspread for automatics var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. - /obj/item/ammo_casing/New() ..() if(projectile_type) @@ -32,6 +31,11 @@ icon_state = "[initial(icon_state)][BB ? "-live" : ""]" desc = "[initial(desc)][BB ? "" : " This one is spent"]" +/obj/item/ammo_casing/proc/newshot() //For energy weapons, shotgun shells and wands (!). + if (!BB) + BB = new projectile_type(src) + return + /obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/ammo_box)) var/obj/item/ammo_box/box = I @@ -99,7 +103,7 @@ update_icon() /obj/item/ammo_box/Destroy() - for(atom/A in stored_ammo) + for(var/atom/A in stored_ammo) qdel(A) stored_ammo = null return ..() @@ -128,7 +132,7 @@ for(var/obj/item/ammo_casing/AC in stored_ammo) if(!AC.BB)//found a spent ammo stored_ammo -= AC - AC.loc = get_turf(src.loc) + AC.loc = get_turf(loc) stored_ammo += R R.loc = src diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 010ce185acb..980e9fb16bc 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -96,7 +96,7 @@ icon_state = "gshell" projectile_type = /obj/item/projectile/bullet/pellet pellets = 6 - deviation = 25 + variance = 25 /obj/item/ammo_casing/shotgun/rubbershot name = "rubber shot" @@ -104,7 +104,7 @@ icon_state = "bshell" projectile_type = /obj/item/projectile/bullet/rpellet pellets = 6 - deviation = 25 + variance = 25 materials = list(MAT_METAL=4000) /obj/item/ammo_casing/shotgun/beanbag @@ -121,17 +121,17 @@ projectile_type = /obj/item/projectile/bullet/pellet/weak materials = list(MAT_METAL=250) pellets = 5 - deviation = 25 + variance = 25 /obj/item/ammo_casing/shotgun/improvised/overload name = "overloaded improvised shell" desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards. This one has been packed with even more \ propellant. It's like playing russian roulette, with a shotgun." icon_state = "improvshell" - projectile_type = /obj/item/projectile/bullet/pellet/random + projectile_type = /obj/item/projectile/bullet/pellet/overload materials = list(MAT_METAL=250) pellets = 5 - deviation = 40 + variance = 40 /obj/item/ammo_casing/shotgun/improvised/overload/New() ..() @@ -191,7 +191,7 @@ icon_state = "ionshell" projectile_type = /obj/item/projectile/ion/weak pellets = 4 - deviation = 35 + variance = 35 /obj/item/ammo_casing/shotgun/laserslug name = "laser slug" diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index b4e979e3b20..4fc5295e8ae 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -110,7 +110,8 @@ /obj/item/ammo_casing/energy/temp/newshot() ..() - BB.temperature = temperature + var/obj/item/projectile/temp/T = BB + T.temperature = temperature /obj/item/ammo_casing/energy/meteor projectile_type = /obj/item/projectile/meteor @@ -202,7 +203,7 @@ projectile_type = /obj/item/projectile/energy/shock_revolver /obj/item/ammo_casing/energy/toxplasma - projectile_type = /obj/item/projectile/toxplasma + projectile_type = /obj/item/projectile/energy/toxplasma fire_sound = "sound/weapons/taser2.ogg" select_name = "plasma dart" @@ -214,7 +215,7 @@ /obj/item/ammo_casing/energy/sniper projectile_type = /obj/item/projectile/beam/sniper fire_sound = 'sound/weapons/marauder.ogg' - fire_delay = 50 + delay = 50 select_name = "sniper beam" /obj/item/ammo_casing/energy/teleport @@ -222,3 +223,8 @@ fire_sound = 'sound/weapons/wave.ogg' e_cost = 1250 select_name = "teleport beam" + var/teleport_target + +/obj/item/ammo_casing/energy/teleport/newshot() + var/obj/item/projectile/energy/teleport/T = BB + T.teleport_target = teleport_target diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index e26e536e62a..367270d0cd1 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -50,7 +50,7 @@ R.loc = src if(bullet) - bullet.loc = get_turf(src.loc) + bullet.loc = get_turf(loc) return 1 return 0 diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index 9642923c452..c17a7948fcb 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -28,7 +28,7 @@ if (zone_override) BB.def_zone = zone_override else - BB.def_zone = user.zone_selected + BB.def_zone = user.zone_sel.selecting BB.suppressed = quiet if(reagents && BB.reagents) @@ -60,18 +60,18 @@ /obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread) var/turf/curloc = get_turf(user) - src.loc = get_turf(user) - src.starting = get_turf(user) - src.current = curloc - src.yo = targloc.y - curloc.y - src.xo = targloc.x - curloc.x + loc = get_turf(user) + starting = get_turf(user) + current = curloc + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x if(params) var/list/mouse_control = params2list(params) if(mouse_control["icon-x"]) - src.p_x = text2num(mouse_control["icon-x"]) + p_x = text2num(mouse_control["icon-x"]) if(mouse_control["icon-y"]) - src.p_y = text2num(mouse_control["icon-y"]) + p_y = text2num(mouse_control["icon-y"]) if(mouse_control["screen-loc"]) //Split screen-loc up into X+Pixel_X and Y+Pixel_Y var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") @@ -90,6 +90,6 @@ var/ox = round(screenview/2) //"origin" x var/oy = round(screenview/2) //"origin" y var/angle = Atan2(y - oy, x - ox) - src.Angle = angle + Angle = angle if(spread) - src.Angle += spread + Angle += spread diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 7d72082b297..8233a172af8 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -65,7 +65,6 @@ ..() if(F) verbs += /obj/item/weapon/gun/proc/toggle_gunlight - new /datum/action/item_action/toggle_gunlight(src) build_zooming() /obj/item/weapon/gun/examine(mob/user) @@ -120,7 +119,7 @@ return if(!ismob(target) || user.a_intent == "harm") //melee attack return - if(target == user && user.zone_selected != "mouth") //so we can't shoot ourselves (unless mouth selected) + if(target == user && user.zone_sel.selecting != "mouth") //so we can't shoot ourselves (unless mouth selected) return if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can. @@ -133,7 +132,7 @@ return if(flag) - if(user.zone_selected == "mouth") + if(user.zone_sel.selecting == "mouth") handle_suicide(user, target, params) return @@ -222,7 +221,7 @@ obj/item/weapon/gun/proc/newshot() user.update_inv_l_hand() else user.update_inv_r_hand() - feedback_add_details("gun_fired","[src.type]") + feedback_add_details("gun_fired","[type]") /obj/item/weapon/gun/attack(mob/M as mob, mob/user) if(user.a_intent == "harm") //Flogging @@ -239,15 +238,12 @@ obj/item/weapon/gun/proc/newshot() return to_chat(user, "You click [S] into place on [src].") if(S.on) - SetLuminosity(0) + set_light(0) F = S I.loc = src update_icon() update_gunlight(user) verbs += /obj/item/weapon/gun/proc/toggle_gunlight - var/datum/action/A = new /datum/action/item_action/toggle_gunlight(src) - if(loc == user) - A.Grant(user) if(istype(I, /obj/item/weapon/screwdriver)) if(F && can_flashlight) @@ -259,8 +255,6 @@ obj/item/weapon/gun/proc/newshot() S.update_brightness(user) update_icon() verbs -= /obj/item/weapon/gun/proc/toggle_gunlight - for(var/datum/action/item_action/toggle_gunlight/TGL in actions) - qdel(TGL) if(unique_rename) if(istype(I, /obj/item/weapon/pen)) @@ -351,7 +345,7 @@ obj/item/weapon/gun/proc/newshot() semicd = 1 - if(!do_mob(user, target, 120) || user.zone_selected != "mouth") + if(!do_mob(user, target, 120) || user.zone_sel.selecting != "mouth") if(user) if(user == target) user.visible_message("[user] decided life was worth living.") diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 56852f4e1ae..a503e92dd6b 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -1,71 +1,5 @@ -//Vox pinning weapon. -/obj/item/weapon/gun/launcher/spikethrower - - name = "Vox spike thrower" - desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive." - - var/last_regen = 0 - var/spike_gen_time = 100 - var/max_spikes = 3 - var/spikes = 3 - release_force = 30 - icon = 'icons/obj/gun.dmi' - icon_state = "spikethrower3" - item_state = "spikethrower" - fire_sound_text = "a strange noise" - fire_sound = 'sound/weapons/bladeslice.ogg' - -/obj/item/weapon/gun/launcher/spikethrower/New() - ..() - processing_objects.Add(src) - last_regen = world.time - -/obj/item/weapon/gun/launcher/spikethrower/Destroy() - processing_objects.Remove(src) - return ..() - -/obj/item/weapon/gun/launcher/spikethrower/process() - - if(spikes < max_spikes && world.time > last_regen + spike_gen_time) - spikes++ - last_regen = world.time - update_icon() - -/obj/item/weapon/gun/launcher/spikethrower/examine(mob/user) - ..(user) - to_chat(user, "It has [spikes] [spikes == 1 ? "spike" : "spikes"] remaining.") - -/obj/item/weapon/gun/launcher/spikethrower/update_icon() - icon_state = "spikethrower[spikes]" - -/obj/item/weapon/gun/launcher/spikethrower/emp_act(severity) - return - -/obj/item/weapon/gun/launcher/spikethrower/special_check(user) - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis") - to_chat(user, "\red \The [src] does not respond to you!") - return 0 - return 1 - -/obj/item/weapon/gun/launcher/spikethrower/update_release_force() - return - -/obj/item/weapon/gun/launcher/spikethrower/chamber_round() - if(in_chamber) return 1 - if(spikes < 1) return 0 - - spikes-- - in_chamber = new /obj/item/weapon/spike(src) - return 1 - -/obj/item/weapon/gun/launcher/spikethrower/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(..()) update_icon() - //This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites. /obj/item/weapon/gun/energy/noisecannon - name = "alien heavy cannon" desc = "It's some kind of enormous alien weapon, as long as a man is tall." @@ -73,15 +7,11 @@ icon_state = "noisecannon" item_state = "noisecannon" recoil = 1 - force = 10 - projectile_type = "/obj/item/projectile/energy/sonic" + ammo_type = "/obj/item/projectile/energy/sonic" cell_type = "/obj/item/weapon/stock_parts/cell/super" - fire_delay = 40 fire_sound = 'sound/effects/basscannon.ogg' - var/mode = 1 - /obj/item/weapon/gun/energy/noisecannon/attack_hand(mob/user as mob) if(loc != user) var/mob/living/carbon/human/H = user @@ -89,16 +19,18 @@ if(H.species.name == "Vox Armalis") ..() return - to_chat(user, "\red \The [src] is far too large for you to pick up.") + to_chat(user, "\The [src] is far too large for you to pick up.") return -/obj/item/weapon/gun/energy/noisecannon/process_chambered() //Does not have ammo. - in_chamber = new projectile_type(src) - return 1 - /obj/item/weapon/gun/energy/noisecannon/update_icon() return +//Casing +/obj/item/ammo_casing/energy/sonic + projectile_type = /obj/item/projectile/energy/sonic + fire_sound = 'sound/effects/basscannon.ogg' + delay = 40 + //Projectile. /obj/item/projectile/energy/sonic name = "distortion" diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index df023424265..32c3009f312 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -3,6 +3,7 @@ name = "energy gun" desc = "A basic energy-based gun." fire_sound = 'sound/weapons/Taser.ogg' + fire_sound_text = "laser blast" var/obj/item/weapon/stock_parts/cell/power_supply //What type of power cell this uses var/cell_type = /obj/item/weapon/stock_parts/cell @@ -42,23 +43,24 @@ update_icon() /obj/item/weapon/gun/energy/Destroy() - if(self_recharge) + if(selfcharge) processing_objects.Remove(src) return ..() /obj/item/weapon/gun/energy/process() if(selfcharge) //Every [recharge_time] ticks, recharge a shot for the cyborg charge_tick++ - if(charge_tick < recharge_time) + if(charge_tick < charge_delay) return 0 charge_tick = 0 if(!power_supply) return 0 // check if we actually need to recharge + var/obj/item/ammo_casing/energy/E = ammo_type[select] if(use_external_power) var/obj/item/weapon/stock_parts/cell/external = get_external_power_supply() - if(!external || !external.use(charge_cost/10)) //Take power from the borg... + if(!external || !external.use((E.e_cost)/10)) //Take power from the borg... return 0 //Note, uses /10 because of shitty mods to the cell system - power_supply.give(charge_cost) //... to recharge the shot + power_supply.give(E.e_cost) //... to recharge the shot update_icon() /obj/item/weapon/gun/energy/attack_self(mob/living/user as mob) @@ -136,11 +138,11 @@ toggle_gunlight() /obj/item/weapon/gun/energy/suicide_act(mob/user) - if (src.can_shoot()) - user.visible_message("[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.") + if (can_shoot()) + user.visible_message("[user] is putting the barrel of the [name] in \his mouth. It looks like \he's trying to commit suicide.") sleep(25) if(user.l_hand == src || user.r_hand == src) - user.visible_message("[user] melts \his face off with the [src.name]!") + user.visible_message("[user] melts \his face off with the [name]!") playsound(loc, fire_sound, 50, 1, -1) var/obj/item/ammo_casing/energy/shot = ammo_type[select] power_supply.use(shot.e_cost) @@ -150,21 +152,21 @@ user.visible_message("[user] panics and starts choking to death!") return(OXYLOSS) else - user.visible_message("[user] is pretending to blow \his brains out with the [src.name]! It looks like \he's trying to commit suicide!") + user.visible_message("[user] is pretending to blow \his brains out with the [name]! It looks like \he's trying to commit suicide!") playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) return (OXYLOSS) /obj/item/weapon/gun/energy/proc/robocharge() - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc + if(isrobot(loc)) + var/mob/living/silicon/robot/R = loc if(R && R.cell) var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot if(R.cell.use(shot.e_cost/10)) //Take power from the borg... //Divided by 10 because cells and charge costs are fucked. power_supply.give(shot.e_cost) //... to recharge the shot /obj/item/weapon/gun/energy/proc/get_external_power_supply() - if(istype(src.loc, /obj/item/rig_module)) - var/obj/item/rig_module/module = src.loc + if(istype(loc, /obj/item/rig_module)) + var/obj/item/rig_module/module = loc if(module.holder && module.holder.wearer) var/mob/living/carbon/human/H = module.holder.wearer if(istype(H) && H.back) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 46add8b8b47..952c61aaf00 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -92,9 +92,9 @@ /obj/item/weapon/gun/energy/lasercannon/mounted name = "mounted laser cannon" - self_recharge = 1 + selfcharge = 1 use_external_power = 1 - recharge_time = 10 + charge_delay = 10 /obj/item/weapon/gun/energy/lasercannon/cyborg @@ -130,7 +130,6 @@ origin_tech = "combat=1;magnets=2" clumsy_check = 0 needs_permit = 0 - pin = /obj/item/device/firing_pin/tag/blue ammo_x_offset = 2 selfcharge = 1 @@ -142,6 +141,5 @@ origin_tech = "combat=1;magnets=2" clumsy_check = 0 needs_permit = 0 - pin = /obj/item/device/firing_pin/tag/red ammo_x_offset = 2 selfcharge = 1 diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index b53563c81a7..ff9ef57a322 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -23,7 +23,7 @@ /obj/item/weapon/gun/energy/gun/mounted name = "mounted energy gun" - self_recharge = 1 + selfcharge = 1 use_external_power = 1 /obj/item/weapon/gun/energy/gun/mini @@ -37,8 +37,8 @@ can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update /obj/item/weapon/gun/energy/gun/mini/New() - cell.maxcharge = 6000 - cell.charge = 6000 + power_supply.maxcharge = 6000 + power_supply.charge = 6000 F = new /obj/item/device/flashlight/seclite(src) ..() @@ -84,7 +84,6 @@ origin_tech = "combat=3;materials=5;powerstorage=3" var/fail_tick = 0 charge_delay = 5 - pin = null can_charge = 0 ammo_x_offset = 1 ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler) @@ -106,11 +105,11 @@ switch(fail_tick) if(0 to 200) fail_tick += (2*(100-reliability)) - M.rad_act(40) + M.apply_effect(rand(3,120), IRRADIATE) to_chat(M, "Your [name] feels warmer.") if(201 to INFINITY) - SSobj.processing.Remove(src) - M.rad_act(80) + processing_objects.Remove(src) + M.apply_effect(300, IRRADIATE) crit_fail = 1 to_chat(M, "Your [name]'s reactor overloads!") @@ -130,27 +129,3 @@ overlays += "[icon_state]_fail_1" if(151 to INFINITY) overlays += "[icon_state]_fail_2" - -/obj/item/weapon/gun/energy/gun/turret/attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 500 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = /obj/item/projectile/beam - modifystate = "energykill" - fire_delay = 0 - if(1) - mode = 0 - charge_cost = 1000 - fire_sound = 'sound/weapons/Taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = /obj/item/projectile/energy/electrode - modifystate = "energystun" - fire_delay = 15 - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index b8ddc12a691..0587040afe4 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -54,7 +54,7 @@ ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse) /obj/item/weapon/gun/energy/pulse/destroyer/attack_self(mob/living/user) - to_chat(user, "[src.name] has three settings, and they are all DESTROY.") + to_chat(user, "[name] has three settings, and they are all DESTROY.") /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911 name = "\improper M1911-P" diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index e0328ac6058..949e0ef7d7d 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -173,7 +173,7 @@ /obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload() power_supply.give(5000) if(!suppressed) - playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) else to_chat(loc, "[src] silently charges up.") update_icon() @@ -200,6 +200,10 @@ holds_charge = TRUE unique_frequency = TRUE +/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/ninja + name = "energy dart thrower" + ammo_type = list(/obj/item/ammo_casing/energy/dart) + /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large name = "energy crossbow" desc = "A reverse engineered weapon using syndicate technology." @@ -218,8 +222,8 @@ /obj/item/weapon/gun/energy/kinetic_accelerator/suicide_act(mob/user) if(!suppressed) - playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) - user.visible_message("[user] cocks the [src.name] and pretends to blow \his brains out! It looks like \he's trying to commit suicide!") + playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + user.visible_message("[user] cocks the [name] and pretends to blow \his brains out! It looks like \he's trying to commit suicide!") shoot_live_shot() return (OXYLOSS) @@ -235,9 +239,9 @@ flags = CONDUCT | OPENCONTAINER attack_verb = list("attacked", "slashed", "cut", "sliced") force = 12 - sharpness = IS_SHARP + sharp = 1 + edge = 1 can_charge = 0 - heat = 3800 /obj/item/weapon/gun/energy/plasmacutter/examine(mob/user) ..() @@ -406,7 +410,7 @@ obj/item/weapon/gun/energy/staff/focus var/e_cost = 1000 origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" - ammo_type = /obj/item/ammo_casing/energy/temp + ammo_type = list(/obj/item/ammo_casing/energy/temp) cell_type = "/obj/item/weapon/stock_parts/cell" var/powercost = "" @@ -427,8 +431,9 @@ obj/item/weapon/gun/energy/staff/focus /obj/item/weapon/gun/energy/temperature/newshot() ..() - chambered.temperature = temperature - chambered.e_cost = e_cost + var/obj/item/ammo_casing/energy/temp/T = chambered + T.temperature = temperature + T.e_cost = e_cost /obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) user.set_machine(src) @@ -459,23 +464,22 @@ obj/item/weapon/gun/energy/staff/focus add_fingerprint(usr) return - /obj/item/weapon/gun/energy/temperature/process() switch(temperature) if(0 to 100) - charge_cost = 3000 + e_cost = 3000 powercost = "High" if(100 to 250) - charge_cost = 2000 + e_cost = 2000 powercost = "Medium" if(251 to 300) - charge_cost = 1000 + e_cost = 1000 powercost = "Low" if(301 to 400) - charge_cost = 2000 + e_cost = 2000 powercost = "Medium" if(401 to 1000) - charge_cost = 3000 + e_cost = 3000 powercost = "High" switch(powercost) if("High") powercostcolor = "orange" diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 5e3f5128d6f..6fdbe55c171 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -9,7 +9,7 @@ /obj/item/weapon/gun/energy/taser/mounted name = "mounted taser gun" - self_recharge = 1 + selfcharge = 1 use_external_power = 1 /obj/item/weapon/gun/energy/taser/cyborg diff --git a/code/modules/projectiles/guns/energy/telegun.dm b/code/modules/projectiles/guns/energy/telegun.dm index e145e2ccbcf..0113f11068c 100644 --- a/code/modules/projectiles/guns/energy/telegun.dm +++ b/code/modules/projectiles/guns/energy/telegun.dm @@ -35,3 +35,7 @@ var/desc = input("Please select a location to lock in.", "Telegun Target Interface") in L teleport_target = L[desc] + +/obj/item/weapon/gun/energy/telegun/newshot() + var/obj/item/ammo_casing/energy/teleport/T = chambered + T.teleport_target = teleport_target diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm index 5d883ac7de7..7af9c18ea7d 100644 --- a/code/modules/projectiles/guns/grenade_launcher.dm +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -15,7 +15,7 @@ /obj/item/weapon/gun/grenadelauncher/examine(mob/user) if(..(user, 2)) - to_chat(user, "[grenades.len] / [max_grenades] [ammo_name]s.") + to_chat(user, "[grenades.len] / [max_grenades] grenades.") /obj/item/weapon/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params) if((istype(I, /obj/item/weapon/grenade))) @@ -24,10 +24,10 @@ return I.loc = src grenades += I - to_chat(user, "You put the [ammo_name] in the [name].") - to_chat(user, "[grenades.len] / [max_grenades] [ammo_name]s.") + to_chat(user, "You put the grenade in the [name].") + to_chat(user, "[grenades.len] / [max_grenades] grenades.") else - to_chat(user, "The grenade launcher cannot hold more [ammo_name]s.") + to_chat(user, "The grenade launcher cannot hold more grenades.") /obj/item/weapon/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) if(target == user) @@ -45,8 +45,8 @@ grenades -= F F.loc = 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]).") + message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([name]).") + log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([name]).") F.active = 1 F.icon_state = initial(icon_state) + "_active" playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index b64fb37e1c6..299c87b536f 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -5,6 +5,7 @@ icon_state = "staffofnothing" item_state = "staff" fire_sound = 'sound/weapons/emitter.ogg' + fire_sound_text = "energy blast" flags = CONDUCT w_class = 5 var/max_charges = 6 @@ -75,6 +76,6 @@ return /obj/item/weapon/gun/magic/suicide_act(mob/user) - user.visible_message("[user] is twisting the [src.name] above \his head, releasing a magical blast! It looks like \he's trying to commit suicide.") + user.visible_message("[user] is twisting the [name] above \his head, releasing a magical blast! It looks like \he's trying to commit suicide.") playsound(loc, fire_sound, 50, 1, -1) return FIRELOSS diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index c6d5bc4bf00..abde404e87d 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -67,7 +67,7 @@ var/message ="You irradiate yourself with pure energy! " message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") to_chat(user, message) - user.adjustBurnLoss(500) + user.adjustFireLoss(500) charges-- ..() diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index bd5f6b23e79..032874c4918 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -48,7 +48,7 @@ spawn(0) current_beam.Start() - feedback_add_details("gun_fired","[src.type]") + feedback_add_details("gun_fired","[type]") /obj/item/weapon/gun/medbeam/process() var/mob/living/carbon/human/H = loc diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/mounted.dm index b200dd1d6a7..592908a6b87 100644 --- a/code/modules/projectiles/guns/mounted.dm +++ b/code/modules/projectiles/guns/mounted.dm @@ -12,7 +12,7 @@ /obj/item/weapon/gun/energy/advtaser/mounted/dropped()//if somebody manages to drop this somehow... ..() - src.loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases. + loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases. /obj/item/weapon/gun/energy/laser/mounted name = "mounted laser" @@ -28,4 +28,4 @@ /obj/item/weapon/gun/energy/laser/mounted/dropped() ..() - src.loc = null + loc = null diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index fddc09349ab..3fc01b0a5b5 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -96,7 +96,7 @@ if(user.l_hand != src && user.r_hand != src) ..() return - to_chat(user, "You unscrew [silenced] from [src].") + to_chat(user, "You unscrew [suppressed] from [src].") user.put_in_hands(suppressed) fire_sound = S.oldsound w_class = S.initial_w_class @@ -108,7 +108,7 @@ /obj/item/weapon/gun/projectile/attack_self(mob/living/user as mob) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) - magazine.loc = get_turf(src.loc) + magazine.loc = get_turf(loc) user.put_in_hands(magazine) magazine.update_icon() magazine = null @@ -136,18 +136,18 @@ return boolets /obj/item/weapon/gun/projectile/suicide_act(mob/user) - if (src.chambered && src.chambered.BB && !src.chambered.BB.nodamage) - user.visible_message("[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.") + if (chambered && chambered.BB && !chambered.BB.nodamage) + user.visible_message("[user] is putting the barrel of the [name] in \his mouth. It looks like \he's trying to commit suicide.") sleep(25) if(user.l_hand == src || user.r_hand == src) process_fire(user, user, 0, zone_override = "head") - user.visible_message("[user] blows \his brains out with the [src.name]!") + user.visible_message("[user] blows \his brains out with the [name]!") return(BRUTELOSS) else user.visible_message("[user] panics and starts choking to death!") return(OXYLOSS) else - user.visible_message("[user] is pretending to blow \his brains out with the [src.name]! It looks like \he's trying to commit suicide!") + user.visible_message("[user] is pretending to blow \his brains out with the [name]! It looks like \he's trying to commit suicide!") playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) return (OXYLOSS) diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 8e700c92cc0..b3d09e049cd 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -1,6 +1,5 @@ /obj/item/weapon/gun/projectile/automatic w_class = 3.0 - automatic = 1 var/alarmed = 0 var/select = 1 can_suppress = 1 @@ -37,14 +36,14 @@ if(istype(AM, mag_type)) if(magazine) to_chat(user, "You perform a tactical reload on \the [src], replacing the magazine.") - magazine.forceMove(get_turf(src.loc)) + magazine.loc = get_turf(loc) magazine.update_icon() magazine = null else to_chat(user, "You insert the magazine into \the [src].") user.remove_from_mob(AM) magazine = AM - magazine.forceMove(src) + magazine.loc = src chamber_round() A.update_icon() update_icon() @@ -74,7 +73,7 @@ /obj/item/weapon/gun/projectile/automatic/proc/empty_alarm() if(!chambered && !get_ammo() && !alarmed) - playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) + playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) update_icon() alarmed = 1 return diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 66e404a7de8..1a9da6fcf22 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -45,7 +45,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) if(CB) - CB.loc = get_turf(src.loc) + CB.loc = get_turf(loc) CB.SpinAnimation(10, 1) CB.update_icon() num_unloaded++ @@ -124,7 +124,7 @@ afterattack(user, user) //you know the drill user.visible_message("[src] goes off!", "[src] goes off in your face!") return - if(do_after(user, 30/A.toolspeed, target = src)) + if(do_after(user, 30, target = src)) if(magazine.ammo_count()) to_chat(user, "You can't modify it!") return @@ -173,7 +173,7 @@ name = "\improper Russian Revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull." origin_tech = "combat=2;materials=2" - mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357 + mag_type = /obj/item/ammo_box/magazine/internal/rus357 var/spun = 0 @@ -211,7 +211,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round() chambered = null - CB.loc = get_turf(src.loc) + CB.loc = get_turf(loc) CB.update_icon() num_unloaded++ if (num_unloaded) @@ -234,7 +234,6 @@ return if(ishuman(user)) - var/mob/living/carbon/human/H = user if(!spun) to_chat(user, "You need to spin the revolver's chamber first!") return @@ -245,12 +244,11 @@ var/obj/item/ammo_casing/AC = chambered if(AC.fire(user, user)) playsound(user, fire_sound, 50, 1) - var/zone = check_zone(user.zone_selected) - var/obj/item/bodypart/affecting = H.get_bodypart(zone) + var/zone = check_zone(user.zone_sel.selecting) if(zone == "head" || zone == "eyes" || zone == "mouth") - shoot_self(user, affecting) + shoot_self(user, zone) else - user.visible_message("[user.name] cowardly fires [src] at \his [affecting.name]!", "You cowardly fire [src] at your [affecting.name]!", "You hear a gunshot!") + user.visible_message("[user.name] cowardly fires [src] at \his [zone]!", "You cowardly fire [src] at your [zone]!", "You hear a gunshot!") return user.visible_message("*click*") diff --git a/code/modules/projectiles/guns/projectile/rocket.dm b/code/modules/projectiles/guns/projectile/rocket.dm index a82caddeba1..b2d01b303ed 100644 --- a/code/modules/projectiles/guns/projectile/rocket.dm +++ b/code/modules/projectiles/guns/projectile/rocket.dm @@ -45,8 +45,8 @@ playsound(user.loc, 'sound/effects/bang.ogg', 50, 1) M.primed = 1 M.throw_at(target, missile_range, missile_speed,user) - message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]).") - log_game("[key_name_admin(user)] used a rocket launcher ([src.name]).") + message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([name]).") + log_game("[key_name_admin(user)] used a rocket launcher ([name]).") rockets -= I qdel(I) return diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm index 5c4856d2503..4cb8a59b305 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -39,7 +39,7 @@ else if(cover_open && magazine) //drop the mag magazine.update_icon() - magazine.loc = get_turf(src.loc) + magazine.loc = get_turf(loc) user.put_in_hands(magazine) magazine = null update_icon() @@ -69,7 +69,7 @@ . = ..() if((blocked != 100) && istype(target, /mob/living/carbon/human)) var/mob/living/carbon/human/H = target - H.drip(35) + H.drip(350) /obj/item/projectile/bullet/saw/hollow damage = 60 diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 1119a795505..47ffa8de488 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -22,7 +22,7 @@ update_icon() -/obj/item/weapon/gun/projectile/shotgun/process_chambered() +/obj/item/weapon/gun/projectile/shotgun/process_chamber() return ..(0, 0) /obj/item/weapon/gun/projectile/shotgun/chamber_round() @@ -79,7 +79,7 @@ name = "riot shotgun" desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control." icon_state = "riotshotgun" - mag_type = /obj/item/ammo_box/magazine/internal/shotriot + mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." /obj/item/weapon/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params) @@ -143,7 +143,7 @@ ..() if(guns_left) var/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/GUN = new - GUN.guns_left = src.guns_left - 1 + GUN.guns_left = guns_left - 1 user.drop_item() user.swap_hand() user.put_in_hands(GUN) @@ -172,7 +172,7 @@ flags = CONDUCT slot_flags = SLOT_BACK origin_tech = "combat=3;materials=1" - mag_type = /obj/item/ammo_box/magazine/internal/cylinder/dual + mag_type = /obj/item/ammo_box/magazine/internal/shot/dual sawn_desc = "Omar's coming!" unique_rename = 1 unique_reskin = 1 @@ -204,7 +204,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) chambered = null - CB.loc = get_turf(src.loc) + CB.loc = get_turf(loc) CB.update_icon() num_unloaded++ if (num_unloaded) @@ -286,7 +286,7 @@ if(do_after(user, 30, target = src)) user.visible_message("[user] shortens \the [src]!", "You shorten \the [src]!") - name = "sawn-off [src.name]" + name = "sawn-off [name]" desc = sawn_desc icon_state = "[icon_state]-sawn" w_class = 3 @@ -303,7 +303,7 @@ /obj/item/weapon/gun/projectile/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj) ..() - src.pump(user) + pump(user) /obj/item/weapon/gun/projectile/shotgun/automatic/combat name = "combat shotgun" @@ -375,7 +375,7 @@ sawn_desc = "I'm sorry, but why did you saw your cane in the first place?" attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") fire_sound = 'sound/weapons/Gunshot_silenced.ogg' - silenced = 1 + suppressed = 1 needs_permit = 0 //its just a cane beepsky..... /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params) @@ -385,7 +385,7 @@ /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/examine(mob/user) // HAD TO REPEAT EXAMINE CODE BECAUSE GUN CODE DOESNT STEALTH var/f_name = "\a [src]." - if(src.blood_DNA && !istype(src, /obj/effect/decal)) + if(blood_DNA && !istype(src, /obj/effect/decal)) if(gender == PLURAL) f_name = "some " else diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 5033d0f8a0e..59bd7fb649b 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -4,7 +4,7 @@ icon_state = "sniper" item_state = "sniper" recoil = 2 - heavy_weapon = 1 + weapon_weight = WEAPON_MEDIUM mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 40 origin_tech = "combat=8" @@ -117,7 +117,7 @@ /obj/item/projectile/bullet/sniper/haemorrhage/on_hit(atom/target, blocked = 0, hit_zone) if((blocked != 100) && istype(target, /mob/living/carbon/human)) var/mob/living/carbon/human/H = target - H.drip(100) + H.drip(1000) return ..() diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 45a590bd420..332d279376b 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -28,7 +28,7 @@ chambered.BB = new S.projectile_type (src) - S.reagents.trans_to(in_chamber, S.reagents.total_volume) + S.reagents.trans_to(chambered.BB, S.reagents.total_volume) chambered.BB.name = S.name syringes.Remove(S) @@ -55,8 +55,9 @@ var/obj/item/weapon/reagent_containers/syringe/S = syringes[syringes.len] - if(!S) return 0 - S.forceMove(user.loc) + if(!S) + return 0 + S.loc = user.loc syringes.Remove(S) to_chat(user, "You unload [S] from \the [src]!") @@ -70,7 +71,7 @@ return to_chat(user, "You load [A] into \the [src]!") syringes.Add(A) - A.forceMove(src) + A.loc = src return 1 else to_chat(user, "[src] cannot hold more syringes.") @@ -90,5 +91,5 @@ w_class = 2 origin_tech = "combat=2;syndicate=2" force = 2 //Also very weak because it's smaller - silenced = 1 //Softer fire sound + suppressed = 1 //Softer fire sound can_unsuppress = 0 //Permanently silenced diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0cba3aa5fbf..9816fa7a804 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -79,7 +79,7 @@ playsound(loc, hitsound, volume, 1, -1) L.visible_message("[L] is hit by \a [src][organ_hit_text]!", \ "[L] is hit by \a [src][organ_hit_text]!") //X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter - L.on_hit(type) + L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) var/reagent_note if(reagents && reagents.reagent_list) @@ -91,8 +91,8 @@ return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) /obj/item/projectile/proc/vol_by_damage() - if(src.damage) - return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 + if(damage) + return Clamp((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 else return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume @@ -113,10 +113,10 @@ if(isnull(organ)) return else if(isturf(A) && hitsound_wall) - var/volume = Clamp(vol_by_damage() + 20, 0, 100) - if(suppressed) - volume = 5 - playsound(loc, hitsound_wall, volume, 1, -1) + var/volume = Clamp(vol_by_damage() + 20, 0, 100) + if(suppressed) + volume = 5 + playsound(loc, hitsound_wall, volume, 1, -1) var/turf/target_turf = get_turf(A) @@ -220,5 +220,5 @@ obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a pro return ..() /obj/item/projectile/proc/dumbfire(var/dir) - current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. - fire() + current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. + fire() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index b11c4f66961..8c946455a65 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -87,11 +87,11 @@ name = "laser tag beam" icon_state = "omnilaser" -/obj/item/projectile/beam/lasertag/red +/obj/item/projectile/beam/lasertag/redtag icon_state = "laser" suit_types = list(/obj/item/clothing/suit/bluetag) -/obj/item/projectile/beam/lasertag/blue +/obj/item/projectile/beam/lasertag/bluetag icon_state = "bluelaser" suit_types = list(/obj/item/clothing/suit/redtag) @@ -131,156 +131,3 @@ var/mob/living/carbon/M = target M.visible_message("[M] explodes into a shower of gibs!") M.gib() - -/* //THIS CODE MAKES ME WANT TO STAB MY EYES OUT -/obj/item/projectile/beam/lightning - invisibility = 101 - name = "lightning" - damage = 0 - icon = 'icons/obj/lightning.dmi' - icon_state = "lightning" - stun = 10 - weaken = 10 - stutter = 50 - eyeblur = 50 - var/tang = 0 - layer = 3 - var/turf/last = null - kill_count = 6 - var/bullet_acted = 0 - -/obj/item/projectile/beam/lightning/Bump(var/atom/A) - if((A != firer) && !bullet_acted) - A.bullet_act(src) - bullet_acted = 1 - -/obj/item/projectile/beam/lightning/proc/adjustAngle(angle) - angle = round(angle) + 45 - if(angle > 180) - angle -= 180 - else - angle += 180 - if(!angle) - angle = 1 - return angle - -/obj/item/projectile/beam/lightning/process() - var/first = 1 //So we don't make the overlay in the same tile as the firer - var/broke = 0 - var/broken - var/atom/curr = current - var/Angle=round(Get_Angle(firer,curr)) - var/icon/I=new('icons/obj/zap.dmi',"lightning") - I.Turn(Angle) - var/DX=(32*curr.x+curr.pixel_x)-(32*firer.x+firer.pixel_x) - var/DY=(32*curr.y+curr.pixel_y)-(32*firer.y+firer.pixel_y) - var/N=0 - var/length=round(sqrt((DX)**2+(DY)**2)) - var/count = 0 - for(N,N= kill_count) - break - count++ - var/obj/effect/overlay/beam/X=new(loc) - X.BeamSource=src - if(N+32>length) - var/icon/II=new(icon,icon_state) - II.DrawBox(null,1,(length-N),32,32) - II.Turn(Angle) - X.icon=II - else X.icon=I - var/Pixel_x=round(sin(Angle)+32*sin(Angle)*(N+16)/32) - var/Pixel_y=round(cos(Angle)+32*cos(Angle)*(N+16)/32) - if(DX==0) Pixel_x=0 - if(DY==0) Pixel_y=0 - if(Pixel_x>32) - for(var/a=0, a<=Pixel_x,a+=32) - X.x++ - Pixel_x-=32 - if(Pixel_x<-32) - for(var/a=0, a>=Pixel_x,a-=32) - X.x-- - Pixel_x+=32 - if(Pixel_y>32) - for(var/a=0, a<=Pixel_y,a+=32) - X.y++ - Pixel_y-=32 - if(Pixel_y<-32) - for(var/a=0, a>=Pixel_y,a-=32) - X.y-- - Pixel_y+=32 - X.pixel_x=Pixel_x - X.pixel_y=Pixel_y - var/turf/TT = get_turf(X.loc) - if(TT == firer.loc) - continue - if(TT.density) - qdel(X) - break - for(var/atom/O in TT) - if(istype(O,/mob/living)) - if(O.density) - qdel(X) - broke = 1 - break - if(!O.CanPass(src)) - qdel(X) - broke = 1 - break - if(broke) - if(X) - qdel(X) - break - spawn - while(src) //Move until we hit something - if(first) - icon = midicon - if((!( current ) || loc == current)) //If we pass our target - broken = 1 - icon = endicon - tang = adjustAngle(get_angle(original,current)) - if(tang > 180) - tang -= 180 - else - tang += 180 - icon_state = "[tang]" - var/turf/simulated/floor/f = current - if(f && istype(f)) - if(!bullet_acted) - f.break_tile() - f.hotspot_expose(1000,CELL_VOLUME) - if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) - broken = 1 - return - if(kill_count < 1) - broken = 1 - kill_count-- - if(!bumped && !isturf(original)) - if(loc == get_turf(original)) - if(!(original in permutated)) - icon = endicon - if(!broken) - tang = adjustAngle(get_angle(original,current)) - if(tang > 180) - tang -= 180 - else - tang += 180 - icon_state = "[tang]" - Bump(original) - first = 0 - if(broken) - break - else - last = get_turf(src.loc) - step_towards(src, current) //Move~ - if(src.loc != current) - tang = adjustAngle(get_angle(src.loc,current)) - icon_state = "[tang]" - qdel(src) - return -/obj/item/projectile/beam/lightning/on_hit(atom/target, blocked = 0) - if(istype(target, /mob/living)) - var/mob/living/M = target - M.playsound_local(src, "explosion", 50, 1) - ..() -*/ diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index f3a676d962f..38c9a9efd55 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -80,7 +80,7 @@ range = rand(8) /obj/item/projectile/bullet/pellet/weak/on_range() - var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread sparks.set_up(1, 1, src) sparks.start() ..() @@ -97,7 +97,7 @@ /obj/item/projectile/bullet/pellet/overload/on_range() explosion(src, 0, 0, 2) - var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread sparks.set_up(3, 3, src) sparks.start() ..() @@ -179,7 +179,7 @@ forcedodge = 1 nodamage = 1 hitsound = 'sound/items/bikehorn.ogg' - icon = 'icons/obj/hydroponics/harvest.dmi' + icon = 'icons/obj/harvest.dmi' icon_state = "banana" range = 200 diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index b023d77de52..79ffc1d0898 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -21,7 +21,7 @@ /obj/item/projectile/energy/electrode/on_hit(var/atom/target, var/blocked = 0) . = ..() if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks! - var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread sparks.set_up(1, 1, src) sparks.start() else if(iscarbon(target)) @@ -33,7 +33,7 @@ C.do_jitter_animation(jitter) /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 - var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread sparks.set_up(1, 1, src) sparks.start() ..() @@ -80,7 +80,7 @@ /obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") ..() - var/obj/item/projectile/hook/P = BB + var/obj/item/projectile/energy/shock_revolver/P = BB spawn(1) P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 74eff57d98d..1d1f6dc93a8 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -48,7 +48,7 @@ /obj/item/projectile/magic/resurrection/on_hit(var/mob/living/carbon/target) . = ..() if(ismob(target)) - var/old_stat = stat + var/old_stat = target.stat target.suiciding = 0 target.revive() if(!target.ckey) @@ -94,16 +94,22 @@ if(isturf(target) && target.density) CreateDoor(target) else if (isturf(T) && T.density) - CreateDoor(T + CreateDoor(T) else if(istype(target, /obj/machinery/door)) - OpenDoor(target)) + OpenDoor(target) /obj/item/projectile/magic/door/proc/CreateDoor(turf/T) var/door_type = pick(door_types) var/obj/structure/mineral_door/D = new door_type(T) - T.ChangeTurf(/turf/open/floor/plating) + T.ChangeTurf(/turf/simulated/floor/plasteel) D.Open() +/obj/item/projectile/magic/door/proc/OpenDoor(var/obj/machinery/door/D) + if(istype(D,/obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/A = D + A.locked = 0 + D.open() + /obj/item/projectile/magic/change name = "bolt of change" icon_state = "ice_1" diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 9f4e36bc1b4..466a8ba8e99 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -1,7 +1,7 @@ /obj/item/projectile/bullet/reusable name = "reusable bullet" desc = "How do you even reuse a bullet?" - ammo_type = /obj/item/ammo_casing/caseless/ + var/ammo_type = /obj/item/ammo_casing/caseless/ var/dropped = 0 /obj/item/projectile/bullet/reusable/on_hit(atom/target, blocked = 0) @@ -14,7 +14,7 @@ /obj/item/projectile/bullet/reusable/proc/handle_drop() if(!dropped) - new ammo_type(src.loc) + new ammo_type(loc) dropped = 1 /obj/item/projectile/bullet/reusable/magspear @@ -42,7 +42,7 @@ if(dropped) return dropped = 1 - var/obj/item/ammo_casing/caseless/foam_dart/newdart = new ammo_type(src.loc) + var/obj/item/ammo_casing/caseless/foam_dart/newdart = new ammo_type(loc) var/obj/item/ammo_casing/caseless/foam_dart/old_dart = ammo_casing newdart.modified = old_dart.modified if(pen) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 851f23bcdd7..56b4875002b 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -115,7 +115,7 @@ if(A == firer) loc = A.loc return - playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) + playsound(loc, 'sound/effects/meteorimpact.ogg', 40, 1) for(var/mob/M in urange(10, src)) if(!M.stat) shake_camera(M, 3, 1) @@ -195,8 +195,8 @@ var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("The [src.name] explodes!","You hear a snap!") + new /obj/effect/decal/cleanable/ash(loc) + visible_message("The [name] explodes!","You hear a snap!") playsound(src, 'sound/effects/snap.ogg', 50, 1) qdel(src) @@ -230,7 +230,7 @@ obj/item/projectile/kinetic/New() ..() /obj/item/projectile/kinetic/on_range() - new /obj/effect/kinetic_blast(src.loc) + new /obj/effect/kinetic_blast(loc) ..() /obj/item/projectile/kinetic/on_hit(atom/target) @@ -240,13 +240,13 @@ obj/item/projectile/kinetic/New() var/turf/simulated/mineral/M = target_turf M.gets_drilled(firer) new /obj/item/effect/kinetic_blast(target_turf) - if(src.splash) + if(splash) for(var/turf/T in range(splash, target_turf)) if(istype(T, /turf/simulated/mineral)) var/turf/simulated/mineral/M = T M.gets_drilled(firer) -/obj/item/effect/kinetic_blast +/obj/effect/kinetic_blast name = "kinetic explosion" icon = 'icons/obj/projectiles.dmi' icon_state = "kinetic_blast" @@ -340,13 +340,8 @@ obj/item/projectile/kinetic/New() icon_state = "bluespace" damage = 0 nodamage = 1 - var/obj/item/weapon/gun/energy/telegun/T = null var/teleport_target = null - OnFired() - T = shot_from - teleport_target = T.teleport_target - /obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0) if(isliving(target)) if(teleport_target) diff --git a/code/modules/reagents/dartgun.dm b/code/modules/reagents/dartgun.dm index 4fb705dbcf9..f08685b3d88 100644 --- a/code/modules/reagents/dartgun.dm +++ b/code/modules/reagents/dartgun.dm @@ -104,7 +104,7 @@ to_chat(user, "