mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 03:57:48 +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:
@@ -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