mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-25 04:57:47 +01:00
Ammo magazine and casing update
Rewrites ammo magazines and casings to be a bit more logical. Updates gun/projectile and all subtypes to work with the new ammo code.
This commit is contained in:
@@ -119,7 +119,7 @@
|
||||
operative_notes = "We'd like to remind our operatives to keep it professional. You are not here to have a good time, you are here to accomplish your objectives. These vile communists must be stopped at all costs. You may collaborate with any friends of the Syndicate coalition, but keep an eye on any of those Tiger punks if they do show up. You are completely free to accomplish your objectives any way you see fit."
|
||||
|
||||
uplink_contents = {"Highly Visible and Dangerous Weapons;
|
||||
/obj/item/weapon/gun/projectile:6:Revolver;
|
||||
/obj/item/weapon/gun/projectile/revolver:6:Revolver;
|
||||
/obj/item/ammo_magazine/a357:2:Ammo-357;
|
||||
/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow;
|
||||
/obj/item/weapon/melee/energy/sword:4:Energy Sword;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
if("combatshotgun")
|
||||
new /obj/item/weapon/gun/projectile/shotgun/pump/combat(get_turf(H))
|
||||
if("mateba")
|
||||
new /obj/item/weapon/gun/projectile/mateba(get_turf(H))
|
||||
new /obj/item/weapon/gun/projectile/revolver/mateba(get_turf(H))
|
||||
if("smg")
|
||||
new /obj/item/weapon/gun/projectile/automatic(get_turf(H))
|
||||
if("uzi")
|
||||
|
||||
@@ -217,13 +217,13 @@
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/magazine_rubber
|
||||
name = "ammunition (rubber)"
|
||||
path = /obj/item/ammo_magazine/c45r
|
||||
name = "ammunition (.45, rubber)"
|
||||
path = /obj/item/ammo_magazine/c45m/rubber
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/magazine_flash
|
||||
name = "ammunition (flash)"
|
||||
path = /obj/item/ammo_magazine/c45f
|
||||
name = "ammunition (.45, flash)"
|
||||
path = /obj/item/ammo_magazine/c45m/flash
|
||||
category = "Arms and Ammunition"
|
||||
|
||||
/datum/autolathe/recipe/consolescreen
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
return
|
||||
|
||||
if("guns")
|
||||
new /obj/item/weapon/gun/projectile(src)
|
||||
new /obj/item/weapon/gun/projectile/revolver(src)
|
||||
new /obj/item/ammo_magazine/a357(src)
|
||||
new /obj/item/weapon/card/emag(src)
|
||||
new /obj/item/weapon/plastique(src)
|
||||
|
||||
@@ -258,8 +258,8 @@
|
||||
new /obj/item/device/radio/headset/headset_sec(src)
|
||||
new /obj/item/device/detective_scanner(src)
|
||||
new /obj/item/clothing/suit/armor/det_suit(src)
|
||||
new /obj/item/ammo_magazine/c45r(src)
|
||||
new /obj/item/ammo_magazine/c45r(src)
|
||||
new /obj/item/ammo_magazine/c45m/rubber(src)
|
||||
new /obj/item/ammo_magazine/c45m/rubber(src)
|
||||
new /obj/item/taperoll/police(src)
|
||||
new /obj/item/weapon/gun/projectile/detective/semiauto(src)
|
||||
new /obj/item/clothing/tie/holster/armpit(src)
|
||||
|
||||
@@ -710,7 +710,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
for(var/i=3, i>0, i--)
|
||||
sec_briefcase.contents += new /obj/item/weapon/spacecash/c1000
|
||||
sec_briefcase.contents += new /obj/item/weapon/gun/energy/crossbow
|
||||
sec_briefcase.contents += new /obj/item/weapon/gun/projectile/mateba
|
||||
sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba
|
||||
sec_briefcase.contents += new /obj/item/ammo_magazine/a357
|
||||
sec_briefcase.contents += new /obj/item/weapon/plastique
|
||||
M.equip_to_slot_or_del(sec_briefcase, slot_l_hand)
|
||||
@@ -892,7 +892,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(M), slot_belt)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_belt)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
|
||||
var/obj/item/weapon/card/id/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card"
|
||||
|
||||
@@ -153,7 +153,7 @@ var/global/sent_strike_team = 0
|
||||
equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(src), slot_l_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/grenade/flashbang(src), slot_r_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(src), slot_belt)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(src), slot_belt)
|
||||
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand)
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
icon_state = "russianranged"
|
||||
icon_living = "russianranged"
|
||||
corpse = /obj/effect/landmark/mobcorpse/russian/ranged
|
||||
weapon1 = /obj/item/weapon/gun/projectile/mateba
|
||||
weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba
|
||||
ranged = 1
|
||||
projectiletype = /obj/item/projectile/bullet
|
||||
projectilesound = 'sound/weapons/Gunshot.ogg'
|
||||
|
||||
@@ -6,73 +6,125 @@
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 1
|
||||
w_class = 1.0
|
||||
w_class = 1
|
||||
var/caliber = "" //Which kind of guns it can be loaded into
|
||||
var/projectile_type //The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
if(ispath(projectile_type))
|
||||
BB = new projectile_type(src)
|
||||
pixel_x = rand(-10.0, 10)
|
||||
pixel_y = rand(-10.0, 10)
|
||||
set_dir(pick(cardinal))
|
||||
var/obj/item/projectile/BB = null //The loaded bullet - make it so that the projectiles are created only when needed?
|
||||
|
||||
/obj/item/ammo_casing/New()
|
||||
..()
|
||||
if(ispath(projectile_type))
|
||||
BB = new projectile_type(src)
|
||||
pixel_x = rand(-10, 10)
|
||||
pixel_y = rand(-10, 10)
|
||||
set_dir(pick(cardinal))
|
||||
|
||||
/obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(BB)
|
||||
if(initial(BB.name) == "bullet")
|
||||
var/tmp_label = ""
|
||||
var/label_text = sanitize(copytext(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 1, MAX_NAME_LEN))
|
||||
if(length(label_text) > 20)
|
||||
user << "\red The inscription can be at most 20 characters long."
|
||||
else
|
||||
if(label_text == "")
|
||||
user << "\blue You scratch the inscription off of [initial(BB)]."
|
||||
BB.name = initial(BB.name)
|
||||
else
|
||||
user << "\blue You inscribe \"[label_text]\" into \the [initial(BB.name)]."
|
||||
BB.name = "[initial(BB.name)] \"[label_text]\""
|
||||
else
|
||||
user << "\blue You can only inscribe a metal bullet." //because inscribing beanbags is silly
|
||||
else
|
||||
if(!BB)
|
||||
user << "\blue There is no bullet in the casing to inscribe anything into."
|
||||
return
|
||||
|
||||
var/tmp_label = ""
|
||||
var/label_text = sanitize(copytext(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 1, MAX_NAME_LEN))
|
||||
if(length(label_text) > 20)
|
||||
user << "\red The inscription can be at most 20 characters long."
|
||||
else if(!label_text)
|
||||
user << "\blue You scratch the inscription off of [initial(BB)]."
|
||||
BB.name = initial(BB.name)
|
||||
else
|
||||
user << "\blue You inscribe \"[label_text]\" into \the [initial(BB.name)]."
|
||||
BB.name = "[initial(BB.name)] (\"[label_text]\")"
|
||||
|
||||
/obj/item/ammo_casing/examine(mob/user)
|
||||
..()
|
||||
if (!BB)
|
||||
user << "This one is spent."
|
||||
|
||||
//Boxes of ammo
|
||||
//Gun loading types
|
||||
#define SINGLE_CASING 1 //The gun only accepts ammo_casings. ammo_magazines should never have this as their mag_type.
|
||||
#define SPEEDLOADER 2 //Transfers casings from the mag to the gun when used.
|
||||
#define MAGAZINE 4 //The magazine item itself goes inside the gun
|
||||
|
||||
//An item that holds casings and can be used to put them inside guns
|
||||
/obj/item/ammo_magazine
|
||||
name = "ammo box (.357)"
|
||||
desc = "A box of ammo"
|
||||
name = "magazine"
|
||||
desc = "A magazine for some kind of gun."
|
||||
icon_state = "357"
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "syringe_kit"
|
||||
matter = list("metal" = 50000)
|
||||
throwforce = 2
|
||||
w_class = 2.0
|
||||
matter = list("metal" = 500)
|
||||
throwforce = 5
|
||||
w_class = 2
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
|
||||
var/list/stored_ammo = list()
|
||||
var/ammo_type = "/obj/item/ammo_casing"
|
||||
var/mag_type = SPEEDLOADER //ammo_magazines can only be used with compatible guns
|
||||
var/caliber = "357"
|
||||
var/max_ammo = 7
|
||||
|
||||
var/ammo_type = /obj/item/ammo_casing //ammo type that is initially loaded
|
||||
var/initial_ammo = null
|
||||
|
||||
var/multiple_sprites = 0
|
||||
var/list/icon_map = list()
|
||||
|
||||
/obj/item/ammo_magazine/New()
|
||||
if(multiple_sprites)
|
||||
//should probably be cached or something.
|
||||
icon_map = list(max_ammo = icon_state)
|
||||
var/list/states = icon_states(icon)
|
||||
for(var/i = 0, i <= max_ammo, i++)
|
||||
var/ammo_state = "[icon_state]-[i]"
|
||||
if(ammo_state in states)
|
||||
//icon_map += i //so stupid BYOND understands that it's an association
|
||||
icon_map[i] = ammo_state
|
||||
|
||||
New()
|
||||
for(var/i = 1, i <= max_ammo, i++)
|
||||
if(isnull(initial_ammo))
|
||||
initial_ammo = max_ammo
|
||||
|
||||
if(initial_ammo)
|
||||
for(var/i in 1 to initial_ammo)
|
||||
stored_ammo += new ammo_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_magazine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = W
|
||||
if(C.caliber != caliber)
|
||||
user << "<span class='warning'>[C] does not fit into [src].</span>"
|
||||
return
|
||||
if(stored_ammo.len >= max_ammo)
|
||||
user << "<span class='warning'>[src] is full!</span>"
|
||||
return
|
||||
user.remove_from_mob(C)
|
||||
C.loc = src
|
||||
stored_ammo.Insert(1, C) //add to the head of the list
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/ammo_magazine/attack_self(mob/user)
|
||||
if(!stored_ammo.len)
|
||||
user << "<span class='notice'>[src] is already empty!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You empty [src].</span>"
|
||||
for(var/obj/item/ammo_casing/C in stored_ammo)
|
||||
C.loc = user.loc
|
||||
stored_ammo.Cut()
|
||||
update_icon()
|
||||
if(multiple_sprites)
|
||||
icon_state = "[initial(icon_state)]-[stored_ammo.len]"
|
||||
desc = "There are [stored_ammo.len] shell\s left!"
|
||||
|
||||
/obj/item/ammo_magazine/update_icon()
|
||||
if(multiple_sprites)
|
||||
//find the lowest key greater than or equal to stored_ammo.len
|
||||
var/new_state = null
|
||||
for(var/i in icon_map)
|
||||
if (i >= stored_ammo.len)
|
||||
new_state = icon_map[i]
|
||||
break
|
||||
icon_state = (new_state)? new_state : initial(icon_state)
|
||||
|
||||
/obj/item/ammo_magazine/examine(mob/user)
|
||||
..()
|
||||
user << "There [(stored_ammo.len > 1)? "are" : "is"] [stored_ammo.len] round\s left!"
|
||||
@@ -2,44 +2,147 @@
|
||||
name = "ammo box (.357)"
|
||||
desc = "A box of .357 ammo"
|
||||
icon_state = "357"
|
||||
ammo_type = "/obj/item/ammo_casing/a357"
|
||||
caliber = "357"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/c38
|
||||
name = "speed loader (.38)"
|
||||
icon_state = "38"
|
||||
ammo_type = "/obj/item/ammo_casing/c38"
|
||||
caliber = "38"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
max_ammo = 6
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/c38/rubber
|
||||
name = "speed loader (.38 rubber)"
|
||||
ammo_type = /obj/item/ammo_casing/c38r
|
||||
|
||||
/obj/item/ammo_magazine/c45m
|
||||
name = "magazine (.45)"
|
||||
icon_state = "45"
|
||||
ammo_type = "/obj/item/ammo_casing/c45"
|
||||
mag_type = MAGAZINE
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
caliber = ".45"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/c45/empty
|
||||
max_ammo = 0
|
||||
/obj/item/ammo_magazine/c45m/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/c45r
|
||||
/obj/item/ammo_magazine/c45m/rubber
|
||||
name = "magazine (.45 rubber)"
|
||||
icon_state = "45"
|
||||
ammo_type = "/obj/item/ammo_casing/c45r"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
ammo_type = /obj/item/ammo_casing/c45r
|
||||
|
||||
/obj/item/ammo_magazine/c45f
|
||||
/obj/item/ammo_magazine/c45m/flash
|
||||
name = "magazine (.45 flash)"
|
||||
icon_state = "45"
|
||||
ammo_type = "/obj/item/ammo_casing/c45f"
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm
|
||||
name = "magazine (9mm)"
|
||||
icon_state = "9x19p"
|
||||
origin_tech = "combat=2"
|
||||
mag_type = MAGAZINE
|
||||
caliber = "9mm"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
max_ammo = 10
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm/flash
|
||||
ammo_type = /obj/item/ammo_casing/c9mmf
|
||||
|
||||
/obj/item/ammo_magazine/c9mm
|
||||
name = "ammunition Box (9mm)"
|
||||
icon_state = "9mm"
|
||||
origin_tech = "combat=2"
|
||||
caliber = "9mm"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
max_ammo = 30
|
||||
|
||||
/obj/item/ammo_magazine/c9mm/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/c45
|
||||
name = "ammunition Box (.45)"
|
||||
icon_state = "9mm"
|
||||
origin_tech = "combat=2"
|
||||
caliber = ".45"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
max_ammo = 30
|
||||
|
||||
/obj/item/ammo_magazine/c9mm/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a12mm
|
||||
name = "magazine (12mm)"
|
||||
icon_state = "12mm"
|
||||
origin_tech = "combat=2"
|
||||
mag_type = MAGAZINE
|
||||
caliber = "12mm"
|
||||
ammo_type = "/obj/item/ammo_casing/a12mm"
|
||||
max_ammo = 20
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/a12mm/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a50
|
||||
name = "magazine (.50)"
|
||||
icon_state = "50ae"
|
||||
origin_tech = "combat=2"
|
||||
mag_type = MAGAZINE
|
||||
caliber = ".50"
|
||||
ammo_type = /obj/item/ammo_casing/a50
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/c45r/empty
|
||||
max_ammo = 0
|
||||
/obj/item/ammo_magazine/a50/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a75
|
||||
name = "ammo magazine (20mm)"
|
||||
icon_state = "75"
|
||||
mag_type = MAGAZINE
|
||||
caliber = "75"
|
||||
ammo_type = /obj/item/ammo_casing/a75
|
||||
multiple_sprites = 1
|
||||
max_ammo = 4
|
||||
|
||||
/obj/item/ammo_magazine/a75/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a762
|
||||
name = "magazine box (7.62mm)"
|
||||
icon_state = "a762"
|
||||
origin_tech = "combat=2"
|
||||
mag_type = MAGAZINE
|
||||
caliber = "a762"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
max_ammo = 50
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/a762/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/chameleon
|
||||
name = "magazine (.45)"
|
||||
icon_state = "45"
|
||||
mag_type = MAGAZINE
|
||||
caliber = ".45"
|
||||
ammo_type = /obj/item/ammo_casing/chameleon
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
matter = list()
|
||||
|
||||
/obj/item/ammo_magazine/chameleon/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/*
|
||||
//unused garbage
|
||||
|
||||
/obj/item/ammo_magazine/a418
|
||||
name = "ammo box (.418)"
|
||||
@@ -48,114 +151,10 @@
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
|
||||
|
||||
/obj/item/ammo_magazine/a666
|
||||
name = "ammo box (.666)"
|
||||
icon_state = "666"
|
||||
ammo_type = "/obj/item/ammo_casing/a666"
|
||||
max_ammo = 4
|
||||
multiple_sprites = 1
|
||||
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm
|
||||
name = "magazine (9mm)"
|
||||
icon_state = "9x19p"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
max_ammo = 10
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm/empty
|
||||
max_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/c9mm
|
||||
name = "Ammunition Box (9mm)"
|
||||
icon_state = "9mm"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
max_ammo = 30
|
||||
|
||||
|
||||
|
||||
/obj/item/ammo_magazine/c45
|
||||
name = "Ammunition Box (.45)"
|
||||
icon_state = "9mm"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c45"
|
||||
max_ammo = 30
|
||||
|
||||
|
||||
|
||||
/obj/item/ammo_magazine/a12mm
|
||||
name = "magazine (12mm)"
|
||||
icon_state = "12mm"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/a12mm"
|
||||
max_ammo = 20
|
||||
multiple_sprites = 1
|
||||
|
||||
|
||||
/obj/item/ammo_magazine/a12mm/empty
|
||||
name = "magazine (12mm)"
|
||||
icon_state = "12mm"
|
||||
ammo_type = "/obj/item/ammo_casing/12mm"
|
||||
max_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a50
|
||||
name = "magazine (.50)"
|
||||
icon_state = "50ae"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/a50"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/a50/empty
|
||||
name = "magazine (.50)"
|
||||
icon_state = "50ae"
|
||||
ammo_type = "/obj/item/ammo_casing/a50"
|
||||
max_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a75
|
||||
name = "ammo magazine (.75)"
|
||||
icon_state = "75"
|
||||
ammo_type = "/obj/item/ammo_casing/a75"
|
||||
multiple_sprites = 1
|
||||
max_ammo = 8
|
||||
|
||||
/obj/item/ammo_magazine/a75/empty
|
||||
name = "ammo magazine (.75)"
|
||||
icon_state = "75"
|
||||
ammo_type = "/obj/item/ammo_casing/a75"
|
||||
max_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a762
|
||||
name = "magazine (a762)"
|
||||
icon_state = "a762"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = "/obj/item/ammo_casing/a762"
|
||||
max_ammo = 50
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/a762/empty
|
||||
name = "magazine (a762)"
|
||||
icon_state = "a762"
|
||||
ammo_type = "/obj/item/ammo_casing/a762"
|
||||
max_ammo = 0
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/chameleon
|
||||
name = "magazine (.45)"
|
||||
icon_state = "45"
|
||||
ammo_type = "/obj/item/ammo_casing/chameleon"
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
matter = list()
|
||||
|
||||
/obj/item/ammo_magazine/chameleon/empty
|
||||
name = "magazine (.45)"
|
||||
icon_state = "45"
|
||||
ammo_type = "/obj/item/ammo_casing/chameleon"
|
||||
max_ammo = 0
|
||||
multiple_sprites = 1
|
||||
matter = list()
|
||||
*/
|
||||
@@ -16,6 +16,11 @@
|
||||
/obj/item/ammo_casing/c38
|
||||
desc = "A .38 bullet casing."
|
||||
caliber = "38"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol
|
||||
|
||||
/obj/item/ammo_casing/c38r
|
||||
desc = "A .38 rubber bullet casing."
|
||||
caliber = "38"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/rubber
|
||||
|
||||
/obj/item/ammo_casing/c9mm
|
||||
@@ -23,6 +28,12 @@
|
||||
caliber = "9mm"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol
|
||||
|
||||
/obj/item/ammo_casing/c9mmf
|
||||
desc = "A 9mm flash shell casing."
|
||||
caliber = "9mm"
|
||||
projectile_type = /obj/item/projectile/energy/flash
|
||||
|
||||
|
||||
/obj/item/ammo_casing/c45
|
||||
desc = "A .45 bullet casing."
|
||||
caliber = ".45"
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
/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
|
||||
//Exclude lasertag guns from the CLUMSY check.
|
||||
if(!user) return
|
||||
|
||||
|
||||
if(clumsy_check)
|
||||
if(istype(user, /mob/living))
|
||||
var/mob/living/M = user
|
||||
@@ -122,7 +122,7 @@
|
||||
"You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
|
||||
|
||||
user.next_move = world.time + 4
|
||||
|
||||
|
||||
var/x_offset = 0
|
||||
var/y_offset = 0
|
||||
if(istype(user, /mob/living/carbon))
|
||||
@@ -135,21 +135,20 @@
|
||||
x_offset = rand(-1,1)
|
||||
|
||||
if(in_chamber)
|
||||
if(params) in_chamber.set_clickpoint(params)
|
||||
|
||||
if(params)
|
||||
in_chamber.set_clickpoint(params)
|
||||
|
||||
var/fail = in_chamber.launch(
|
||||
target = target,
|
||||
user = user,
|
||||
launcher = src,
|
||||
target_zone = user.zone_sel.selecting,
|
||||
x_offset = x_offset,
|
||||
y_offset = y_offset,
|
||||
px = p_x,
|
||||
py = p_y
|
||||
target = target,
|
||||
user = user,
|
||||
launcher = src,
|
||||
target_zone = user.zone_sel.selecting,
|
||||
x_offset = x_offset,
|
||||
y_offset = y_offset
|
||||
)
|
||||
|
||||
|
||||
if(fail) return
|
||||
|
||||
|
||||
if(recoil)
|
||||
spawn()
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
|
||||
@@ -1,111 +1,160 @@
|
||||
#define SPEEDLOADER 0
|
||||
#define FROM_BOX 1
|
||||
#define MAGAZINE 2
|
||||
|
||||
/obj/item/weapon/gun/projectile
|
||||
name = "revolver"
|
||||
desc = "A classic revolver. Uses .357 ammo"
|
||||
name = "gun"
|
||||
desc = "A gun that fires bullets."
|
||||
icon_state = "revolver"
|
||||
caliber = "357"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
w_class = 3.0
|
||||
w_class = 3
|
||||
matter = list("metal" = 1000)
|
||||
recoil = 1
|
||||
var/ammo_type = "/obj/item/ammo_casing/a357"
|
||||
|
||||
var/load_method = SINGLE_CASING|SPEEDLOADER //1 = Single shells, 2 = box or quick loader, 3 = magazine
|
||||
|
||||
//For SINGLE_CASING or SPEEDLOADER guns
|
||||
var/max_shells = 0
|
||||
var/ammo_type = null
|
||||
var/list/loaded = list()
|
||||
var/max_shells = 7
|
||||
var/load_method = SPEEDLOADER //0 = Single shells or quick loader, 1 = box, 2 = magazine
|
||||
var/obj/item/ammo_magazine/empty_mag = null
|
||||
var/mag_type = null
|
||||
|
||||
//For MAGAZINE guns
|
||||
var/magazine_type = null
|
||||
var/obj/item/ammo_magazine/ammo_magazine = null
|
||||
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
|
||||
|
||||
/obj/item/weapon/gun/projectile/New()
|
||||
..()
|
||||
for(var/i = 1, i <= max_shells, i++)
|
||||
loaded += new ammo_type(src)
|
||||
if(load_method == MAGAZINE)
|
||||
empty_mag = new mag_type(src)
|
||||
|
||||
if(load_method & (SINGLE_CASING|SPEEDLOADER))
|
||||
for(var/i in 1 to max_shells)
|
||||
loaded += new ammo_type(src)
|
||||
if(load_method & MAGAZINE)
|
||||
ammo_magazine = new magazine_type(src)
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
//This proc is badly named. There is no "chamber." Would be better to call this get_next_projectile() or something.
|
||||
/obj/item/weapon/gun/projectile/load_into_chamber()
|
||||
if(in_chamber)
|
||||
return 1 //{R}
|
||||
|
||||
if(!loaded.len)
|
||||
return 0
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
if(isnull(AC) || !istype(AC))
|
||||
return 0
|
||||
AC.loc = get_turf(src) //Eject casing onto ground.
|
||||
if(AC.BB)
|
||||
in_chamber = AC.BB //Load projectile into chamber.
|
||||
AC.BB.loc = src //Set projectile loc to gun.
|
||||
return 1
|
||||
var/obj/item/ammo_casing/C = null
|
||||
if(loaded.len)
|
||||
C = loaded[1] //load next casing.
|
||||
loaded -= C
|
||||
else if(ammo_magazine && ammo_magazine.stored_ammo.len)
|
||||
C = ammo_magazine.stored_ammo[1]
|
||||
ammo_magazine.stored_ammo -= C
|
||||
|
||||
if(istype(C))
|
||||
C.loc = get_turf(src) //Eject casing onto ground.
|
||||
if(C.BB)
|
||||
in_chamber = C.BB
|
||||
C.BB.loc = src //Set projectile loc to gun.
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
//Attempts to load A into src, depending on the type of thing being loaded and the load_method
|
||||
/obj/item/weapon/gun/projectile/proc/load_ammo(var/obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
var/obj/item/ammo_magazine/AM = A
|
||||
if(!(load_method & AM.mag_type) || caliber != AM.caliber)
|
||||
return //incompatible
|
||||
|
||||
switch(AM.mag_type)
|
||||
if(MAGAZINE)
|
||||
if(ammo_magazine)
|
||||
return //already a magazine here
|
||||
user.remove_from_mob(AM)
|
||||
AM.loc = src
|
||||
ammo_magazine = AM
|
||||
user.visible_message("[user] inserts [AM] into [src].", "<span class='notice'>You insert [AM] into [src]!</span>")
|
||||
if(SPEEDLOADER)
|
||||
var/count = 0
|
||||
for(var/obj/item/ammo_casing/C in AM.stored_ammo)
|
||||
if(loaded.len >= max_shells)
|
||||
break
|
||||
if(C.caliber == caliber)
|
||||
C.loc = src
|
||||
loaded += C
|
||||
AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way...
|
||||
count++
|
||||
if(count)
|
||||
user.visible_message("[user] reloads [src].", "<span class='notice'>You load [count] round\s into [src]!</span>")
|
||||
AM.update_icon()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else if(istype(A, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = A
|
||||
if(!(load_method & SINGLE_CASING) || caliber != C.caliber || loaded.len >= max_shells)
|
||||
return //incompatible or full
|
||||
|
||||
user.remove_from_mob(C)
|
||||
C.loc = src
|
||||
loaded += C
|
||||
user.visible_message("[user] inserts \a [C] into [src].", "<span class='notice'>You insert \a [C] into [src]!</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
//attempts to unload src
|
||||
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user)
|
||||
if(ammo_magazine)
|
||||
user.put_in_hands(ammo_magazine)
|
||||
user.visible_message("[user] removes [ammo_magazine] from [src].", "<span class='notice'>You remove [ammo_magazine] from [src]!</span>")
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
update_icon()
|
||||
|
||||
else if(loaded.len)
|
||||
//presumably, if it can be speed-loaded, it can be speed-unloaded.
|
||||
if(load_method & SPEEDLOADER)
|
||||
var/count = 0
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
for(var/obj/item/ammo_casing/C in loaded)
|
||||
C.loc = T
|
||||
count++
|
||||
loaded.Cut()
|
||||
if(count)
|
||||
user.visible_message("[user] unloads [src].", "<span class='notice'>You unload [count] round\s from [src]!</span>")
|
||||
else
|
||||
var/obj/item/ammo_casing/C = loaded[loaded.len]
|
||||
loaded.len--
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
else
|
||||
user << "<span class='warning'>There's nothing loaded in [src]!</span>"
|
||||
|
||||
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
|
||||
var/num_loaded = 0
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
if((load_method == MAGAZINE) && loaded.len) return
|
||||
var/obj/item/ammo_magazine/AM = A
|
||||
if(AM.stored_ammo.len <= 0)
|
||||
user << "<span class='warning'>The magazine is empty!</span>"
|
||||
return
|
||||
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
|
||||
if(loaded.len >= max_shells)
|
||||
break
|
||||
if(AC.caliber == caliber && loaded.len < max_shells)
|
||||
AC.loc = src
|
||||
AM.stored_ammo -= AC
|
||||
loaded += AC
|
||||
num_loaded++
|
||||
if(load_method == MAGAZINE)
|
||||
user.remove_from_mob(AM)
|
||||
empty_mag = AM
|
||||
empty_mag.loc = src
|
||||
if(istype(A, /obj/item/ammo_casing) && load_method == SPEEDLOADER)
|
||||
var/obj/item/ammo_casing/AC = A
|
||||
if(AC.caliber == caliber && loaded.len < max_shells)
|
||||
user.drop_item()
|
||||
AC.loc = src
|
||||
loaded += AC
|
||||
num_loaded++
|
||||
if(num_loaded)
|
||||
user << "\blue You load [num_loaded] shell\s into the gun!"
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
return
|
||||
load_ammo(A, user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
|
||||
if (target)
|
||||
if (target) //TODO replace untargeting with a hotkey
|
||||
return ..()
|
||||
if (loaded.len)
|
||||
if (load_method == SPEEDLOADER)
|
||||
var/obj/item/ammo_casing/AC = loaded[1]
|
||||
loaded -= AC
|
||||
AC.loc = get_turf(src) //Eject casing onto ground.
|
||||
user << "\blue You unload shell from \the [src]!"
|
||||
if (load_method == MAGAZINE)
|
||||
var/obj/item/ammo_magazine/AM = empty_mag
|
||||
for (var/obj/item/ammo_casing/AC in loaded)
|
||||
AM.stored_ammo += AC
|
||||
loaded -= AC
|
||||
AM.loc = get_turf(src)
|
||||
empty_mag = null
|
||||
update_icon()
|
||||
AM.update_icon()
|
||||
user << "\blue You unload magazine from \the [src]!"
|
||||
else
|
||||
user << "\red Nothing loaded in \the [src]!"
|
||||
unload_ammo(user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user)
|
||||
..()
|
||||
if(auto_eject && !ammo_magazine.stored_ammo.len)
|
||||
eject_magazine(user)
|
||||
|
||||
//called when the magazine auto-ejects
|
||||
/obj/item/weapon/gun/projectile/proc/eject_magazine(mob/user)
|
||||
if(ammo_magazine)
|
||||
ammo_magazine.loc = get_turf(src.loc)
|
||||
user.visible_message(
|
||||
"[ammo_magazine] falls out and clatters on the floor!",
|
||||
"<span class='notice'>[ammo_magazine] falls out and clatters on the floor!</span>"
|
||||
)
|
||||
ammo_magazine = null
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/examine(mob/user)
|
||||
..(user)
|
||||
if(ammo_magazine)
|
||||
user << "It has \a [ammo_magazine] loaded."
|
||||
user << "Has [getAmmo()] round\s remaining."
|
||||
// if(in_chamber && !loaded.len)
|
||||
// user << "However, it has a chambered round."
|
||||
@@ -115,7 +164,8 @@
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/getAmmo()
|
||||
var/bullets = 0
|
||||
for(var/obj/item/ammo_casing/AC in loaded)
|
||||
if(istype(AC))
|
||||
bullets += 1
|
||||
if(loaded)
|
||||
bullets += loaded.len
|
||||
if(ammo_magazine.stored_ammo)
|
||||
bullets += ammo_magazine.stored_ammo.len
|
||||
return bullets
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
name = "submachine gun"
|
||||
desc = "A lightweight, fast firing gun. Uses 9mm rounds."
|
||||
icon_state = "saber" //ugly
|
||||
w_class = 3.0
|
||||
w_class = 3
|
||||
load_method = SPEEDLOADER //yup. until someone sprites a magazine for it.
|
||||
max_shells = 22
|
||||
caliber = "9mm"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
automatic = 1
|
||||
|
||||
fire_delay = 0
|
||||
@@ -14,19 +15,16 @@
|
||||
isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/test
|
||||
name = "test gun"
|
||||
ammo_type = "/obj/item/ammo_casing/a145"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/mini_uzi
|
||||
name = "\improper Uzi"
|
||||
desc = "A lightweight, fast firing gun, for when you want someone dead. Uses .45 rounds."
|
||||
icon_state = "mini-uzi"
|
||||
w_class = 3.0
|
||||
max_shells = 16
|
||||
w_class = 3
|
||||
load_method = SPEEDLOADER //yup. until someone sprites a magazine for it.
|
||||
max_shells = 15
|
||||
caliber = ".45"
|
||||
origin_tech = "combat=5;materials=2;syndicate=8"
|
||||
ammo_type = "/obj/item/ammo_casing/c45"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
|
||||
isHandgun()
|
||||
return 1
|
||||
@@ -37,32 +35,26 @@
|
||||
desc = "A lightweight, fast firing gun, for when you REALLY need someone dead. Uses 12mm rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp"
|
||||
icon_state = "c20r"
|
||||
item_state = "c20r"
|
||||
w_class = 3.0
|
||||
max_shells = 20
|
||||
w_class = 3
|
||||
caliber = "12mm"
|
||||
origin_tech = "combat=5;materials=2;syndicate=8"
|
||||
ammo_type = "/obj/item/ammo_casing/a12mm"
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/a12mm/empty
|
||||
magazine_type = /obj/item/ammo_magazine/a12mm
|
||||
auto_eject = 1
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
if(!loaded.len && empty_mag)
|
||||
empty_mag.loc = get_turf(src.loc)
|
||||
empty_mag = null
|
||||
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
update_icon()
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/eject_magazine(mob/user)
|
||||
..()
|
||||
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
|
||||
..()
|
||||
if(ammo_magazine)
|
||||
icon_state = "c20r-[round(loaded.len,4)]"
|
||||
else
|
||||
icon_state = "c20r"
|
||||
return
|
||||
|
||||
update_icon()
|
||||
..()
|
||||
if(empty_mag)
|
||||
icon_state = "c20r-[round(loaded.len,4)]"
|
||||
else
|
||||
icon_state = "c20r"
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw
|
||||
name = "\improper L6 SAW"
|
||||
@@ -77,19 +69,16 @@
|
||||
ammo_type = "/obj/item/ammo_casing/a762"
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/a762
|
||||
var/cover_open = 0
|
||||
var/mag_inserted = 1
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob)
|
||||
cover_open = !cover_open
|
||||
user << "<span class='notice'>You [cover_open ? "open" : "close"] [src]'s cover.</span>"
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon()
|
||||
icon_state = "l6[cover_open ? "open" : "closed"][mag_inserted ? round(loaded.len, 25) : "-empty"]"
|
||||
|
||||
icon_state = "l6[cover_open ? "open" : "closed"][ammo_magazine ? round(loaded.len, 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)
|
||||
@@ -98,46 +87,14 @@
|
||||
..()
|
||||
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 && !mag_inserted))
|
||||
..()
|
||||
else if(cover_open && mag_inserted)
|
||||
//drop the mag
|
||||
empty_mag = new /obj/item/ammo_magazine/a762(src)
|
||||
empty_mag.stored_ammo = loaded
|
||||
empty_mag.icon_state = "a762-[round(loaded.len, 10)]"
|
||||
empty_mag.desc = "There are [loaded.len] shells left!"
|
||||
empty_mag.loc = get_turf(src.loc)
|
||||
user.put_in_hands(empty_mag)
|
||||
empty_mag = null
|
||||
mag_inserted = 0
|
||||
loaded = list()
|
||||
update_icon()
|
||||
user << "<span class='notice'>You remove the magazine from [src].</span>"
|
||||
|
||||
..() //let them pick it up
|
||||
else if(cover_open)
|
||||
unload_ammo(user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
if(!cover_open)
|
||||
if(istype(A,/obj/item/ammo_magazine) && !cover_open)
|
||||
user << "<span class='notice'>[src]'s cover is closed! You can't insert a new mag!</span>"
|
||||
return
|
||||
else if(cover_open && mag_inserted)
|
||||
user << "<span class='notice'>[src] already has a magazine inserted!</span>"
|
||||
return
|
||||
else if(cover_open && !mag_inserted)
|
||||
mag_inserted = 1
|
||||
user << "<span class='notice'>You insert the magazine!</span>"
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
|
||||
/* The thing I found with guns in ss13 is that they don't seem to simulate the rounds in the magazine in the gun.
|
||||
Afaik, since projectile.dm features a revolver, this would make sense since the magazine is part of the gun.
|
||||
However, it looks like subsequent guns that use removable magazines don't take that into account and just get
|
||||
around simulating a removable magazine by adding the casings into the loaded list and spawning an empty magazine
|
||||
when the gun is out of rounds. Which means you can't eject magazines with rounds in them. The below is a very
|
||||
rough and poor attempt at making that happen. -Ausops */
|
||||
|
||||
..()
|
||||
@@ -2,42 +2,32 @@
|
||||
name = "silenced pistol"
|
||||
desc = "A small, quiet, easily concealable gun. Uses .45 rounds."
|
||||
icon_state = "silenced_pistol"
|
||||
w_class = 3.0
|
||||
max_shells = 12
|
||||
w_class = 3
|
||||
caliber = ".45"
|
||||
silenced = 1
|
||||
origin_tech = "combat=2;materials=2;syndicate=8"
|
||||
ammo_type = "/obj/item/ammo_casing/c45"
|
||||
|
||||
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/c45m
|
||||
|
||||
/obj/item/weapon/gun/projectile/deagle
|
||||
name = "desert eagle"
|
||||
desc = "A robust handgun that uses .50 AE ammo"
|
||||
icon_state = "deagle"
|
||||
force = 14.0
|
||||
max_shells = 7
|
||||
caliber = ".50"
|
||||
ammo_type ="/obj/item/ammo_casing/a50"
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/a50/empty
|
||||
magazine_type = /obj/item/ammo_magazine/a50
|
||||
auto_eject = 1
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
if(!loaded.len && empty_mag)
|
||||
empty_mag.loc = get_turf(src.loc)
|
||||
empty_mag = null
|
||||
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
update_icon()
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/deagle/eject_magazine(mob/user)
|
||||
..()
|
||||
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
|
||||
/obj/item/weapon/gun/projectile/deagle/gold
|
||||
desc = "A gold plated gun folded over a million times by superior martian gunsmiths. Uses .50 AE ammo."
|
||||
icon_state = "deagleg"
|
||||
item_state = "deagleg"
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/deagle/camo
|
||||
desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo."
|
||||
icon_state = "deaglecamo"
|
||||
@@ -55,44 +45,34 @@
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = "/obj/item/ammo_casing/a75"
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/a75/empty
|
||||
magazine_type = /obj/item/ammo_magazine/a75
|
||||
auto_eject = 1
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
if(!loaded.len && empty_mag)
|
||||
empty_mag.loc = get_turf(src.loc)
|
||||
empty_mag = null
|
||||
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
update_icon()
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/gyropistol/eject_magazine(mob/user)
|
||||
..()
|
||||
playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
|
||||
update_icon()
|
||||
..()
|
||||
if(empty_mag)
|
||||
icon_state = "gyropistolloaded"
|
||||
else
|
||||
icon_state = "gyropistol"
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/gyropistol/update_icon()
|
||||
..()
|
||||
if(ammo_magazine)
|
||||
icon_state = "gyropistolloaded"
|
||||
else
|
||||
icon_state = "gyropistol"
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol
|
||||
name = "\improper Stechtkin pistol"
|
||||
desc = "A small, easily concealable gun. Uses 9mm rounds."
|
||||
icon_state = "pistol"
|
||||
w_class = 2
|
||||
max_shells = 10
|
||||
caliber = "9mm"
|
||||
silenced = 0
|
||||
origin_tech = "combat=2;materials=2;syndicate=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c9mm"
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/mc9mm/empty
|
||||
magazine_type = /obj/item/ammo_magazine/mc9mm
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
if(!loaded.len && empty_mag)
|
||||
empty_mag.loc = get_turf(src.loc)
|
||||
empty_mag = null
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/pistol/flash
|
||||
desc = "A small, easily concealable gun. Uses 9mm illumination rounds."
|
||||
magazine_type = /obj/item/ammo_magazine/mc9mm/flash
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol/attack_hand(mob/user as mob)
|
||||
if(loc == user)
|
||||
@@ -108,7 +88,6 @@
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/silencer))
|
||||
if(user.l_hand != src && user.r_hand != src) //if we're not in his hands
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/obj/item/weapon/gun/projectile/revolver
|
||||
name = "revolver"
|
||||
desc = "A classic revolver. Uses .357 ammo"
|
||||
icon_state = "revolver"
|
||||
caliber = "357"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
|
||||
max_shells = 7
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective
|
||||
name = "revolver"
|
||||
desc = "A cheap Martian knock-off of a Smith & Wesson Model 10. Uses .38-Special rounds."
|
||||
@@ -5,7 +15,7 @@
|
||||
max_shells = 6
|
||||
caliber = "38"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c38"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
|
||||
special_check(var/mob/living/carbon/human/M)
|
||||
if(caliber == initial(caliber))
|
||||
@@ -73,37 +83,27 @@
|
||||
name = "\improper Colt M1911"
|
||||
desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds."
|
||||
icon_state = "colt"
|
||||
max_shells = 7
|
||||
caliber = ".45"
|
||||
ammo_type = "/obj/item/ammo_casing/c45r"
|
||||
load_method = MAGAZINE
|
||||
mag_type = /obj/item/ammo_magazine/c45r/empty
|
||||
magazine_type = /obj/item/ammo_magazine/c45m/rubber
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/flash
|
||||
ammo_type = "/obj/item/ammo_casing/c45f"
|
||||
magazine_type = /obj/item/ammo_magazine/c45m/flash
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/colt
|
||||
desc = "A cheap Martian knock-off of a Colt M1911."
|
||||
ammo_type = "/obj/item/ammo_casing/c45"
|
||||
magazine_type = /obj/item/ammo_magazine/c45m
|
||||
|
||||
/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
if(!loaded.len && empty_mag)
|
||||
empty_mag.loc = get_turf(src.loc)
|
||||
empty_mag = null
|
||||
user << "<span class='notice'>The Magazine falls out and clatters on the floor!</span>"
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/mateba
|
||||
/obj/item/weapon/gun/projectile/revolver/mateba
|
||||
name = "mateba"
|
||||
desc = "When you absolutely, positively need a 10mm hole in the other guy. Uses .357 ammo." //>10mm hole >.357
|
||||
icon_state = "mateba"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
|
||||
|
||||
// A gun to play Russian Roulette!
|
||||
// You can spin the chamber to randomize the position of the bullet.
|
||||
|
||||
/*
|
||||
/obj/item/weapon/gun/projectile/russian
|
||||
name = "\improper Russian revolver"
|
||||
desc = "A Russian made revolver. Uses .357 ammo. It has a single slot in it's chamber for a bullet."
|
||||
@@ -184,3 +184,4 @@
|
||||
user.apply_damage(300, BRUTE, affecting, sharp=1) // You are dead, dead, dead.
|
||||
return
|
||||
..()
|
||||
*/
|
||||
@@ -10,127 +10,89 @@
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "shotgun"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/shotgun/pellet"
|
||||
load_method = SINGLE_CASING
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/pellet
|
||||
var/recentpump = 0 // to prevent spammage
|
||||
var/pumped = 0
|
||||
var/obj/item/ammo_casing/current_shell = null
|
||||
|
||||
isHandgun()
|
||||
return 0
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/isHandgun()
|
||||
return 0
|
||||
|
||||
load_into_chamber()
|
||||
if(in_chamber)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
if(recentpump) return
|
||||
pump(user)
|
||||
recentpump = 1
|
||||
spawn(10)
|
||||
recentpump = 0
|
||||
return
|
||||
|
||||
|
||||
proc/pump(mob/M as mob)
|
||||
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
|
||||
pumped = 0
|
||||
if(current_shell)//We have a shell in the chamber
|
||||
current_shell.loc = get_turf(src)//Eject casing
|
||||
current_shell = null
|
||||
if(in_chamber)
|
||||
in_chamber = null
|
||||
if(!loaded.len) return 0
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
current_shell = AC
|
||||
if(AC.BB)
|
||||
in_chamber = AC.BB //Load projectile into chamber.
|
||||
update_icon() //I.E. fix the desc
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/load_into_chamber()
|
||||
if(in_chamber)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob)
|
||||
if(world.time >= recentpump + 10)
|
||||
pump(user)
|
||||
recentpump = world.time
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/getAmmo()
|
||||
. = ..()
|
||||
if(current_shell) .++
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob)
|
||||
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
|
||||
pumped = 0
|
||||
if(current_shell)//We have a shell in the chamber
|
||||
current_shell.loc = get_turf(src)//Eject casing
|
||||
current_shell = null
|
||||
if(in_chamber)
|
||||
in_chamber = null
|
||||
if(!loaded.len) return 0
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
current_shell = AC
|
||||
if(AC.BB)
|
||||
in_chamber = AC.BB //Load projectile into chamber.
|
||||
update_icon() //I.E. fix the desc
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat
|
||||
name = "combat shotgun"
|
||||
icon_state = "cshotgun"
|
||||
max_shells = 8
|
||||
origin_tech = "combat=5;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/shotgun"
|
||||
max_shells = 8
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
|
||||
|
||||
//this is largely hacky and bad :( -Pete
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel
|
||||
name = "double-barreled shotgun"
|
||||
desc = "A true classic."
|
||||
icon_state = "dshotgun"
|
||||
item_state = "shotgun"
|
||||
//SPEEDLOADER because rapid unloading.
|
||||
//In principle someone could make a speedloader for it, so it makes sense.
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
max_shells = 2
|
||||
w_class = 4.0
|
||||
w_class = 4
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "shotgun"
|
||||
origin_tech = "combat=3;materials=1"
|
||||
ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
|
||||
New()
|
||||
for(var/i = 1, i <= max_shells, i++)
|
||||
loaded += new ammo_type(src)
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
load_into_chamber()
|
||||
// if(in_chamber)
|
||||
// return 1 {R}
|
||||
if(!loaded.len)
|
||||
return 0
|
||||
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
AC.desc += " This one is spent."
|
||||
|
||||
if(AC.BB)
|
||||
in_chamber = AC.BB //Load projectile into chamber.
|
||||
return 1
|
||||
return 0
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
if(!(locate(/obj/item/ammo_casing/shotgun) in src) && !loaded.len)
|
||||
user << "<span class='notice'>\The [src] is empty.</span>"
|
||||
return
|
||||
|
||||
for(var/obj/item/ammo_casing/shotgun/shell in src) //This feels like a hack. //don't code at 3:30am kids!!
|
||||
if(shell in loaded)
|
||||
loaded -= shell
|
||||
shell.loc = get_turf(src.loc)
|
||||
|
||||
user << "<span class='notice'>You break \the [src].</span>"
|
||||
update_icon()
|
||||
|
||||
attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
if(istype(A, /obj/item/ammo_casing) && !load_method)
|
||||
var/obj/item/ammo_casing/AC = A
|
||||
if(AC.caliber == caliber && (loaded.len < max_shells) && (contents.len < max_shells)) //forgive me father, for i have sinned
|
||||
user.drop_item()
|
||||
AC.loc = src
|
||||
loaded += AC
|
||||
user << "<span class='notice'>You load a shell into \the [src]!</span>"
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
|
||||
user << "<span class='notice'>You begin to shorten the barrel of \the [src].</span>"
|
||||
if(loaded.len)
|
||||
afterattack(user, user) //will this work?
|
||||
afterattack(user, user) //it will. we call it twice, for twice the FUN
|
||||
//this is largely hacky and bad :( -Pete
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
|
||||
user << "<span class='notice'>You begin to shorten the barrel of \the [src].</span>"
|
||||
if(loaded.len)
|
||||
for(var/i in 1 to max_shells)
|
||||
afterattack(user, user) //will this work? //it will. we call it twice, for twice the FUN
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
user.visible_message("<span class='danger'>The shotgun goes off!</span>", "<span class='danger'>The shotgun goes off in your face!</span>")
|
||||
return
|
||||
if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY
|
||||
icon_state = "sawnshotgun"
|
||||
w_class = 3.0
|
||||
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)
|
||||
name = "sawn-off shotgun"
|
||||
desc = "Omar's coming!"
|
||||
user << "<span class='warning'>You shorten the barrel of \the [src]!</span>"
|
||||
user.visible_message("<span class='danger'>The shotgun goes off!</span>", "<span class='danger'>The shotgun goes off in your face!</span>")
|
||||
return
|
||||
if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY
|
||||
icon_state = "sawnshotgun"
|
||||
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)
|
||||
name = "sawn-off shotgun"
|
||||
desc = "Omar's coming!"
|
||||
user << "<span class='warning'>You shorten the barrel of \the [src]!</span>"
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -103,8 +103,8 @@
|
||||
user.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
if(targloc == curloc) //Shooting the ground
|
||||
targloc.bullet_act(src, target_zone)
|
||||
if(targloc == curloc) //Shooting something in the same turf
|
||||
target.bullet_act(src, target_zone)
|
||||
del(src)
|
||||
return 0
|
||||
|
||||
@@ -236,14 +236,20 @@
|
||||
/obj/item/projectile/process()
|
||||
if(kill_count < 1)
|
||||
del(src)
|
||||
return
|
||||
step_towards(src, current)
|
||||
sleep(1)
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
kill_count--
|
||||
spawn while(src)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
|
||||
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
|
||||
del(src)
|
||||
return
|
||||
step_towards(src, current)
|
||||
sleep(1)
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
|
||||
//"Tracing" projectile
|
||||
/obj/item/projectile/test //Used to see if you can hit them.
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
item_type = "gun"
|
||||
if(27)
|
||||
//revolver
|
||||
var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile(src.loc)
|
||||
var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile/revolver(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "gun[rand(1,4)]"
|
||||
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
@@ -383,7 +383,7 @@
|
||||
if(num_bullets < new_gun.loaded.len)
|
||||
new_gun.loaded.Cut()
|
||||
for(var/i = 1, i <= num_bullets, i++)
|
||||
var/A = text2path(new_gun.ammo_type)
|
||||
var/A = new_gun.ammo_type
|
||||
new_gun.loaded += new A(new_gun)
|
||||
else
|
||||
for(var/obj/item/I in new_gun)
|
||||
|
||||
Reference in New Issue
Block a user