[READY] I got guns (#41804)

cl actioninja\memager
refactor: Ballistic guns have been almost entirely reworked from a backend side. This primarily focused on moving as much as possible into the base ballistic gun and turning as many other guns into essentially varedits as possible.
add: Guns can now be racked. This is the default action unless the magazine is empty.
add: Guns now can have the magazine removed by clicking on them with an open hand while they are in hand.
tweak: Suppressors are now removed by alt clicking instead of clicking with an open hand
add: Guns now have various bolt types that all function a bit differently. Open bolts cannot have a bullet chambered with no mag, locking bolts lock back after running out of ammo, etc.
add: All ballistic gun sounds are controlled by variables instead of hardcoded usages.
tweak: The l6 LMG has a reworked control scheme. alt + click to open and close the cover, open hand to remove mag, place mag in by slapping them together, default action is rack.
tweak: Functionality that used to be snowflake code such as tactical reloads has been moved to the base gun, and can be toggled by variables.
refactor: All shotguns are now properly subpaths of the shotgun type. They still work the same.
imagedel: Gun sprites have been almost entirely overhauled to use overlays instead of states. This collapsed the L6 sprite from 20 sprites to 9 sprites to give an example.
soundadd: Remixed versions of the shotgun and base gun firesound
soundadd: New rifle firesound for l6 and moist nugget, new SMG fire sound, new sniper fire sound.
soundadd: Lots of new weapon operation sounds such as racking and bolts and the like.
imageadd: New sprites for the Riot Shotgun, Combat Shotgun, c20r, Deagle, m90, double barrel shotgun and 1911 by Memager.
imageadd: All gun sprites that were pointing to the left have been flipped to point to the right.
balance: Shotguns now can be pumped faster.
balance: Bulldog can now be tac reloaded
balance: Sawn off shotguns now have an accuracy penalty and recoil
/cl
This commit is contained in:
Rob Bailey
2019-02-04 10:27:01 +13:00
committed by oranges
parent cc8bcdcb06
commit 69e217d8d9
51 changed files with 598 additions and 552 deletions
@@ -18,8 +18,8 @@
var/max_ammo = 7
var/multiple_sprites = 0
var/caliber
var/multiload = 1
var/start_empty = 0
var/multiload = TRUE
var/start_empty = FALSE
var/list/bullet_cost
var/list/base_cost// override this one as well if you override bullet_cost
@@ -38,7 +38,7 @@
stored_ammo += new ammo_type(src)
update_icon()
/obj/item/ammo_box/proc/get_round(keep = 0)
/obj/item/ammo_box/proc/get_round(keep = FALSE)
if (!stored_ammo.len)
return null
else
@@ -51,12 +51,12 @@
/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
return FALSE
if (stored_ammo.len < max_ammo)
stored_ammo += R
R.forceMove(src)
return 1
return TRUE
//for accessibles magazines (e.g internal ones) when full, start replacing spent ammo
else if(replace_spent)
@@ -67,12 +67,11 @@
stored_ammo += R
R.forceMove(src)
return 1
return 0
return TRUE
return FALSE
/obj/item/ammo_box/proc/can_load(mob/user)
return 1
return TRUE
/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = FALSE, replace_spent = 0)
var/num_loaded = 0
@@ -96,7 +95,7 @@
if(num_loaded)
if(!silent)
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src]!</span>")
playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1)
playsound(src, 'sound/weapons/bulletinsert.ogg', 60, TRUE)
A.update_icon()
update_icon()
+233 -58
View File
@@ -3,16 +3,61 @@
name = "projectile gun"
icon_state = "pistol"
w_class = WEIGHT_CLASS_NORMAL
//sound info vars
var/load_sound = "gun_insert_full_magazine"
var/load_empty_sound = "gun_insert_empty_magazine"
var/load_sound_volume = 40
var/load_sound_vary = TRUE
var/rack_sound = "gun_slide_lock"
var/rack_sound_volume = 60
var/rack_sound_vary = TRUE
var/lock_back_sound = "sound/weapons/pistollock.ogg"
var/lock_back_sound_volume = 60
var/lock_back_sound_vary = TRUE
var/eject_sound = "gun_remove_empty_magazine"
var/eject_empty_sound = "gun_remove_full_magazine"
var/eject_sound_volume = 40
var/eject_sound_vary = TRUE
var/bolt_drop_sound = 'sound/weapons/gun_chamber_round.ogg'
var/bolt_drop_sound_volume = 60
var/empty_alarm_sound = 'sound/weapons/smg_empty_alarm.ogg'
var/empty_alarm_volume = 70
var/empty_alarm_vary = TRUE
var/spawnwithmagazine = TRUE
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
var/mag_display = FALSE //Whether the sprite has a visible magazine or not
var/mag_display_ammo = FALSE //Whether the sprite has a visible ammo display or not
var/empty_indicator = FALSE //Whether the sprite has an indicator for being empty or not.
var/empty_alarm = FALSE //Whether the gun alarms when empty or not.
var/special_mags = FALSE //Whether the gun supports multiple special mag types
var/alarmed = FALSE
//Four bolt types:
//BOLT_TYPE_STANDARD: Gun has a bolt, it stays closed while not cycling. The gun must be racked to have a bullet chambered when a mag is inserted.
//Example: c20, shotguns, m90
//BOLT_TYPE_OPEN: Gun has a bolt, it is open when ready to fire. Largely the same as standard, except the gun can never have a chambered bullet with no magazine.
//Example: Some SMGs, the L6
//BOLT_TYPE_NO_BOLT: Gun has no moving bolt mechanism, it cannot be racked. Also dumps the entire contents when emptied instead of a magazine.
//Example: Break action shotguns, revolvers
//BOLT_TYPE_LOCKING: Gun has a bolt, it locks back when empty. It can be released to chamber a round if a magazine is in.
//Example: Pistols with a slide lock, some SMGs
var/bolt_type = BOLT_TYPE_STANDARD
var/bolt_locked = FALSE
var/bolt_wording = "bolt" //bolt, slide, etc.
var/semi_auto = TRUE //Whether the gun has to be racked each shot or not.
var/obj/item/ammo_box/magazine/magazine
var/casing_ejector = TRUE //whether the gun ejects the chambered casing
var/internal_magazine = FALSE //Whether the gun has an internal magazine or a detatchable one. Overridden by BOLT_TYPE_NO_BOLT.
var/magazine_wording = "magazine"
var/cartridge_wording = "bullet"
var/rack_delay = 5
var/recent_rack = 0
var/tac_reloads = FALSE //Snowflake mechanic no more.
/obj/item/gun/ballistic/Initialize()
. = ..()
if(!spawnwithmagazine)
update_icon()
if (!spawnwithmagazine)
return
if (!magazine)
magazine = new mag_type(src)
@@ -20,60 +65,150 @@
update_icon()
/obj/item/gun/ballistic/update_icon()
if (QDELETED(src))
return
..()
if(current_skin)
icon_state = "[unique_reskin[current_skin]][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]"
icon_state = "[unique_reskin[current_skin]][sawn_off ? "_sawn" : ""]"
else
icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]"
icon_state = "[initial(icon_state)][sawn_off ? "_sawn" : ""]"
cut_overlays()
if (bolt_type == BOLT_TYPE_LOCKING)
add_overlay("[icon_state]_bolt[bolt_locked ? "_locked" : ""]")
if (suppressed)
add_overlay("[icon_state]_suppressor")
if(!chambered && empty_indicator)
add_overlay("[icon_state]_empty")
if (magazine)
if (special_mags)
add_overlay("[icon_state]_mag_[magazine.icon_state]")
if (!magazine.ammo_count())
add_overlay("[icon_state]_mag_empty")
else
add_overlay("[icon_state]_mag")
var/capacity_number = 0
switch(get_ammo() / magazine.max_ammo)
if(0.2 to 0.39)
capacity_number = 20
if(0.4 to 0.59)
capacity_number = 40
if(0.6 to 0.79)
capacity_number = 60
if(0.8 to 0.99)
capacity_number = 80
if(1.0)
capacity_number = 100
if (capacity_number)
add_overlay("[icon_state]_mag_[capacity_number]")
/obj/item/gun/ballistic/process_chamber(empty_chamber = 1)
/obj/item/gun/ballistic/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE)
if(!semi_auto && from_firing)
return
var/obj/item/ammo_casing/AC = chambered //Find chambered round
if(istype(AC)) //there's a chambered round
if(casing_ejector)
if(casing_ejector || !from_firing)
AC.forceMove(drop_location()) //Eject casing onto ground.
AC.bounce_away(TRUE)
chambered = null
else if(empty_chamber)
chambered = null
chamber_round()
if (chamber_next_round)
chamber_round()
/obj/item/gun/ballistic/proc/chamber_round()
if (chambered || !magazine)
return
else if (magazine.ammo_count())
chambered = magazine.get_round()
chambered.forceMove(src)
if (magazine.ammo_count())
chambered = magazine.get_round((bolt_type == BOLT_TYPE_NO_BOLT))
if (bolt_type != BOLT_TYPE_OPEN)
chambered.forceMove(src)
/obj/item/gun/ballistic/proc/rack(mob/user = null)
if (bolt_type == BOLT_TYPE_NO_BOLT) //If there's no bolt, nothing to rack
return
if (bolt_type == BOLT_TYPE_OPEN && chambered != null) //If it's an open bolt, there's no way to rack it once it's open
if (user)
to_chat("<span class='notice'>It's already chambered!</span>")
return
if (user)
to_chat(user, "<span class='notice'>You rack the [bolt_wording] of \the [src].</span>")
process_chamber(!chambered, FALSE)
if (bolt_type == BOLT_TYPE_LOCKING && !chambered)
bolt_locked = TRUE
playsound(src, lock_back_sound, lock_back_sound_volume, lock_back_sound_vary)
else
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
update_icon()
/obj/item/gun/ballistic/proc/drop_bolt(mob/user = null)
playsound(src, bolt_drop_sound, bolt_drop_sound_volume, FALSE)
if (user)
to_chat(user, "<span class='notice'>You drop the [bolt_wording] of \the [src].</span>")
chamber_round()
bolt_locked = FALSE
update_icon()
/obj/item/gun/ballistic/proc/insert_magazine(mob/user, obj/item/ammo_box/magazine/AM, display_message = TRUE)
if(user.transferItemToLoc(AM, src))
magazine = AM
if (display_message)
to_chat(user, "<span class='notice'>You load a new [magazine_wording] into \the [src].</span>")
playsound(src, load_empty_sound, load_sound_volume, load_sound_vary)
update_icon()
return TRUE
else
to_chat(user, "<span class='warning'>You cannot seem to get \the [src] out of your hands!</span>")
return FALSE
/obj/item/gun/ballistic/proc/eject_magazine(mob/user, display_message = TRUE, obj/item/ammo_box/magazine/tac_load = null)
if(bolt_type == BOLT_TYPE_OPEN)
chambered = null
if (magazine.ammo_count())
playsound(src, load_sound, load_sound_volume, load_sound_vary)
else
playsound(src, load_empty_sound, load_sound_volume, load_sound_vary)
magazine.forceMove(drop_location())
var/obj/item/ammo_box/magazine/old_mag = magazine
if (tac_load)
insert_magazine(user, tac_load, FALSE)
to_chat(user, "<span class='notice'>You perform a tactical reload on \the [src].")
user.put_in_hands(old_mag)
magazine.update_icon()
if (!tac_load)
magazine = null
if (display_message)
to_chat(user, "<span class='notice'>You pull the [magazine_wording] out of \the [src].</span>")
update_icon()
/obj/item/gun/ballistic/can_shoot()
if(!magazine || !magazine.ammo_count(FALSE))
return 0
return 1
return (chambered || magazine || magazine.ammo_count(FALSE))
/obj/item/gun/ballistic/attackby(obj/item/A, mob/user, params)
..()
if (istype(A, /obj/item/ammo_box/magazine))
if (.)
return
if (!internal_magazine && istype(A, /obj/item/ammo_box/magazine))
var/obj/item/ammo_box/magazine/AM = A
if (!magazine && istype(AM, mag_type))
if(user.transferItemToLoc(AM, src))
magazine = AM
to_chat(user, "<span class='notice'>You load a new [magazine_wording] into \the [src].</span>")
if(magazine.ammo_count())
playsound(src, "gun_insert_full_magazine", 70, 1)
if(!chambered)
chamber_round()
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/gun_chamber_round.ogg', 100, 1), 3)
else
playsound(src, "gun_insert_empty_magazine", 70, 1)
insert_magazine(user, AM)
else if (magazine)
if(tac_reloads)
eject_magazine(user, FALSE, AM)
else
to_chat(user, "<span class='notice'>There's already a [magazine_wording] in \the [src].</span>")
return
if (istype(A, /obj/item/ammo_casing) || istype(A, /obj/item/ammo_box))
if (bolt_type == BOLT_TYPE_NO_BOLT || internal_magazine)
var/num_loaded = magazine.attackby(A, user, params, TRUE)
if (num_loaded)
to_chat(user, "<span class='notice'>You load [num_loaded] [cartridge_wording]\s into \the [src].</span>")
playsound(src, load_sound, load_sound_volume, load_sound_vary)
if (chambered == null && bolt_type == BOLT_TYPE_NO_BOLT)
chamber_round()
A.update_icon()
update_icon()
return 1
else
to_chat(user, "<span class='warning'>You cannot seem to get \the [src] out of your hands!</span>")
return
else if (magazine)
to_chat(user, "<span class='notice'>There's already a [magazine_wording] in \the [src].</span>")
return
if(istype(A, /obj/item/suppressor))
var/obj/item/suppressor/S = A
if(!can_suppress)
@@ -86,10 +221,15 @@
to_chat(user, "<span class='warning'>[src] already has a suppressor!</span>")
return
if(user.transferItemToLoc(A, src))
to_chat(user, "<span class='notice'>You screw [S] onto [src].</span>")
to_chat(user, "<span class='notice'>You screw \the [S] onto \the [src].</span>")
install_suppressor(A)
return
return 0
return FALSE
/obj/item/gun/ballistic/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if (sawn_off)
bonus_spread += SAWN_OFF_ACC_PENALTY
. = ..()
/obj/item/gun/ballistic/proc/install_suppressor(obj/item/suppressor/S)
// this proc assumes that the suppressor is already inside src
@@ -97,48 +237,82 @@
w_class += S.w_class //so pistols do not fit in pockets when suppressed
update_icon()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/gun/ballistic/attack_hand(mob/user)
/obj/item/gun/ballistic/AltClick(mob/user)
if (unique_reskin && !current_skin && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
reskin_obj(user)
return
if(loc == user)
if(suppressed && can_unsuppress)
var/obj/item/suppressor/S = suppressed
if(!user.is_holding(src))
return ..()
to_chat(user, "<span class='notice'>You unscrew [suppressed] from [src].</span>")
to_chat(user, "<span class='notice'>You unscrew \the [suppressed] from \the [src].</span>")
user.put_in_hands(suppressed)
w_class -= S.w_class
suppressed = null
update_icon()
return
/obj/item/gun/ballistic/proc/empty_checks()
if (!chambered && !get_ammo())
if (!alarmed && empty_alarm)
playsound(src.loc, empty_alarm_sound, empty_alarm_volume, empty_alarm_vary)
alarmed = TRUE
update_icon()
if (bolt_type == BOLT_TYPE_LOCKING)
bolt_locked = TRUE
update_icon()
/obj/item/gun/ballistic/afterattack()
empty_checks()
. = ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/gun/ballistic/attack_hand(mob/user)
if(!internal_magazine && loc == user && user.is_holding(src) && magazine)
eject_magazine(user)
return
return ..()
/obj/item/gun/ballistic/attack_self(mob/living/user)
var/obj/item/ammo_casing/AC = chambered //Find chambered round
if(magazine)
magazine.forceMove(drop_location())
user.put_in_hands(magazine)
magazine.update_icon()
if(magazine.ammo_count())
playsound(src, 'sound/weapons/gun_magazine_remove_full.ogg', 70, 1)
if(!internal_magazine && magazine)
if(!magazine.ammo_count())
eject_magazine(user)
return
if(bolt_type == BOLT_TYPE_NO_BOLT)
var/num_unloaded = 0
while (get_ammo() > 0)
var/obj/item/ammo_casing/CB
CB = magazine.get_round(FALSE)
chambered = null
CB.forceMove(drop_location())
CB.bounce_away(FALSE, NONE)
num_unloaded++
if (num_unloaded)
to_chat(user, "<span class='notice'>You unload [num_unloaded] [cartridge_wording]\s from [src].</span>")
playsound(user, eject_sound, eject_sound_volume, eject_sound_vary)
else
playsound(src, "gun_remove_empty_magazine", 70, 1)
magazine = null
to_chat(user, "<span class='notice'>You pull the magazine out of \the [src].</span>")
else if(chambered)
AC.forceMove(drop_location())
AC.bounce_away()
chambered = null
to_chat(user, "<span class='notice'>You unload the round from \the [src]'s chamber.</span>")
playsound(src, "gun_slide_lock", 70, 1)
else
to_chat(user, "<span class='notice'>There's no magazine in \the [src].</span>")
update_icon()
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(bolt_type == BOLT_TYPE_LOCKING && bolt_locked)
drop_bolt(user)
return
if (recent_rack > world.time)
return
recent_rack = world.time + rack_delay
rack(user)
return
/obj/item/gun/ballistic/examine(mob/user)
..()
to_chat(user, "It has [get_ammo()] round\s remaining.")
if (!chambered)
to_chat(user, "It does not seem to have a round chambered.")
if (bolt_locked)
to_chat(user, "The [bolt_wording] is locked back and needs to be released before firing.")
if (suppressed)
to_chat(user, "It has a suppressor attached that can be removed with <b>alt+click</b>.")
/obj/item/gun/ballistic/proc/get_ammo(countchambered = TRUE)
var/boolets = 0 //mature var names for mature people
@@ -199,17 +373,18 @@
item_state = "gun"
slot_flags &= ~ITEM_SLOT_BACK //you can't sling it on your back
slot_flags |= ITEM_SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
recoil = SAWN_OFF_RECOIL
sawn_off = TRUE
update_icon()
return 1
return TRUE
// Sawing guns related proc
/obj/item/gun/ballistic/proc/blow_up(mob/user)
. = 0
. = FALSE
for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
if(AC.BB)
process_fire(user, user, FALSE)
. = 1
. = TRUE
/obj/item/suppressor
@@ -1,11 +1,15 @@
/obj/item/gun/ballistic/automatic
w_class = WEIGHT_CLASS_NORMAL
var/alarmed = 0
var/select = 1
can_suppress = TRUE
burst_size = 3
fire_delay = 2
actions_types = list(/datum/action/item_action/toggle_firemode)
semi_auto = TRUE
fire_sound = "sound/weapons/smgshot.ogg"
fire_sound_volume = 80
vary_fire_sound = FALSE
rack_sound = "sound/weapons/smgrack.ogg"
/obj/item/gun/ballistic/automatic/proto
name = "\improper Nanotrasen Saber SMG"
@@ -13,6 +17,9 @@
icon_state = "saber"
mag_type = /obj/item/ammo_box/magazine/smgm9mm
pin = null
bolt_type = BOLT_TYPE_LOCKING
mag_display = TRUE
tac_reloads = TRUE
/obj/item/gun/ballistic/automatic/proto/unrestricted
pin = /obj/item/firing_pin
@@ -20,36 +27,9 @@
/obj/item/gun/ballistic/automatic/update_icon()
..()
if(!select)
add_overlay("[initial(icon_state)]semi")
add_overlay("[initial(icon_state)]_semi")
if(select == 1)
add_overlay("[initial(icon_state)]burst")
icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
/obj/item/gun/ballistic/automatic/attackby(obj/item/A, mob/user, params)
. = ..()
if(.)
return
if(istype(A, /obj/item/ammo_box/magazine))
var/obj/item/ammo_box/magazine/AM = A
if(istype(AM, mag_type))
var/obj/item/ammo_box/magazine/oldmag = magazine
if(user.transferItemToLoc(AM, src))
magazine = AM
if(oldmag)
to_chat(user, "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>")
oldmag.dropped()
oldmag.forceMove(get_turf(src.loc))
oldmag.update_icon()
else
to_chat(user, "<span class='notice'>You insert the magazine into \the [src].</span>")
playsound(src, 'sound/weapons/autoguninsert.ogg', 60, TRUE)
chamber_round()
A.update_icon()
update_icon()
return 1
else
to_chat(user, "<span class='warning'>You cannot seem to get \the [src] out of your hands!</span>")
add_overlay("[initial(icon_state)]_burst")
/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, actiontype)
if(istype(actiontype, /datum/action/item_action/toggle_firemode))
@@ -75,29 +55,22 @@
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/gun/ballistic/automatic/can_shoot()
return get_ammo()
/obj/item/gun/ballistic/automatic/proc/empty_alarm()
if(!chambered && !get_ammo() && !alarmed)
playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
update_icon()
alarmed = 1
return
/obj/item/gun/ballistic/automatic/c20r
name = "\improper C-20r SMG"
desc = "A bullpup two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
icon_state = "c20r"
item_state = "c20r"
mag_type = /obj/item/ammo_box/magazine/smgm45
fire_sound = 'sound/weapons/gunshot_smg.ogg'
fire_delay = 2
burst_size = 2
pin = /obj/item/firing_pin/implant/pindicate
can_bayonet = TRUE
knife_x_offset = 26
knife_y_offset = 12
mag_display = TRUE
mag_display_ammo = TRUE
empty_indicator = TRUE
tac_reloads = TRUE
/obj/item/gun/ballistic/automatic/c20r/unrestricted
pin = /obj/item/firing_pin
@@ -106,14 +79,6 @@
. = ..()
update_icon()
/obj/item/gun/ballistic/automatic/c20r/afterattack()
. = ..()
empty_alarm()
/obj/item/gun/ballistic/automatic/c20r/update_icon()
..()
icon_state = "c20r[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
/obj/item/gun/ballistic/automatic/wt550
name = "security auto rifle"
desc = "An outdated personal defence weapon. Uses 4.6x30mm rounds and is designated the WT-550 Automatic Rifle."
@@ -127,17 +92,18 @@
can_bayonet = TRUE
knife_x_offset = 25
knife_y_offset = 12
/obj/item/gun/ballistic/automatic/wt550/update_icon()
..()
icon_state = "wt550[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]"
mag_display = TRUE
mag_display_ammo = TRUE
empty_indicator = TRUE
/obj/item/gun/ballistic/automatic/mini_uzi
name = "\improper Type U3 Uzi"
desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds."
icon_state = "mini-uzi"
icon_state = "miniuzi"
mag_type = /obj/item/ammo_box/magazine/uzim9mm
burst_size = 2
bolt_type = BOLT_TYPE_OPEN
mag_display = TRUE
/obj/item/gun/ballistic/automatic/m90
name = "\improper M-90gl Carbine"
@@ -151,6 +117,8 @@
burst_size = 3
fire_delay = 2
pin = /obj/item/firing_pin/implant/pindicate
mag_display = TRUE
empty_indicator = TRUE
/obj/item/gun/ballistic/automatic/m90/Initialize()
. = ..()
@@ -178,18 +146,18 @@
underbarrel.attackby(A, user, params)
else
..()
/obj/item/gun/ballistic/automatic/m90/update_icon()
..()
cut_overlays()
switch(select)
if(0)
add_overlay("[initial(icon_state)]semi")
add_overlay("[initial(icon_state)]_semi")
if(1)
add_overlay("[initial(icon_state)]burst")
add_overlay("[initial(icon_state)]_burst")
if(2)
add_overlay("[initial(icon_state)]gren")
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
add_overlay("[initial(icon_state)]_gren")
return
/obj/item/gun/ballistic/automatic/m90/burst_select()
var/mob/living/carbon/human/user = usr
switch(select)
@@ -222,6 +190,7 @@
can_suppress = FALSE
burst_size = 4
fire_delay = 1
bolt_type = BOLT_TYPE_OPEN
/obj/item/gun/ballistic/automatic/ar
name = "\improper NT-ARG 'Boarder'"
@@ -235,63 +204,29 @@
burst_size = 3
fire_delay = 1
// Bulldog shotgun //
/obj/item/gun/ballistic/automatic/shotgun/bulldog
name = "\improper Bulldog Shotgun"
desc = "A semi-auto, mag-fed 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 = WEIGHT_CLASS_NORMAL
weapon_weight = WEAPON_MEDIUM
mag_type = /obj/item/ammo_box/magazine/m12g
fire_sound = 'sound/weapons/shotgunshot.ogg'
vary_fire_sound = FALSE
fire_sound_volume = 90
can_suppress = FALSE
burst_size = 1
fire_delay = 0
pin = /obj/item/firing_pin/implant/pindicate
actions_types = list()
/obj/item/gun/ballistic/automatic/shotgun/bulldog/unrestricted
pin = /obj/item/firing_pin
/obj/item/gun/ballistic/automatic/shotgun/bulldog/Initialize()
. = ..()
update_icon()
/obj/item/gun/ballistic/automatic/shotgun/bulldog/update_icon()
cut_overlays()
if(magazine)
add_overlay("[magazine.icon_state]")
icon_state = "bulldog[chambered ? "" : "-e"]"
/obj/item/gun/ballistic/automatic/shotgun/bulldog/afterattack()
. = ..()
empty_alarm()
return
// L6 SAW //
/obj/item/gun/ballistic/automatic/l6_saw
name = "\improper L6 SAW"
desc = "A heavily modified 7.12x82mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
icon_state = "l6closed100"
icon_state = "l6"
item_state = "l6closedmag"
w_class = WEIGHT_CLASS_HUGE
slot_flags = 0
mag_type = /obj/item/ammo_box/magazine/mm712x82
weapon_weight = WEAPON_HEAVY
fire_sound = 'sound/weapons/gunshot_smg.ogg'
var/cover_open = FALSE
can_suppress = FALSE
burst_size = 3
fire_delay = 1
spread = 7
pin = /obj/item/firing_pin/implant/pindicate
bolt_type = BOLT_TYPE_OPEN
mag_display = TRUE
mag_display_ammo = TRUE
fire_sound = 'sound/weapons/rifleshot.ogg'
rack_sound = 'sound/weapons/chunkyrack.ogg'
/obj/item/gun/ballistic/automatic/l6_saw/unrestricted
pin = /obj/item/firing_pin
@@ -299,52 +234,47 @@
/obj/item/gun/ballistic/automatic/l6_saw/examine(mob/user)
..()
to_chat(user, "<b>ctrl + click</b> to [cover_open ? "close" : "open"] the dust cover.")
if(cover_open && magazine)
to_chat(user, "<span class='notice'>It seems like you could use an <b>empty hand</b> to remove the magazine.</span>")
/obj/item/gun/ballistic/automatic/l6_saw/attack_self(mob/user)
/obj/item/gun/ballistic/automatic/l6_saw/AltClick(mob/user)
cover_open = !cover_open
to_chat(user, "<span class='notice'>You [cover_open ? "open" : "close"] [src]'s cover.</span>")
if(cover_open)
playsound(user, 'sound/weapons/sawopen.ogg', 60, 1)
else
playsound(user, 'sound/weapons/sawclose.ogg', 60, 1)
playsound(user, 'sound/weapons/sawopen.ogg', 60, 1)
update_icon()
/obj/item/gun/ballistic/automatic/l6_saw/update_icon()
icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(0)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]"
item_state = "l6[cover_open ? "openmag" : "closedmag"]"
/obj/item/gun/ballistic/automatic/l6_saw/update_icon()
. = ..()
add_overlay("l6_door_[cover_open ? "open" : "closed"]")
/obj/item/gun/ballistic/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
/obj/item/gun/ballistic/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params)
if(cover_open)
to_chat(user, "<span class='warning'>[src]'s cover is open! Close it before firing!</span>")
return
else
. = ..()
update_icon()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/gun/ballistic/automatic/l6_saw/attack_hand(mob/user)
if(loc != 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.forceMove(drop_location())
user.put_in_hands(magazine)
magazine = null
update_icon()
to_chat(user, "<span class='notice'>You remove the magazine from [src].</span>")
playsound(user, 'sound/weapons/magout.ogg', 60, 1)
return
if (!cover_open)
to_chat("<span class='warning'>[src]'s cover is closed! Open it before trying to remove the magazine!</span>")
return
..()
/obj/item/gun/ballistic/automatic/l6_saw/attackby(obj/item/A, mob/user, params)
if(!cover_open && istype(A, mag_type))
to_chat(user, "<span class='warning'>[src]'s cover is closed! You can't insert a new mag.</span>")
to_chat(user, "<span class='warning'>[src]'s dust cover prevents a magazine from being fit.</span>")
return
..()
@@ -357,31 +287,29 @@
desc = "A long ranged weapon that does significant damage. No, you can't quickscope."
icon_state = "sniper"
item_state = "sniper"
fire_sound = "sound/weapons/sniper_shot.ogg"
fire_sound_volume = 90
vary_fire_sound = FALSE
load_sound = "sound/weapons/sniper_mag_insert.ogg"
rack_sound = "sound/weapons/sniper_rack.ogg"
recoil = 2
weapon_weight = WEAPON_HEAVY
mag_type = /obj/item/ammo_box/magazine/sniper_rounds
fire_delay = 40
burst_size = 1
can_unsuppress = TRUE
can_suppress = TRUE
w_class = WEIGHT_CLASS_NORMAL
zoomable = TRUE
zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you.
zoom_out_amt = 13
slot_flags = ITEM_SLOT_BACK
actions_types = list()
/obj/item/gun/ballistic/automatic/sniper_rifle/update_icon()
if(magazine)
icon_state = "sniper-mag"
else
icon_state = "sniper"
mag_display = TRUE
/obj/item/gun/ballistic/automatic/sniper_rifle/syndicate
name = "syndicate sniper rifle"
desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work."
can_suppress = TRUE
can_unsuppress = TRUE
pin = /obj/item/firing_pin/implant/pindicate
// Old Semi-Auto Rifle //
@@ -400,13 +328,7 @@
w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BACK
actions_types = list()
/obj/item/gun/ballistic/automatic/surplus/update_icon()
if(magazine)
icon_state = "surplus"
else
icon_state = "surplus-e"
mag_display = TRUE
// Laser rifle (rechargeable magazine) //
@@ -422,8 +344,3 @@
actions_types = list()
fire_sound = 'sound/weapons/laser.ogg'
casing_ejector = FALSE
/obj/item/gun/ballistic/automatic/laser/update_icon()
..()
icon_state = "oldrifle[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]"
return
@@ -8,14 +8,17 @@
burst_size = 1
fire_delay = 0
actions_types = list()
bolt_type = BOLT_TYPE_LOCKING
fire_sound = "sound/weapons/gunshot.ogg"
vary_fire_sound = FALSE
fire_sound_volume = 80
rack_sound = "sound/weapons/pistolrack.ogg"
bolt_drop_sound = "sound/weapons/pistolslidedrop.ogg"
bolt_wording = "slide"
/obj/item/gun/ballistic/automatic/pistol/no_mag
spawnwithmagazine = FALSE
/obj/item/gun/ballistic/automatic/pistol/update_icon()
..()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
/obj/item/gun/ballistic/automatic/pistol/suppressed/Initialize(mapload)
. = ..()
var/obj/item/suppressor/S = new(src)
@@ -39,15 +42,7 @@
force = 14
mag_type = /obj/item/ammo_box/magazine/m50
can_suppress = FALSE
/obj/item/gun/ballistic/automatic/pistol/deagle/update_icon()
..()
if(magazine)
cut_overlays()
add_overlay("deagle_magazine")
else
cut_overlays()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
mag_display = TRUE
/obj/item/gun/ballistic/automatic/pistol/deagle/gold
desc = "A gold plated Desert Eagle folded over a million times by superior martian gunsmiths. Uses .50 AE ammo."
@@ -4,15 +4,16 @@
icon_state = "revolver"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
fire_sound = 'sound/weapons/revolver357shot.ogg'
load_sound = 'sound/weapons/revolverload.ogg'
eject_sound = 'sound/weapons/revolverempty.ogg'
vary_fire_sound = FALSE
fire_sound_volume = 90
dry_fire_sound = 'sound/weapons/revolverdry.ogg'
casing_ejector = FALSE
/obj/item/gun/ballistic/revolver/Initialize()
. = ..()
if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder))
verbs -= /obj/item/gun/ballistic/revolver/verb/spin
internal_magazine = TRUE
bolt_type = BOLT_TYPE_NO_BOLT
var/spin_delay = 10
var/recent_spin = 0
/obj/item/gun/ballistic/revolver/chamber_round(spin = 1)
if(spin)
@@ -24,33 +25,9 @@
..()
chamber_round(1)
/obj/item/gun/ballistic/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, "<span class='notice'>You load [num_loaded] shell\s into \the [src].</span>")
playsound(user, 'sound/weapons/revolverload.ogg', 40, TRUE)
A.update_icon()
update_icon()
chamber_round(0)
/obj/item/gun/ballistic/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)
if(CB)
CB.forceMove(drop_location())
CB.bounce_away(FALSE, NONE)
num_unloaded++
if (num_unloaded)
to_chat(user, "<span class='notice'>You unload [num_unloaded] shell\s from [src].</span>")
playsound(user, 'sound/weapons/revolverempty.ogg', 40, FALSE)
else
to_chat(user, "<span class='warning'>[src] is empty!</span>")
/obj/item/gun/ballistic/revolver/AltClick(mob/user)
..()
spin()
/obj/item/gun/ballistic/revolver/verb/spin()
set name = "Spin Chamber"
@@ -61,6 +38,10 @@
if(M.stat || !in_range(M,src))
return
if (recent_spin > world.time)
return
recent_spin = world.time + spin_delay
if(do_spin())
playsound(usr, "revolver_spin", 30, FALSE)
@@ -75,9 +56,6 @@
C.spin()
chamber_round(0)
/obj/item/gun/ballistic/revolver/can_shoot()
return get_ammo(FALSE, FALSE)
/obj/item/gun/ballistic/revolver/get_ammo(countchambered = FALSE, countempties = TRUE)
var/boolets = 0 //mature var names for mature people
if (chambered && countchambered)
@@ -90,6 +68,8 @@
..()
var/live_ammo = get_ammo(FALSE, FALSE)
to_chat(user, "[live_ammo ? live_ammo : "None"] of those are live rounds.")
if (current_skin)
to_chat(user, "It can be spun with <b>alt+click</b>")
/obj/item/gun/ballistic/revolver/detective
name = "\improper .38 Mars Special"
@@ -180,12 +160,6 @@
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357
var/spun = FALSE
/obj/item/gun/ballistic/revolver/russian/Initialize()
. = ..()
do_spin()
spun = TRUE
update_icon()
/obj/item/gun/ballistic/revolver/russian/attackby(obj/item/A, mob/user, params)
..()
if(get_ammo() > 0)
@@ -258,108 +232,6 @@
return
user.visible_message("<span class='danger'>[user.name]'s soul is captured by \the [src]!</span>", "<span class='userdanger'>You've lost the gamble! Your soul is forfeit!</span>")
/////////////////////////////
// DOUBLE BARRELED SHOTGUN //
/////////////////////////////
/obj/item/gun/ballistic/revolver/doublebarrel
name = "double-barreled shotgun"
desc = "A true classic."
icon_state = "dshotgun"
item_state = "shotgun"
fire_sound = 'sound/weapons/shotgunshot.ogg'
vary_fire_sound = FALSE
fire_sound_volume = 90
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/internal/shot/dual
sawn_desc = "Omar's coming!"
obj_flags = UNIQUE_RENAME
unique_reskin = list("Default" = "dshotgun",
"Dark Red Finish" = "dshotgun-d",
"Ash" = "dshotgun-f",
"Faded Grey" = "dshotgun-g",
"Maple" = "dshotgun-l",
"Rosewood" = "dshotgun-p"
)
/obj/item/gun/ballistic/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/melee/transforming/energy))
var/obj/item/melee/transforming/energy/W = A
if(W.active)
sawoff(user)
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
/obj/item/gun/ballistic/revolver/doublebarrel/attack_self(mob/living/user)
var/num_unloaded = 0
while (get_ammo() > 0)
var/obj/item/ammo_casing/CB
CB = magazine.get_round(0)
chambered = null
CB.forceMove(drop_location())
CB.update_icon()
num_unloaded++
if (num_unloaded)
to_chat(user, "<span class='notice'>You break open \the [src] and unload [num_unloaded] shell\s.</span>")
else
to_chat(user, "<span class='warning'>[src] is empty!</span>")
// IMPROVISED SHOTGUN //
/obj/item/gun/ballistic/revolver/doublebarrel/improvised
name = "improvised shotgun"
desc = "Essentially a tube that aims shotgun shells."
icon_state = "ishotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
force = 10
slot_flags = null
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised
sawn_desc = "I'm just here for the gasoline."
unique_reskin = null
var/slung = FALSE
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
..()
if(istype(A, /obj/item/stack/cable_coil) && !sawn_off)
var/obj/item/stack/cable_coil/C = A
if(C.use(10))
slot_flags = ITEM_SLOT_BACK
to_chat(user, "<span class='notice'>You tie the lengths of cable to the shotgun, making a sling.</span>")
slung = TRUE
update_icon()
else
to_chat(user, "<span class='warning'>You need at least ten lengths of cable if you want to make a sling!</span>")
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/update_icon()
..()
if(slung)
icon_state += "sling"
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawoff(mob/user)
. = ..()
if(. && slung) //sawing off the gun removes the sling
new /obj/item/stack/cable_coil(get_turf(src), 10)
slung = 0
update_icon()
/obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn
name = "sawn-off improvised shotgun"
desc = "A single-shot shotgun. Better not miss."
icon_state = "ishotgun"
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL
sawn_off = TRUE
slot_flags = ITEM_SLOT_BELT
/obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
clumsy_check = 0
@@ -0,0 +1,104 @@
/obj/item/gun/ballistic/rifle
name = "Bolt Rifle"
desc = "Some kind of bolt action rifle. You get the feeling you shouldn't have this."
icon_state = "moistnugget"
icon_state = "moistnugget"
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
bolt_wording = "bolt"
bolt_type = BOLT_TYPE_STANDARD
semi_auto = FALSE
internal_magazine = TRUE
fire_sound = "sound/weapons/rifleshot.ogg"
fire_sound_volume = 80
vary_fire_sound = FALSE
rack_sound = "sound/weapons/mosinboltout.ogg"
bolt_drop_sound = "sound/weapons/mosinboltin.ogg"
obj/item/gun/ballistic/rifle/update_icon()
..()
add_overlay("[icon_state]_bolt[bolt_locked ? "_locked" : ""]")
obj/item/gun/ballistic/rifle/rack(mob/user = null)
if (bolt_locked == FALSE)
to_chat(user, "<span class='notice'>You open the bolt of \the [src]</span>")
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
process_chamber(FALSE, FALSE, FALSE)
bolt_locked = TRUE
update_icon()
return
drop_bolt()
obj/item/gun/ballistic/rifle/can_shoot()
if (bolt_locked)
return FALSE
. = ..()
obj/item/gun/ballistic/rifle/attackby(obj/item/A, mob/user, params)
if (!bolt_locked)
to_chat(user, "<span class='notice'>The bolt is closed!</span>")
return
. = ..()
/obj/item/gun/ballistic/rifle/examine(mob/user)
..()
to_chat(user, "The bolt is [bolt_locked ? "open" : "closed"].")
///////////////////////
// BOLT ACTION RIFLE //
///////////////////////
/obj/item/gun/ballistic/rifle/boltaction
name = "\improper Mosin Nagant"
desc = "This piece of junk looks like something that could have been used 700 years ago. It feels slightly moist."
icon_state = "moistnugget"
item_state = "moistnugget"
slot_flags = 0 //no ITEM_SLOT_BACK sprite, alas
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
can_bayonet = TRUE
knife_x_offset = 27
knife_y_offset = 13
/obj/item/gun/ballistic/rifle/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
/obj/item/gun/ballistic/rifle/boltaction/enchanted/arcane_barrage
name = "arcane barrage"
desc = "Pew Pew Pew."
fire_sound = 'sound/weapons/emitter.ogg'
pin = /obj/item/firing_pin/magic
icon_state = "arcane_barrage"
item_state = "arcane_barrage"
can_bayonet = FALSE
item_flags = NEEDS_PERMIT | DROPDEL
flags_1 = NONE
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage
/obj/item/gun/ballistic/rifle/boltaction/enchanted/dropped()
..()
guns_left = 0
/obj/item/gun/ballistic/rifle/boltaction/enchanted/proc/discard_gun(mob/user)
throw_at(pick(oview(7,get_turf(user))),1,1)
user.visible_message("<span class='warning'>[user] tosses aside the spent rifle!</span>")
/obj/item/gun/ballistic/rifle/boltaction/enchanted/arcane_barrage/discard_gun(mob/user)
return
/obj/item/gun/ballistic/rifle/boltaction/enchanted/attack_self()
return
/obj/item/gun/ballistic/rifle/boltaction/enchanted/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
..()
if(guns_left)
var/obj/item/gun/ballistic/rifle/boltaction/enchanted/GUN = new type
GUN.guns_left = guns_left - 1
user.dropItemToGround(src, TRUE)
user.swap_hand()
user.put_in_hands(GUN)
else
user.dropItemToGround(src, TRUE)
discard_gun(user)
+126 -150
View File
@@ -6,43 +6,19 @@
fire_sound = "sound/weapons/shotgunshot.ogg"
vary_fire_sound = FALSE
fire_sound_volume = 90
rack_sound = "sound/weapons/shotgunpump.ogg"
load_sound = "sound/weapons/shotguninsert.ogg"
w_class = WEIGHT_CLASS_BULKY
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/internal/shot
casing_ejector = FALSE
var/recentpump = 0 // to prevent spammage
weapon_weight = WEAPON_MEDIUM
/obj/item/gun/ballistic/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, "<span class='notice'>You load [num_loaded] shell\s into \the [src]!</span>")
playsound(user, 'sound/weapons/shotguninsert.ogg', 40, 1)
A.update_icon()
update_icon()
/obj/item/gun/ballistic/shotgun/process_chamber(empty_chamber = 0)
return ..() //changed argument value
/obj/item/gun/ballistic/shotgun/chamber_round()
return
/obj/item/gun/ballistic/shotgun/can_shoot()
if(!chambered)
return 0
return (chambered.BB ? 1 : 0)
/obj/item/gun/ballistic/shotgun/attack_self(mob/living/user)
if(recentpump > world.time)
return
pump(user)
recentpump = world.time + 10
return
semi_auto = FALSE
internal_magazine = TRUE
casing_ejector = FALSE
bolt_wording = "pump"
cartridge_wording = "shell"
/obj/item/gun/ballistic/shotgun/blow_up(mob/user)
. = 0
@@ -50,31 +26,6 @@
process_fire(user, user, FALSE)
. = 1
/obj/item/gun/ballistic/shotgun/proc/pump(mob/M)
playsound(M, 'sound/weapons/shotgunpump.ogg', 40, 1)
pump_unload(M)
pump_reload(M)
update_icon() //I.E. fix the desc
return 1
/obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M)
if(chambered)//We have a shell in the chamber
chambered.forceMove(drop_location())//Eject casing
chambered.bounce_away()
chambered = null
/obj/item/gun/ballistic/shotgun/proc/pump_reload(mob/M)
if(!magazine.ammo_count())
return 0
var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing.
chambered = AC
/obj/item/gun/ballistic/shotgun/examine(mob/user)
..()
if (chambered)
to_chat(user, "A [chambered.BB ? "live" : "spent"] one is in the chamber.")
/obj/item/gun/ballistic/shotgun/lethal
mag_type = /obj/item/ammo_box/magazine/internal/shot/lethal
@@ -96,101 +47,11 @@
if(W.active)
sawoff(user)
///////////////////////
// BOLT ACTION RIFLE //
///////////////////////
/obj/item/gun/ballistic/shotgun/boltaction
name = "\improper Mosin Nagant"
desc = "This piece of junk looks like something that could have been used 700 years ago. It feels slightly moist."
icon_state = "moistnugget"
item_state = "moistnugget"
slot_flags = 0 //no ITEM_SLOT_BACK sprite, alas
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
var/bolt_open = FALSE
can_bayonet = TRUE
knife_x_offset = 27
knife_y_offset = 13
/obj/item/gun/ballistic/shotgun/boltaction/pump(mob/M)
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
if(bolt_open)
pump_reload(M)
else
pump_unload(M)
bolt_open = !bolt_open
update_icon() //I.E. fix the desc
return 1
/obj/item/gun/ballistic/shotgun/boltaction/attackby(obj/item/A, mob/user, params)
if(!bolt_open)
to_chat(user, "<span class='notice'>The bolt is closed!</span>")
return
. = ..()
/obj/item/gun/ballistic/shotgun/boltaction/examine(mob/user)
..()
to_chat(user, "The bolt is [bolt_open ? "open" : "closed"].")
/obj/item/gun/ballistic/shotgun/boltaction/enchanted
name = "enchanted bolt action rifle"
desc = "Careful not to lose your head."
var/guns_left = 30
var/gun_type
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage
name = "arcane barrage"
desc = "Pew Pew Pew."
fire_sound = 'sound/weapons/emitter.ogg'
pin = /obj/item/firing_pin/magic
icon_state = "arcane_barrage"
item_state = "arcane_barrage"
can_bayonet = FALSE
item_flags = NEEDS_PERMIT | DROPDEL
flags_1 = NONE
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/Initialize()
. = ..()
bolt_open = TRUE
pump()
gun_type = type
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/dropped()
..()
guns_left = 0
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/proc/discard_gun(mob/user)
throw_at(pick(oview(7,get_turf(user))),1,1)
user.visible_message("<span class='warning'>[user] tosses aside the spent rifle!</span>")
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/arcane_barrage/discard_gun(mob/user)
return
/obj/item/gun/ballistic/shotgun/boltaction/enchanted/attack_self()
return
/obj/item/gun/ballistic/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/gun/ballistic/shotgun/boltaction/enchanted/GUN = new gun_type
GUN.guns_left = guns_left - 1
user.dropItemToGround(src, TRUE)
user.swap_hand()
user.put_in_hands(GUN)
else
user.dropItemToGround(src, TRUE)
discard_gun(user)
// Automatic Shotguns//
/obj/item/gun/ballistic/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj)
..()
src.pump(user)
src.rack()
/obj/item/gun/ballistic/shotgun/automatic/combat
name = "combat shotgun"
@@ -216,6 +77,7 @@
w_class = WEIGHT_CLASS_HUGE
var/toggled = FALSE
var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine
semi_auto = TRUE
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/examine(mob/user)
..()
@@ -228,7 +90,7 @@
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/attack_self(mob/living/user)
if(!chambered && magazine.contents.len)
pump()
rack()
else
toggle_tube(user)
@@ -246,7 +108,121 @@
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
pump()
rack()
// Bulldog shotgun //
/obj/item/gun/ballistic/shotgun/bulldog
name = "\improper Bulldog Shotgun"
desc = "A semi-auto, mag-fed 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 = WEIGHT_CLASS_NORMAL
weapon_weight = WEAPON_MEDIUM
mag_type = /obj/item/ammo_box/magazine/m12g
can_suppress = FALSE
burst_size = 1
fire_delay = 0
pin = /obj/item/firing_pin/implant/pindicate
actions_types = list()
mag_display = TRUE
empty_indicator = TRUE
empty_alarm = TRUE
special_mags = TRUE
semi_auto = TRUE
internal_magazine = FALSE
tac_reloads = TRUE
// DOUBLE BARRELED SHOTGUN and IMPROVISED SHOTGUN are in revolver.dm
/obj/item/gun/ballistic/shotgun/bulldog/unrestricted
pin = /obj/item/firing_pin
/////////////////////////////
// DOUBLE BARRELED SHOTGUN //
/////////////////////////////
/obj/item/gun/ballistic/shotgun/doublebarrel
name = "double-barreled shotgun"
desc = "A true classic."
icon_state = "dshotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/internal/shot/dual
sawn_desc = "Omar's coming!"
obj_flags = UNIQUE_RENAME
rack_sound_volume = 0
unique_reskin = list("Default" = "dshotgun",
"Dark Red Finish" = "dshotgun_d",
"Ash" = "dshotgun_f",
"Faded Grey" = "dshotgun_g",
"Maple" = "dshotgun_l",
"Rosewood" = "dshotgun_p"
)
semi_auto = TRUE
bolt_type = BOLT_TYPE_NO_BOLT
/obj/item/gun/ballistic/shotgun/doublebarrel/AltClick(mob/user)
. = ..()
if(unique_reskin && !current_skin && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
reskin_obj(user)
/obj/item/gun/ballistic/shotgun/doublebarrel/attackby(obj/item/A, mob/user, params)
..()
if(istype(A, /obj/item/melee/transforming/energy))
var/obj/item/melee/transforming/energy/W = A
if(W.active)
sawoff(user)
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
// IMPROVISED SHOTGUN //
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised
name = "improvised shotgun"
desc = "Essentially a tube that aims shotgun shells."
icon_state = "ishotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
force = 10
slot_flags = null
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised
sawn_desc = "I'm just here for the gasoline."
unique_reskin = null
var/slung = FALSE
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
..()
if(istype(A, /obj/item/stack/cable_coil) && !sawn_off)
var/obj/item/stack/cable_coil/C = A
if(C.use(10))
slot_flags = ITEM_SLOT_BACK
to_chat(user, "<span class='notice'>You tie the lengths of cable to the shotgun, making a sling.</span>")
slung = TRUE
update_icon()
else
to_chat(user, "<span class='warning'>You need at least ten lengths of cable if you want to make a sling!</span>")
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/update_icon()
..()
if(slung)
add_overlay("improvised_sling")
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/sawoff(mob/user)
. = ..()
if(. && slung) //sawing off the gun removes the sling
new /obj/item/stack/cable_coil(get_turf(src), 10)
slung = 0
update_icon()
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/sawn
name = "sawn-off improvised shotgun"
desc = "A single-shot shotgun. Better not miss."
icon_state = "ishotgun"
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL
sawn_off = TRUE
slot_flags = ITEM_SLOT_BELT