mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-16 01:23:41 +01:00
Merge branch 'ParadiseSS13/master' into runtime-fix-2
This commit is contained in:
@@ -1,221 +1,222 @@
|
||||
/obj/item/ammo_casing
|
||||
name = "bullet casing"
|
||||
desc = "A bullet casing."
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "s-casing"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/fire_sound = null //What sound should play when this ammo is fired
|
||||
var/drop_sound = "casingdrop" //What sound should play when this ammo hits the ground
|
||||
var/caliber = null //Which kind of guns it can be loaded into
|
||||
var/projectile_type = null //The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet
|
||||
var/pellets = 1 //Pellets for spreadshot
|
||||
var/variance = 0 //Variance for inaccuracy fundamental to the casing
|
||||
var/delay = 0 //Delay for energy weapons
|
||||
var/randomspread = 0 //Randomspread for automatics
|
||||
var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown.
|
||||
var/harmful = TRUE //pacifism check for boolet, set to FALSE if bullet is non-lethal
|
||||
|
||||
/obj/item/ammo_casing/New()
|
||||
..()
|
||||
if(projectile_type)
|
||||
BB = new projectile_type(src)
|
||||
pixel_x = rand(-10.0, 10)
|
||||
pixel_y = rand(-10.0, 10)
|
||||
dir = pick(alldirs)
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_casing/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)][BB ? "-live" : ""]"
|
||||
desc = "[initial(desc)][BB ? "" : " This one is spent."]"
|
||||
|
||||
/obj/item/ammo_casing/proc/newshot(params) //For energy weapons, shotgun shells and wands (!).
|
||||
if(!BB)
|
||||
BB = new projectile_type(src, params)
|
||||
return
|
||||
|
||||
/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
if(istype(I, /obj/item/ammo_box))
|
||||
var/obj/item/ammo_box/box = I
|
||||
if(isturf(loc))
|
||||
var/boolets = 0
|
||||
for(var/obj/item/ammo_casing/bullet in loc)
|
||||
if(box.stored_ammo.len >= box.max_ammo)
|
||||
break
|
||||
if(bullet.BB)
|
||||
if(box.give_round(bullet, 0))
|
||||
boolets++
|
||||
else
|
||||
continue
|
||||
if(boolets > 0)
|
||||
box.update_icon()
|
||||
to_chat(user, "<span class='notice'>You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.</span>")
|
||||
playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to collect anything!</span>")
|
||||
else
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
if(BB)
|
||||
if(initial(BB.name) == "bullet")
|
||||
var/tmp_label = ""
|
||||
var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label))
|
||||
if(length(label_text) > 20)
|
||||
to_chat(user, "<span class='warning''>The inscription can be at most 20 characters long.</span>")
|
||||
else
|
||||
if(label_text == "")
|
||||
to_chat(user, "<span class='notice'>You scratch the inscription off of [initial(BB)].</span>")
|
||||
BB.name = initial(BB.name)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You inscribe \"[label_text]\" into \the [initial(BB.name)].</span>")
|
||||
BB.name = "[initial(BB.name)] \"[label_text]\""
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can only inscribe a metal bullet.</span>")//because inscribing beanbags is silly
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There is no bullet in the casing to inscribe anything into.</span>")
|
||||
..()
|
||||
|
||||
//Boxes of ammo
|
||||
/obj/item/ammo_box
|
||||
name = "ammo box (generic)"
|
||||
desc = "A box of ammo?"
|
||||
icon_state = "357"
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "syringe_kit"
|
||||
materials = list(MAT_METAL = 30000)
|
||||
throwforce = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
var/list/stored_ammo = list()
|
||||
var/ammo_type = /obj/item/ammo_casing
|
||||
var/max_ammo = 7
|
||||
var/multiple_sprites = 0
|
||||
var/caliber
|
||||
var/multiload = 1
|
||||
var/list/initial_mats //For calculating refund values.
|
||||
|
||||
/obj/item/ammo_box/New()
|
||||
for(var/i in 1 to max_ammo)
|
||||
stored_ammo += new ammo_type(src)
|
||||
update_icon()
|
||||
initial_mats = materials.Copy()
|
||||
update_mat_value()
|
||||
|
||||
/obj/item/ammo_box/Destroy()
|
||||
QDEL_LIST(stored_ammo)
|
||||
stored_ammo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/ammo_box/proc/get_round(keep = 0)
|
||||
if(!stored_ammo.len)
|
||||
return null
|
||||
else
|
||||
var/b = stored_ammo[stored_ammo.len]
|
||||
stored_ammo -= b
|
||||
if(keep)
|
||||
stored_ammo.Insert(1,b)
|
||||
update_mat_value()
|
||||
return b
|
||||
|
||||
/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0)
|
||||
// Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type.
|
||||
if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type))
|
||||
return 0
|
||||
|
||||
if(stored_ammo.len < max_ammo)
|
||||
stored_ammo += R
|
||||
R.loc = src
|
||||
playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1)
|
||||
update_mat_value()
|
||||
return 1
|
||||
//for accessibles magazines (e.g internal ones) when full, start replacing spent ammo
|
||||
else if(replace_spent)
|
||||
for(var/obj/item/ammo_casing/AC in stored_ammo)
|
||||
if(!AC.BB)//found a spent ammo
|
||||
stored_ammo -= AC
|
||||
AC.loc = get_turf(loc)
|
||||
|
||||
stored_ammo += R
|
||||
R.loc = src
|
||||
playsound(src, 'sound/weapons/gun_interactions/shotguninsert.ogg', 50, 1)
|
||||
update_mat_value()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/ammo_box/proc/can_load(mob/user)
|
||||
return 1
|
||||
|
||||
/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = 0, replace_spent = 0)
|
||||
var/num_loaded = 0
|
||||
if(!can_load(user))
|
||||
return
|
||||
if(istype(A, /obj/item/ammo_box))
|
||||
var/obj/item/ammo_box/AM = A
|
||||
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
|
||||
var/did_load = give_round(AC, replace_spent)
|
||||
if(did_load)
|
||||
AM.stored_ammo -= AC
|
||||
num_loaded++
|
||||
if(!multiload || !did_load)
|
||||
break
|
||||
if(istype(A, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/AC = A
|
||||
if(give_round(AC, replace_spent))
|
||||
user.drop_item()
|
||||
AC.loc = src
|
||||
num_loaded++
|
||||
if(num_loaded)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src]!</span>")
|
||||
playsound(src, 'sound/weapons/gun_interactions/shotguninsert.ogg', 50, 1)
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
|
||||
return num_loaded
|
||||
|
||||
/obj/item/ammo_box/attack_self(mob/user as mob)
|
||||
var/obj/item/ammo_casing/A = get_round()
|
||||
if(A)
|
||||
user.put_in_hands(A)
|
||||
playsound(src, 'sound/weapons/gun_interactions/remove_bullet.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove a round from \the [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_box/update_icon()
|
||||
switch(multiple_sprites)
|
||||
if(1)
|
||||
icon_state = "[initial(icon_state)]-[stored_ammo.len]"
|
||||
if(2)
|
||||
icon_state = "[initial(icon_state)]-[stored_ammo.len ? "[max_ammo]" : "0"]"
|
||||
desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!"
|
||||
|
||||
/obj/item/ammo_box/proc/update_mat_value()
|
||||
var/num_ammo = 0
|
||||
for(var/B in stored_ammo)
|
||||
var/obj/item/ammo_casing/AC = B
|
||||
if(!AC.BB) //Skip any casing which are empty
|
||||
continue
|
||||
num_ammo++
|
||||
for(var/M in initial_mats) //In case we have multiple types of materials
|
||||
var/materials_per = initial_mats[M] / max_ammo
|
||||
|
||||
var/value = max(materials_per * num_ammo, 500) //Enforce a minimum of 500 units even if empty.
|
||||
materials[M] = value
|
||||
|
||||
//Behavior for magazines
|
||||
/obj/item/ammo_box/magazine/proc/ammo_count()
|
||||
return stored_ammo.len
|
||||
|
||||
/obj/item/ammo_box/magazine/proc/empty_magazine()
|
||||
var/turf_mag = get_turf(src)
|
||||
for(var/obj/item/ammo in stored_ammo)
|
||||
ammo.forceMove(turf_mag)
|
||||
stored_ammo -= ammo
|
||||
/obj/item/ammo_casing
|
||||
name = "bullet casing"
|
||||
desc = "A bullet casing."
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "s-casing"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/fire_sound = null //What sound should play when this ammo is fired
|
||||
var/drop_sound = "casingdrop" //What sound should play when this ammo hits the ground
|
||||
var/caliber = null //Which kind of guns it can be loaded into
|
||||
var/projectile_type = null //The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet
|
||||
var/pellets = 1 //Pellets for spreadshot
|
||||
var/variance = 0 //Variance for inaccuracy fundamental to the casing
|
||||
var/delay = 0 //Delay for energy weapons
|
||||
var/randomspread = 0 //Randomspread for automatics
|
||||
var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown.
|
||||
var/harmful = TRUE //pacifism check for boolet, set to FALSE if bullet is non-lethal
|
||||
|
||||
/obj/item/ammo_casing/New()
|
||||
..()
|
||||
if(projectile_type)
|
||||
BB = new projectile_type(src)
|
||||
pixel_x = rand(-10.0, 10)
|
||||
pixel_y = rand(-10.0, 10)
|
||||
dir = pick(alldirs)
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_casing/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)][BB ? "-live" : ""]"
|
||||
desc = "[initial(desc)][BB ? "" : " This one is spent."]"
|
||||
|
||||
/obj/item/ammo_casing/proc/newshot(params) //For energy weapons, shotgun shells and wands (!).
|
||||
if(!BB)
|
||||
BB = new projectile_type(src, params)
|
||||
return
|
||||
|
||||
/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
if(istype(I, /obj/item/ammo_box))
|
||||
var/obj/item/ammo_box/box = I
|
||||
if(isturf(loc))
|
||||
var/boolets = 0
|
||||
for(var/obj/item/ammo_casing/bullet in loc)
|
||||
if(box.stored_ammo.len >= box.max_ammo)
|
||||
break
|
||||
if(bullet.BB)
|
||||
if(box.give_round(bullet, 0))
|
||||
boolets++
|
||||
else
|
||||
continue
|
||||
if(boolets > 0)
|
||||
box.update_icon()
|
||||
to_chat(user, "<span class='notice'>You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.</span>")
|
||||
playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to collect anything!</span>")
|
||||
else
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
if(BB)
|
||||
if(initial(BB.name) == "bullet")
|
||||
var/tmp_label = ""
|
||||
var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label))
|
||||
if(length(label_text) > 20)
|
||||
to_chat(user, "<span class='warning''>The inscription can be at most 20 characters long.</span>")
|
||||
else
|
||||
if(label_text == "")
|
||||
to_chat(user, "<span class='notice'>You scratch the inscription off of [initial(BB)].</span>")
|
||||
BB.name = initial(BB.name)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You inscribe \"[label_text]\" into \the [initial(BB.name)].</span>")
|
||||
BB.name = "[initial(BB.name)] \"[label_text]\""
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can only inscribe a metal bullet.</span>")//because inscribing beanbags is silly
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There is no bullet in the casing to inscribe anything into.</span>")
|
||||
..()
|
||||
|
||||
//Boxes of ammo
|
||||
/obj/item/ammo_box
|
||||
name = "ammo box (generic)"
|
||||
desc = "A box of ammo?"
|
||||
icon_state = "357"
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "syringe_kit"
|
||||
materials = list(MAT_METAL = 30000)
|
||||
throwforce = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
var/list/stored_ammo = list()
|
||||
var/ammo_type = /obj/item/ammo_casing
|
||||
var/max_ammo = 7
|
||||
var/multiple_sprites = 0
|
||||
var/caliber
|
||||
var/multiload = 1
|
||||
var/list/initial_mats //For calculating refund values.
|
||||
|
||||
/obj/item/ammo_box/New()
|
||||
..()
|
||||
for(var/i in 1 to max_ammo)
|
||||
stored_ammo += new ammo_type(src)
|
||||
update_icon()
|
||||
initial_mats = materials.Copy()
|
||||
update_mat_value()
|
||||
|
||||
/obj/item/ammo_box/Destroy()
|
||||
QDEL_LIST(stored_ammo)
|
||||
stored_ammo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/ammo_box/proc/get_round(keep = 0)
|
||||
if(!stored_ammo.len)
|
||||
return null
|
||||
else
|
||||
var/b = stored_ammo[stored_ammo.len]
|
||||
stored_ammo -= b
|
||||
if(keep)
|
||||
stored_ammo.Insert(1,b)
|
||||
update_mat_value()
|
||||
return b
|
||||
|
||||
/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0)
|
||||
// Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type.
|
||||
if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type))
|
||||
return 0
|
||||
|
||||
if(stored_ammo.len < max_ammo)
|
||||
stored_ammo += R
|
||||
R.loc = src
|
||||
playsound(src, 'sound/weapons/gun_interactions/bulletinsert.ogg', 50, 1)
|
||||
update_mat_value()
|
||||
return 1
|
||||
//for accessibles magazines (e.g internal ones) when full, start replacing spent ammo
|
||||
else if(replace_spent)
|
||||
for(var/obj/item/ammo_casing/AC in stored_ammo)
|
||||
if(!AC.BB)//found a spent ammo
|
||||
stored_ammo -= AC
|
||||
AC.loc = get_turf(loc)
|
||||
|
||||
stored_ammo += R
|
||||
R.loc = src
|
||||
playsound(src, 'sound/weapons/gun_interactions/shotguninsert.ogg', 50, 1)
|
||||
update_mat_value()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/ammo_box/proc/can_load(mob/user)
|
||||
return 1
|
||||
|
||||
/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = 0, replace_spent = 0)
|
||||
var/num_loaded = 0
|
||||
if(!can_load(user))
|
||||
return
|
||||
if(istype(A, /obj/item/ammo_box))
|
||||
var/obj/item/ammo_box/AM = A
|
||||
for(var/obj/item/ammo_casing/AC in AM.stored_ammo)
|
||||
var/did_load = give_round(AC, replace_spent)
|
||||
if(did_load)
|
||||
AM.stored_ammo -= AC
|
||||
num_loaded++
|
||||
if(!multiload || !did_load)
|
||||
break
|
||||
if(istype(A, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/AC = A
|
||||
if(give_round(AC, replace_spent))
|
||||
user.drop_item()
|
||||
AC.loc = src
|
||||
num_loaded++
|
||||
if(num_loaded)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src]!</span>")
|
||||
playsound(src, 'sound/weapons/gun_interactions/shotguninsert.ogg', 50, 1)
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
|
||||
return num_loaded
|
||||
|
||||
/obj/item/ammo_box/attack_self(mob/user as mob)
|
||||
var/obj/item/ammo_casing/A = get_round()
|
||||
if(A)
|
||||
user.put_in_hands(A)
|
||||
playsound(src, 'sound/weapons/gun_interactions/remove_bullet.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove a round from \the [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_box/update_icon()
|
||||
switch(multiple_sprites)
|
||||
if(1)
|
||||
icon_state = "[initial(icon_state)]-[stored_ammo.len]"
|
||||
if(2)
|
||||
icon_state = "[initial(icon_state)]-[stored_ammo.len ? "[max_ammo]" : "0"]"
|
||||
desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!"
|
||||
|
||||
/obj/item/ammo_box/proc/update_mat_value()
|
||||
var/num_ammo = 0
|
||||
for(var/B in stored_ammo)
|
||||
var/obj/item/ammo_casing/AC = B
|
||||
if(!AC.BB) //Skip any casing which are empty
|
||||
continue
|
||||
num_ammo++
|
||||
for(var/M in initial_mats) //In case we have multiple types of materials
|
||||
var/materials_per = initial_mats[M] / max_ammo
|
||||
|
||||
var/value = max(materials_per * num_ammo, 500) //Enforce a minimum of 500 units even if empty.
|
||||
materials[M] = value
|
||||
|
||||
//Behavior for magazines
|
||||
/obj/item/ammo_box/magazine/proc/ammo_count()
|
||||
return stored_ammo.len
|
||||
|
||||
/obj/item/ammo_box/magazine/proc/empty_magazine()
|
||||
var/turf_mag = get_turf(src)
|
||||
for(var/obj/item/ammo in stored_ammo)
|
||||
ammo.forceMove(turf_mag)
|
||||
stored_ammo -= ammo
|
||||
|
||||
@@ -1,148 +1,148 @@
|
||||
/obj/item/ammo_box/a357
|
||||
name = "speed loader (.357)"
|
||||
desc = "Designed to quickly reload revolvers."
|
||||
icon_state = "357"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/c38
|
||||
name = "speed loader (.38)"
|
||||
desc = "Designed to quickly reload revolvers."
|
||||
icon_state = "38"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
max_ammo = 6
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/c9mm
|
||||
name = "ammo box (9mm)"
|
||||
icon_state = "9mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
max_ammo = 30
|
||||
|
||||
/obj/item/ammo_box/c10mm
|
||||
name = "ammo box (10mm)"
|
||||
icon_state = "10mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c10mm
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/c45
|
||||
name = "ammo box (.45)"
|
||||
icon_state = "45box"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/rubber45
|
||||
name = "ammo box (.45 rubber)"
|
||||
icon_state = "45box-r"
|
||||
ammo_type = /obj/item/ammo_casing/rubber45
|
||||
max_ammo = 16
|
||||
|
||||
/obj/item/ammo_box/a40mm
|
||||
name = "ammo box (40mm grenades)"
|
||||
icon_state = "40mm"
|
||||
ammo_type = /obj/item/ammo_casing/a40mm
|
||||
max_ammo = 4
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/a762
|
||||
name = "stripper clip (7.62mm)"
|
||||
desc = "A stripper clip."
|
||||
icon_state = "762"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
max_ammo = 5
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/n762
|
||||
name = "ammo box (7.62x38mmR)"
|
||||
icon_state = "riflebox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/n762
|
||||
max_ammo = 14
|
||||
|
||||
/obj/item/ammo_box/shotgun
|
||||
name = "Shotgun Speedloader (slug)"
|
||||
icon_state = "slugloader"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
max_ammo = 7
|
||||
materials = list(MAT_METAL=28000)
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/shotgun/buck
|
||||
name = "Shotgun Speedloader (buckshot)"
|
||||
icon_state = "buckloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/dragonsbreath
|
||||
name = "Shotgun Speedloader (dragonsbreath)"
|
||||
icon_state = "dragonsbreathloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/stun
|
||||
name = "Shotgun Speedloader (stun shells)"
|
||||
icon_state = "stunloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/beanbag
|
||||
name = "Shotgun Speedloader (beanbag shells)"
|
||||
icon_state = "beanbagloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
materials = list(MAT_METAL=1750)
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/rubbershot
|
||||
name = "Shotgun Speedloader (rubbershot shells)"
|
||||
icon_state = "rubbershotloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
|
||||
materials = list(MAT_METAL=1750)
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/tranquilizer
|
||||
name = "Shotgun Speedloader (tranquilizer darts)"
|
||||
icon_state = "tranqloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/tranquilizer
|
||||
materials = list(MAT_METAL=1750)
|
||||
|
||||
|
||||
//FOAM DARTS
|
||||
/obj/item/ammo_box/foambox
|
||||
name = "ammo box (Foam Darts)"
|
||||
icon = 'icons/obj/guns/toy.dmi'
|
||||
icon_state = "foambox"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
|
||||
max_ammo = 40
|
||||
materials = list(MAT_METAL = 500)
|
||||
|
||||
/obj/item/ammo_box/foambox/riot
|
||||
icon_state = "foambox_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
materials = list(MAT_METAL = 50000)
|
||||
|
||||
/obj/item/ammo_box/foambox/sniper
|
||||
name = "ammo box (Foam Sniper Darts)"
|
||||
icon = 'icons/obj/guns/toy.dmi'
|
||||
icon_state = "foambox_sniper"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/sniper
|
||||
max_ammo = 40
|
||||
materials = list(MAT_METAL = 900)
|
||||
|
||||
/obj/item/ammo_box/foambox/sniper/riot
|
||||
icon_state = "foambox_sniper_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/sniper/riot
|
||||
materials = list(MAT_METAL = 90000)
|
||||
|
||||
|
||||
|
||||
/obj/item/ammo_box/caps
|
||||
name = "speed loader (caps)"
|
||||
icon_state = "357"
|
||||
ammo_type = /obj/item/ammo_casing/cap
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
/obj/item/ammo_box/a357
|
||||
name = "speed loader (.357)"
|
||||
desc = "Designed to quickly reload revolvers."
|
||||
icon_state = "357"
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/c38
|
||||
name = "speed loader (.38)"
|
||||
desc = "Designed to quickly reload revolvers."
|
||||
icon_state = "38"
|
||||
ammo_type = /obj/item/ammo_casing/c38
|
||||
max_ammo = 6
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/c9mm
|
||||
name = "ammo box (9mm)"
|
||||
icon_state = "9mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
max_ammo = 30
|
||||
|
||||
/obj/item/ammo_box/c10mm
|
||||
name = "ammo box (10mm)"
|
||||
icon_state = "10mmbox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c10mm
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/c45
|
||||
name = "ammo box (.45)"
|
||||
icon_state = "45box"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/c45
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/rubber45
|
||||
name = "ammo box (.45 rubber)"
|
||||
icon_state = "45box-r"
|
||||
ammo_type = /obj/item/ammo_casing/rubber45
|
||||
max_ammo = 16
|
||||
|
||||
/obj/item/ammo_box/a40mm
|
||||
name = "ammo box (40mm grenades)"
|
||||
icon_state = "40mm"
|
||||
ammo_type = /obj/item/ammo_casing/a40mm
|
||||
max_ammo = 4
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/a762
|
||||
name = "stripper clip (7.62mm)"
|
||||
desc = "A stripper clip."
|
||||
icon_state = "762"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
max_ammo = 5
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/n762
|
||||
name = "ammo box (7.62x38mmR)"
|
||||
icon_state = "riflebox"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/n762
|
||||
max_ammo = 14
|
||||
|
||||
/obj/item/ammo_box/shotgun
|
||||
name = "Shotgun Speedloader (slug)"
|
||||
icon_state = "slugloader"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
max_ammo = 7
|
||||
materials = list(MAT_METAL=28000)
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_box/shotgun/buck
|
||||
name = "Shotgun Speedloader (buckshot)"
|
||||
icon_state = "buckloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/dragonsbreath
|
||||
name = "Shotgun Speedloader (dragonsbreath)"
|
||||
icon_state = "dragonsbreathloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/stun
|
||||
name = "Shotgun Speedloader (stun shells)"
|
||||
icon_state = "stunloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/beanbag
|
||||
name = "Shotgun Speedloader (beanbag shells)"
|
||||
icon_state = "beanbagloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
materials = list(MAT_METAL=1750)
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/rubbershot
|
||||
name = "Shotgun Speedloader (rubbershot shells)"
|
||||
icon_state = "rubbershotloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
|
||||
materials = list(MAT_METAL=1750)
|
||||
|
||||
|
||||
/obj/item/ammo_box/shotgun/tranquilizer
|
||||
name = "Shotgun Speedloader (tranquilizer darts)"
|
||||
icon_state = "tranqloader"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/tranquilizer
|
||||
materials = list(MAT_METAL=1750)
|
||||
|
||||
|
||||
//FOAM DARTS
|
||||
/obj/item/ammo_box/foambox
|
||||
name = "ammo box (Foam Darts)"
|
||||
icon = 'icons/obj/guns/toy.dmi'
|
||||
icon_state = "foambox"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
|
||||
max_ammo = 40
|
||||
materials = list(MAT_METAL = 500)
|
||||
|
||||
/obj/item/ammo_box/foambox/riot
|
||||
icon_state = "foambox_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
materials = list(MAT_METAL = 50000)
|
||||
|
||||
/obj/item/ammo_box/foambox/sniper
|
||||
name = "ammo box (Foam Sniper Darts)"
|
||||
icon = 'icons/obj/guns/toy.dmi'
|
||||
icon_state = "foambox_sniper"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/sniper
|
||||
max_ammo = 40
|
||||
materials = list(MAT_METAL = 900)
|
||||
|
||||
/obj/item/ammo_box/foambox/sniper/riot
|
||||
icon_state = "foambox_sniper_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/sniper/riot
|
||||
materials = list(MAT_METAL = 90000)
|
||||
|
||||
|
||||
|
||||
/obj/item/ammo_box/caps
|
||||
name = "speed loader (caps)"
|
||||
icon_state = "357"
|
||||
ammo_type = /obj/item/ammo_casing/cap
|
||||
max_ammo = 7
|
||||
multiple_sprites = 1
|
||||
|
||||
@@ -157,6 +157,8 @@
|
||||
multiload = 0
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/rus357/New()
|
||||
..()
|
||||
stored_ammo.Cut() // We only want 1 bullet in there
|
||||
stored_ammo += new ammo_type(src)
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/boltaction
|
||||
@@ -504,4 +506,4 @@
|
||||
icon_state = "c20r45-[round(ammo_count(),2)]"
|
||||
|
||||
/obj/item/ammo_box/magazine/toy/smgm45/riot
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
|
||||
|
||||
+524
-521
File diff suppressed because it is too large
Load Diff
@@ -1,212 +1,220 @@
|
||||
/obj/item/gun/energy
|
||||
icon_state = "energy"
|
||||
name = "energy gun"
|
||||
desc = "A basic energy-based gun."
|
||||
icon = 'icons/obj/guns/energy.dmi'
|
||||
fire_sound_text = "laser blast"
|
||||
|
||||
var/obj/item/stock_parts/cell/cell //What type of power cell this uses
|
||||
var/cell_type = /obj/item/stock_parts/cell
|
||||
var/modifystate = 0
|
||||
var/list/ammo_type = list(/obj/item/ammo_casing/energy)
|
||||
var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next.
|
||||
var/can_charge = 1
|
||||
var/charge_sections = 4
|
||||
ammo_x_offset = 2
|
||||
var/shaded_charge = 0 //if this gun uses a stateful charge bar for more detail
|
||||
var/selfcharge = 0
|
||||
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
|
||||
var/charge_tick = 0
|
||||
var/charge_delay = 4
|
||||
|
||||
/obj/item/gun/energy/emp_act(severity)
|
||||
cell.use(round(cell.charge / severity))
|
||||
if(chambered)//phil235
|
||||
if(chambered.BB)
|
||||
qdel(chambered.BB)
|
||||
chambered.BB = null
|
||||
chambered = null
|
||||
newshot() //phil235
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/item/gun/energy/New()
|
||||
..()
|
||||
if(cell_type)
|
||||
cell = new cell_type(src)
|
||||
else
|
||||
cell = new(src)
|
||||
cell.give(cell.maxcharge)
|
||||
update_ammo_types()
|
||||
on_recharge()
|
||||
if(selfcharge)
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/proc/update_ammo_types()
|
||||
var/obj/item/ammo_casing/energy/shot
|
||||
for(var/i = 1, i <= ammo_type.len, i++)
|
||||
var/shottype = ammo_type[i]
|
||||
shot = new shottype(src)
|
||||
ammo_type[i] = shot
|
||||
shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
|
||||
/obj/item/gun/energy/Destroy()
|
||||
if(selfcharge)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/process()
|
||||
if(selfcharge) //Every [recharge_time] ticks, recharge a shot for the cyborg
|
||||
charge_tick++
|
||||
if(charge_tick < charge_delay)
|
||||
return
|
||||
charge_tick = 0
|
||||
if(!cell)
|
||||
return // check if we actually need to recharge
|
||||
var/obj/item/ammo_casing/energy/E = ammo_type[select]
|
||||
if(use_external_power)
|
||||
var/obj/item/stock_parts/cell/external = get_external_cell()
|
||||
if(!external || !external.use(E.e_cost)) //Take power from the borg...
|
||||
return //Note, uses /10 because of shitty mods to the cell system
|
||||
cell.give(100) //... to recharge the shot
|
||||
on_recharge()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/proc/on_recharge()
|
||||
newshot()
|
||||
|
||||
/obj/item/gun/energy/attack_self(mob/living/user as mob)
|
||||
if(ammo_type.len > 1)
|
||||
select_fire(user)
|
||||
update_icon()
|
||||
if(istype(user,/mob/living/carbon/human)) //This has to be here or else if you toggle modes by clicking the gun in hand
|
||||
var/mob/living/carbon/human/H = user //Otherwise the mob icon doesn't update, blame shitty human update_icons() code
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
|
||||
/obj/item/gun/energy/can_shoot()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
return cell.charge >= shot.e_cost
|
||||
|
||||
/obj/item/gun/energy/newshot()
|
||||
if(!ammo_type || !cell)
|
||||
return
|
||||
if(!chambered)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
if(cell.charge >= shot.e_cost) //if there's enough power in the cell cell...
|
||||
chambered = shot //...prepare a new shot based on the current ammo type selected
|
||||
if(!chambered.BB)
|
||||
chambered.newshot()
|
||||
|
||||
/obj/item/gun/energy/process_chamber()
|
||||
if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired...
|
||||
var/obj/item/ammo_casing/energy/shot = chambered
|
||||
cell.use(shot.e_cost)//... drain the cell cell
|
||||
robocharge()
|
||||
chambered = null //either way, released the prepared shot
|
||||
newshot()
|
||||
|
||||
/obj/item/gun/energy/proc/select_fire(mob/living/user)
|
||||
select++
|
||||
if(select > ammo_type.len)
|
||||
select = 1
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
if(shot.select_name)
|
||||
to_chat(user, "<span class='notice'>[src] is now set to [shot.select_name].</span>")
|
||||
if(chambered)//phil235
|
||||
if(chambered.BB)
|
||||
qdel(chambered.BB)
|
||||
chambered.BB = null
|
||||
chambered = null
|
||||
newshot()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/update_icon()
|
||||
overlays.Cut()
|
||||
var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/iconState = "[icon_state]_charge"
|
||||
var/itemState = null
|
||||
if(!initial(item_state))
|
||||
itemState = icon_state
|
||||
if(modifystate)
|
||||
overlays += "[icon_state]_[shot.select_name]"
|
||||
iconState += "_[shot.select_name]"
|
||||
if(itemState)
|
||||
itemState += "[shot.select_name]"
|
||||
if(cell.charge < shot.e_cost)
|
||||
overlays += "[icon_state]_empty"
|
||||
else
|
||||
if(!shaded_charge)
|
||||
for(var/i = ratio, i >= 1, i--)
|
||||
overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1))
|
||||
else
|
||||
overlays += image(icon = icon, icon_state = "[icon_state]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]")
|
||||
if(gun_light && can_flashlight)
|
||||
var/iconF = "flight"
|
||||
if(gun_light.on)
|
||||
iconF = "flight_on"
|
||||
overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)
|
||||
if(bayonet && can_bayonet)
|
||||
overlays += knife_overlay
|
||||
if(itemState)
|
||||
itemState += "[ratio]"
|
||||
item_state = itemState
|
||||
|
||||
/obj/item/gun/energy/ui_action_click()
|
||||
toggle_gunlight()
|
||||
|
||||
/obj/item/gun/energy/suicide_act(mob/user)
|
||||
if(can_shoot())
|
||||
user.visible_message("<span class='suicide'>[user] is putting the barrel of the [name] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
sleep(25)
|
||||
if(user.l_hand == src || user.r_hand == src)
|
||||
user.visible_message("<span class='suicide'>[user] melts [user.p_their()] face off with the [name]!</span>")
|
||||
playsound(loc, fire_sound, 50, 1, -1)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
cell.use(shot.e_cost)
|
||||
update_icon()
|
||||
return FIRELOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return OXYLOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!</b></span>")
|
||||
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
|
||||
return OXYLOSS
|
||||
|
||||
/obj/item/gun/energy/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("selfcharge")
|
||||
if(var_value)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/energy/proc/robocharge()
|
||||
if(isrobot(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
if(R && R.cell)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot
|
||||
if(R.cell.use(shot.e_cost)) //Take power from the borg...
|
||||
cell.give(shot.e_cost) //... to recharge the shot
|
||||
|
||||
/obj/item/gun/energy/proc/get_external_cell()
|
||||
if(istype(loc, /obj/item/rig_module))
|
||||
var/obj/item/rig_module/module = loc
|
||||
if(module.holder && module.holder.wearer)
|
||||
var/mob/living/carbon/human/H = module.holder.wearer
|
||||
if(istype(H) && H.back)
|
||||
var/obj/item/rig/suit = H.back
|
||||
if(istype(suit))
|
||||
return suit.cell
|
||||
return null
|
||||
/obj/item/gun/energy
|
||||
icon_state = "energy"
|
||||
name = "energy gun"
|
||||
desc = "A basic energy-based gun."
|
||||
icon = 'icons/obj/guns/energy.dmi'
|
||||
fire_sound_text = "laser blast"
|
||||
|
||||
var/obj/item/stock_parts/cell/cell //What type of power cell this uses
|
||||
var/cell_type = /obj/item/stock_parts/cell
|
||||
var/modifystate = 0
|
||||
var/list/ammo_type = list(/obj/item/ammo_casing/energy)
|
||||
var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next.
|
||||
var/can_charge = 1
|
||||
var/charge_sections = 4
|
||||
ammo_x_offset = 2
|
||||
var/shaded_charge = 0 //if this gun uses a stateful charge bar for more detail
|
||||
var/selfcharge = 0
|
||||
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
|
||||
var/charge_tick = 0
|
||||
var/charge_delay = 4
|
||||
|
||||
/obj/item/gun/energy/emp_act(severity)
|
||||
cell.use(round(cell.charge / severity))
|
||||
if(chambered)//phil235
|
||||
if(chambered.BB)
|
||||
qdel(chambered.BB)
|
||||
chambered.BB = null
|
||||
chambered = null
|
||||
newshot() //phil235
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/item/gun/energy/New()
|
||||
..()
|
||||
if(cell_type)
|
||||
cell = new cell_type(src)
|
||||
else
|
||||
cell = new(src)
|
||||
cell.give(cell.maxcharge)
|
||||
update_ammo_types()
|
||||
on_recharge()
|
||||
if(selfcharge)
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/proc/update_ammo_types()
|
||||
var/obj/item/ammo_casing/energy/shot
|
||||
for(var/i = 1, i <= ammo_type.len, i++)
|
||||
var/shottype = ammo_type[i]
|
||||
shot = new shottype(src)
|
||||
ammo_type[i] = shot
|
||||
shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
|
||||
/obj/item/gun/energy/Destroy()
|
||||
if(selfcharge)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/process()
|
||||
if(selfcharge) //Every [recharge_time] ticks, recharge a shot for the cyborg
|
||||
charge_tick++
|
||||
if(charge_tick < charge_delay)
|
||||
return
|
||||
charge_tick = 0
|
||||
if(!cell)
|
||||
return // check if we actually need to recharge
|
||||
var/obj/item/ammo_casing/energy/E = ammo_type[select]
|
||||
if(use_external_power)
|
||||
var/obj/item/stock_parts/cell/external = get_external_cell()
|
||||
if(!external || !external.use(E.e_cost)) //Take power from the borg...
|
||||
return //Note, uses /10 because of shitty mods to the cell system
|
||||
cell.give(100) //... to recharge the shot
|
||||
on_recharge()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/proc/on_recharge()
|
||||
newshot()
|
||||
|
||||
/obj/item/gun/energy/attack_self(mob/living/user as mob)
|
||||
if(ammo_type.len > 1)
|
||||
select_fire(user)
|
||||
update_icon()
|
||||
if(istype(user,/mob/living/carbon/human)) //This has to be here or else if you toggle modes by clicking the gun in hand
|
||||
var/mob/living/carbon/human/H = user //Otherwise the mob icon doesn't update, blame shitty human update_icons() code
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
|
||||
/obj/item/gun/energy/can_shoot()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
return cell.charge >= shot.e_cost
|
||||
|
||||
/obj/item/gun/energy/newshot()
|
||||
if(!ammo_type || !cell)
|
||||
return
|
||||
if(!chambered)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
if(cell.charge >= shot.e_cost) //if there's enough power in the WEAPON'S cell...
|
||||
chambered = shot //...prepare a new shot based on the current ammo type selected
|
||||
if(!chambered.BB)
|
||||
chambered.newshot()
|
||||
|
||||
/obj/item/gun/energy/process_chamber()
|
||||
if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired...
|
||||
var/obj/item/ammo_casing/energy/shot = chambered
|
||||
cell.use(shot.e_cost)//... drain the cell cell
|
||||
robocharge()
|
||||
chambered = null //either way, released the prepared shot
|
||||
newshot()
|
||||
|
||||
/obj/item/gun/energy/process_fire(atom/target, mob/living/user, message = 1, params, zone_override, bonus_spread = 0)
|
||||
if(!chambered && can_shoot())
|
||||
process_chamber()
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/proc/select_fire(mob/living/user)
|
||||
select++
|
||||
if(select > ammo_type.len)
|
||||
select = 1
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
if(shot.select_name)
|
||||
to_chat(user, "<span class='notice'>[src] is now set to [shot.select_name].</span>")
|
||||
if(chambered)//phil235
|
||||
if(chambered.BB)
|
||||
qdel(chambered.BB)
|
||||
chambered.BB = null
|
||||
chambered = null
|
||||
newshot()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/update_icon()
|
||||
overlays.Cut()
|
||||
var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/iconState = "[icon_state]_charge"
|
||||
var/itemState = null
|
||||
if(!initial(item_state))
|
||||
itemState = icon_state
|
||||
if(modifystate)
|
||||
overlays += "[icon_state]_[shot.select_name]"
|
||||
iconState += "_[shot.select_name]"
|
||||
if(itemState)
|
||||
itemState += "[shot.select_name]"
|
||||
if(cell.charge < shot.e_cost)
|
||||
overlays += "[icon_state]_empty"
|
||||
else
|
||||
if(!shaded_charge)
|
||||
for(var/i = ratio, i >= 1, i--)
|
||||
overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1))
|
||||
else
|
||||
overlays += image(icon = icon, icon_state = "[icon_state]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]")
|
||||
if(gun_light && can_flashlight)
|
||||
var/iconF = "flight"
|
||||
if(gun_light.on)
|
||||
iconF = "flight_on"
|
||||
overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)
|
||||
if(bayonet && can_bayonet)
|
||||
overlays += knife_overlay
|
||||
if(itemState)
|
||||
itemState += "[ratio]"
|
||||
item_state = itemState
|
||||
|
||||
/obj/item/gun/energy/ui_action_click()
|
||||
toggle_gunlight()
|
||||
|
||||
/obj/item/gun/energy/suicide_act(mob/user)
|
||||
if(can_shoot())
|
||||
user.visible_message("<span class='suicide'>[user] is putting the barrel of the [name] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
sleep(25)
|
||||
if(user.l_hand == src || user.r_hand == src)
|
||||
user.visible_message("<span class='suicide'>[user] melts [user.p_their()] face off with the [name]!</span>")
|
||||
playsound(loc, fire_sound, 50, 1, -1)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
cell.use(shot.e_cost)
|
||||
update_icon()
|
||||
return FIRELOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return OXYLOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!</b></span>")
|
||||
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
|
||||
return OXYLOSS
|
||||
|
||||
/obj/item/gun/energy/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("selfcharge")
|
||||
if(var_value)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/energy/proc/robocharge()
|
||||
if(cell.charge == cell.maxcharge)
|
||||
// No point in recharging a weapon's cell that is already at 100%. That would just waste borg cell power for no reason.
|
||||
return
|
||||
if(isrobot(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
if(R && R.cell)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot
|
||||
if(R.cell.use(shot.e_cost)) //Take power from the borg...
|
||||
cell.give(shot.e_cost) //... to recharge the shot
|
||||
|
||||
/obj/item/gun/energy/proc/get_external_cell()
|
||||
if(istype(loc, /obj/item/rig_module))
|
||||
var/obj/item/rig_module/module = loc
|
||||
if(module.holder && module.holder.wearer)
|
||||
var/mob/living/carbon/human/H = module.holder.wearer
|
||||
if(istype(H) && H.back)
|
||||
var/obj/item/rig/suit = H.back
|
||||
if(istype(suit))
|
||||
return suit.cell
|
||||
return null
|
||||
|
||||
@@ -37,20 +37,23 @@
|
||||
. += "<span class='notice'>There is a [M.name] mod installed, using <b>[M.cost]%</b> capacity.</span>"
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user)
|
||||
if(iscrowbar(I))
|
||||
if(modkits.len)
|
||||
to_chat(user, "<span class='notice'>You pry the modifications out.</span>")
|
||||
playsound(loc, I.usesound, 100, 1)
|
||||
for(var/obj/item/borg/upgrade/modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no modifications currently installed.</span>")
|
||||
else if(istype(I, /obj/item/borg/upgrade/modkit))
|
||||
if(istype(I, /obj/item/borg/upgrade/modkit))
|
||||
var/obj/item/borg/upgrade/modkit/MK = I
|
||||
MK.install(src, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/crowbar_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!modkits.len)
|
||||
to_chat(user, "<span class='notice'>There are no modifications currently installed.</span>")
|
||||
return
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You pry the modifications out.</span>")
|
||||
for(var/obj/item/borg/upgrade/modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity()
|
||||
var/current_capacity_used = 0
|
||||
for(var/A in get_modkits())
|
||||
@@ -596,4 +599,4 @@
|
||||
desc = "Causes kinetic accelerator bolts to have an adjustable-colored tracer trail and explosion. Use in-hand to change color."
|
||||
|
||||
/obj/item/borg/upgrade/modkit/tracer/adjustable/attack_self(mob/user)
|
||||
bolt_color = input(user,"","Choose Color",bolt_color) as color|null
|
||||
bolt_color = input(user,"","Choose Color",bolt_color) as color|null
|
||||
|
||||
@@ -1,159 +1,159 @@
|
||||
/obj/item/gun/energy/laser
|
||||
name = "laser gun"
|
||||
desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal."
|
||||
icon_state = "laser"
|
||||
item_state = "laser"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
materials = list(MAT_METAL=2000)
|
||||
origin_tech = "combat=4;magnets=2"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/lasergun)
|
||||
ammo_x_offset = 1
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/laser/practice
|
||||
name = "practice laser gun"
|
||||
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
|
||||
origin_tech = "combat=2;magnets=2"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/practice)
|
||||
clumsy_check = 0
|
||||
needs_permit = 0
|
||||
|
||||
/obj/item/gun/energy/laser/retro
|
||||
name ="retro laser gun"
|
||||
icon_state = "retro"
|
||||
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's private security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws."
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/laser/captain
|
||||
name = "antique laser gun"
|
||||
icon_state = "caplaser"
|
||||
item_state = "caplaser"
|
||||
desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding."
|
||||
force = 10
|
||||
origin_tech = null
|
||||
ammo_x_offset = 3
|
||||
selfcharge = 1
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/gun/energy/laser/captain/scattershot
|
||||
name = "scatter shot laser rifle"
|
||||
icon_state = "lasercannon"
|
||||
item_state = "laser"
|
||||
desc = "An industrial-grade heavy-duty laser rifle with a modified laser lense to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theorically infinite use."
|
||||
origin_tech = "combat=5;materials=4;powerstorage=4"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser)
|
||||
shaded_charge = 0
|
||||
|
||||
/obj/item/gun/energy/laser/cyborg
|
||||
can_charge = 0
|
||||
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/cyborg)
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/gun/energy/laser/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/laser/cyborg/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/laser/scatter
|
||||
name = "scatter laser gun"
|
||||
desc = "A laser gun equipped with a refraction kit that spreads bolts."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser)
|
||||
|
||||
///Laser Cannon
|
||||
|
||||
/obj/item/gun/energy/lasercannon
|
||||
name = "accelerator laser cannon"
|
||||
desc = "An advanced laser cannon that does more damage the farther away the target is."
|
||||
icon_state = "lasercannon"
|
||||
item_state = "laser"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/lasercannon/isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/accelerator
|
||||
projectile_type = /obj/item/projectile/beam/laser/accelerator
|
||||
select_name = "accelerator"
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
|
||||
/obj/item/projectile/beam/laser/accelerator
|
||||
name = "accelerator laser"
|
||||
icon_state = "heavylaser"
|
||||
range = 255
|
||||
damage = 6
|
||||
|
||||
/obj/item/projectile/beam/laser/accelerator/Range()
|
||||
..()
|
||||
damage = min(damage+7, 100)
|
||||
|
||||
/obj/item/gun/energy/lasercannon/mounted
|
||||
name = "mounted laser cannon"
|
||||
selfcharge = 1
|
||||
use_external_power = 1
|
||||
charge_delay = 10
|
||||
|
||||
/obj/item/gun/energy/lasercannon/cyborg
|
||||
|
||||
/obj/item/gun/energy/lasercannon/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/lasercannon/cyborg/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/xray
|
||||
name = "xray laser gun"
|
||||
desc = "A high-power laser gun capable of expelling concentrated xray blasts. These blasts will penetrate solid objects, but will decrease in power the longer they have to travel."
|
||||
icon_state = "xray"
|
||||
origin_tech = "combat=6;materials=4;magnets=4;syndicate=1"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/xray)
|
||||
|
||||
/obj/item/gun/energy/immolator
|
||||
name = "Immolator laser gun"
|
||||
desc = "A modified laser gun, shooting highly concetrated beams with higher intensity that ignites the target, for the cost of draining more power per shot"
|
||||
icon_state = "immolator"
|
||||
item_state = "laser"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/immolator)
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=3"
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/immolator/multi
|
||||
name = "multi lens immolator cannon"
|
||||
desc = "A large laser cannon, similar to the Immolator Laser, with toggleable firemodes. It is frequently used by military-like forces through Nanotrasen."
|
||||
icon_state = "multilensimmolator"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/immolator/strong, /obj/item/ammo_casing/energy/immolator/scatter)
|
||||
origin_tech = "combat=5;magnets=5;powerstorage=4"
|
||||
|
||||
/obj/item/gun/energy/immolator/multi/update_icon()
|
||||
..()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/append = shot.select_name
|
||||
overlays += image(icon = icon, icon_state = "multilensimmolator-[append]")
|
||||
|
||||
////////Laser Tag////////////////////
|
||||
|
||||
/obj/item/gun/energy/laser/tag
|
||||
name = "laser tag gun"
|
||||
desc = "Standard issue weapon of the Imperial Guard"
|
||||
origin_tech = "combat=2;magnets=2"
|
||||
clumsy_check = 0
|
||||
needs_permit = 0
|
||||
ammo_x_offset = 2
|
||||
selfcharge = 1
|
||||
|
||||
/obj/item/gun/energy/laser/tag/blue
|
||||
icon_state = "bluetag"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag)
|
||||
|
||||
/obj/item/gun/energy/laser/tag/red
|
||||
icon_state = "redtag"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag)
|
||||
/obj/item/gun/energy/laser
|
||||
name = "laser gun"
|
||||
desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal."
|
||||
icon_state = "laser"
|
||||
item_state = "laser"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
materials = list(MAT_METAL=2000)
|
||||
origin_tech = "combat=4;magnets=2"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/lasergun)
|
||||
ammo_x_offset = 1
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/laser/practice
|
||||
name = "practice laser gun"
|
||||
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
|
||||
origin_tech = "combat=2;magnets=2"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/practice)
|
||||
clumsy_check = 0
|
||||
needs_permit = 0
|
||||
|
||||
/obj/item/gun/energy/laser/retro
|
||||
name ="retro laser gun"
|
||||
icon_state = "retro"
|
||||
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's private security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws."
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/laser/captain
|
||||
name = "antique laser gun"
|
||||
icon_state = "caplaser"
|
||||
item_state = "caplaser"
|
||||
desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding."
|
||||
force = 10
|
||||
origin_tech = null
|
||||
ammo_x_offset = 3
|
||||
selfcharge = 1
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/gun/energy/laser/captain/scattershot
|
||||
name = "scatter shot laser rifle"
|
||||
icon_state = "lasercannon"
|
||||
item_state = "laser"
|
||||
desc = "An industrial-grade heavy-duty laser rifle with a modified laser lense to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theorically infinite use."
|
||||
origin_tech = "combat=5;materials=4;powerstorage=4"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser)
|
||||
shaded_charge = 0
|
||||
|
||||
/obj/item/gun/energy/laser/cyborg
|
||||
can_charge = 0
|
||||
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/cyborg)
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/gun/energy/laser/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/laser/cyborg/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/laser/scatter
|
||||
name = "scatter laser gun"
|
||||
desc = "A laser gun equipped with a refraction kit that spreads bolts."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser)
|
||||
|
||||
///Laser Cannon
|
||||
|
||||
/obj/item/gun/energy/lasercannon
|
||||
name = "accelerator laser cannon"
|
||||
desc = "An advanced laser cannon that does more damage the farther away the target is."
|
||||
icon_state = "lasercannon"
|
||||
item_state = "laser"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/lasercannon/isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/accelerator
|
||||
projectile_type = /obj/item/projectile/beam/laser/accelerator
|
||||
select_name = "accelerator"
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
|
||||
/obj/item/projectile/beam/laser/accelerator
|
||||
name = "accelerator laser"
|
||||
icon_state = "heavylaser"
|
||||
range = 255
|
||||
damage = 6
|
||||
|
||||
/obj/item/projectile/beam/laser/accelerator/Range()
|
||||
..()
|
||||
damage = min(damage+7, 100)
|
||||
|
||||
/obj/item/gun/energy/lasercannon/mounted
|
||||
name = "mounted laser cannon"
|
||||
selfcharge = 1
|
||||
use_external_power = 1
|
||||
charge_delay = 10
|
||||
|
||||
/obj/item/gun/energy/lasercannon/cyborg
|
||||
|
||||
/obj/item/gun/energy/lasercannon/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/lasercannon/cyborg/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/xray
|
||||
name = "xray laser gun"
|
||||
desc = "A high-power laser gun capable of expelling concentrated xray blasts. These blasts will penetrate solid objects, but will decrease in power the longer they have to travel."
|
||||
icon_state = "xray"
|
||||
origin_tech = "combat=6;materials=4;magnets=4;syndicate=1"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/xray)
|
||||
|
||||
/obj/item/gun/energy/immolator
|
||||
name = "Immolator laser gun"
|
||||
desc = "A modified laser gun, shooting highly concetrated beams with higher intensity that ignites the target, for the cost of draining more power per shot"
|
||||
icon_state = "immolator"
|
||||
item_state = "laser"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/immolator)
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=3"
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/immolator/multi
|
||||
name = "multi lens immolator cannon"
|
||||
desc = "A large laser cannon, similar to the Immolator Laser, with toggleable firemodes. It is frequently used by military-like forces through Nanotrasen."
|
||||
icon_state = "multilensimmolator"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/immolator/strong, /obj/item/ammo_casing/energy/immolator/scatter)
|
||||
origin_tech = "combat=5;magnets=5;powerstorage=4"
|
||||
|
||||
/obj/item/gun/energy/immolator/multi/update_icon()
|
||||
..()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/append = shot.select_name
|
||||
overlays += image(icon = icon, icon_state = "multilensimmolator-[append]")
|
||||
|
||||
////////Laser Tag////////////////////
|
||||
|
||||
/obj/item/gun/energy/laser/tag
|
||||
name = "laser tag gun"
|
||||
desc = "Standard issue weapon of the Imperial Guard"
|
||||
origin_tech = "combat=2;magnets=2"
|
||||
clumsy_check = 0
|
||||
needs_permit = 0
|
||||
ammo_x_offset = 2
|
||||
selfcharge = 1
|
||||
|
||||
/obj/item/gun/energy/laser/tag/blue
|
||||
icon_state = "bluetag"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag)
|
||||
|
||||
/obj/item/gun/energy/laser/tag/red
|
||||
icon_state = "redtag"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag)
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
/obj/item/gun/energy/gun
|
||||
name = "energy gun"
|
||||
desc = "A basic energy-based gun with two settings: kill and disable."
|
||||
icon_state = "energy"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
|
||||
origin_tech = "combat=4;magnets=3"
|
||||
modifystate = 2
|
||||
can_flashlight = 1
|
||||
ammo_x_offset = 3
|
||||
flight_x_offset = 15
|
||||
flight_y_offset = 10
|
||||
|
||||
/obj/item/gun/energy/gun/cyborg
|
||||
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
|
||||
|
||||
/obj/item/gun/energy/gun/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/gun/cyborg/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/gun/mounted
|
||||
name = "mounted energy gun"
|
||||
selfcharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/gun/energy/gun/mini
|
||||
name = "miniature energy gun"
|
||||
desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: disable and kill."
|
||||
icon_state = "mini"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
ammo_x_offset = 2
|
||||
charge_sections = 3
|
||||
can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update
|
||||
actions_types = list(/datum/action/item_action/toggle_gunlight)
|
||||
|
||||
/obj/item/gun/energy/gun/mini/New()
|
||||
gun_light = new /obj/item/flashlight/seclite(src)
|
||||
..()
|
||||
cell.maxcharge = 600
|
||||
cell.charge = 600
|
||||
|
||||
/obj/item/gun/energy/gun/mini/update_icon()
|
||||
..()
|
||||
if(gun_light && gun_light.on)
|
||||
overlays += "mini-light"
|
||||
|
||||
/obj/item/gun/energy/gun/hos
|
||||
name = "\improper X-01 MultiPhase Energy Gun"
|
||||
desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time."
|
||||
icon_state = "hoslaser"
|
||||
origin_tech = null
|
||||
force = 10
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler)
|
||||
ammo_x_offset = 4
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/gun/energy/gun/blueshield
|
||||
name = "advanced stun revolver"
|
||||
desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers."
|
||||
icon_state = "bsgun"
|
||||
item_state = "gun"
|
||||
force = 7
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos)
|
||||
ammo_x_offset = 1
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/gun/blueshield/pdw9
|
||||
name = "PDW-9 taser pistol"
|
||||
desc = "A military grade sidearm, used by many militia forces throughout the local sector."
|
||||
icon_state = "pdw9pistol"
|
||||
|
||||
/obj/item/gun/energy/gun/turret
|
||||
name = "hybrid turret gun"
|
||||
desc = "A heavy hybrid energy cannon with two settings: Stun and kill."
|
||||
icon_state = "turretlaser"
|
||||
item_state = "turretlaser"
|
||||
slot_flags = null
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
can_flashlight = 0
|
||||
trigger_guard = TRIGGER_GUARD_NONE
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/gun/energy/gun/nuclear
|
||||
name = "advanced energy gun"
|
||||
desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell."
|
||||
icon_state = "nucgun"
|
||||
item_state = "nucgun"
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=4"
|
||||
var/fail_tick = 0
|
||||
charge_delay = 5
|
||||
can_charge = 0
|
||||
ammo_x_offset = 1
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler)
|
||||
selfcharge = 1
|
||||
/obj/item/gun/energy/gun
|
||||
name = "energy gun"
|
||||
desc = "A basic energy-based gun with two settings: kill and disable."
|
||||
icon_state = "energy"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
|
||||
origin_tech = "combat=4;magnets=3"
|
||||
modifystate = 2
|
||||
can_flashlight = 1
|
||||
ammo_x_offset = 3
|
||||
flight_x_offset = 15
|
||||
flight_y_offset = 10
|
||||
|
||||
/obj/item/gun/energy/gun/cyborg
|
||||
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
|
||||
|
||||
/obj/item/gun/energy/gun/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/gun/cyborg/emp_act()
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/gun/mounted
|
||||
name = "mounted energy gun"
|
||||
selfcharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/gun/energy/gun/mini
|
||||
name = "miniature energy gun"
|
||||
desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: disable and kill."
|
||||
icon_state = "mini"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
ammo_x_offset = 2
|
||||
charge_sections = 3
|
||||
can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update
|
||||
actions_types = list(/datum/action/item_action/toggle_gunlight)
|
||||
|
||||
/obj/item/gun/energy/gun/mini/New()
|
||||
gun_light = new /obj/item/flashlight/seclite(src)
|
||||
..()
|
||||
cell.maxcharge = 600
|
||||
cell.charge = 600
|
||||
|
||||
/obj/item/gun/energy/gun/mini/update_icon()
|
||||
..()
|
||||
if(gun_light && gun_light.on)
|
||||
overlays += "mini-light"
|
||||
|
||||
/obj/item/gun/energy/gun/hos
|
||||
name = "\improper X-01 MultiPhase Energy Gun"
|
||||
desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time."
|
||||
icon_state = "hoslaser"
|
||||
origin_tech = null
|
||||
force = 10
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler)
|
||||
ammo_x_offset = 4
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/gun/energy/gun/blueshield
|
||||
name = "advanced stun revolver"
|
||||
desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers."
|
||||
icon_state = "bsgun"
|
||||
item_state = "gun"
|
||||
force = 7
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos)
|
||||
ammo_x_offset = 1
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/gun/blueshield/pdw9
|
||||
name = "PDW-9 taser pistol"
|
||||
desc = "A military grade sidearm, used by many militia forces throughout the local sector."
|
||||
icon_state = "pdw9pistol"
|
||||
|
||||
/obj/item/gun/energy/gun/turret
|
||||
name = "hybrid turret gun"
|
||||
desc = "A heavy hybrid energy cannon with two settings: Stun and kill."
|
||||
icon_state = "turretlaser"
|
||||
item_state = "turretlaser"
|
||||
slot_flags = null
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
can_flashlight = 0
|
||||
trigger_guard = TRIGGER_GUARD_NONE
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/gun/energy/gun/nuclear
|
||||
name = "advanced energy gun"
|
||||
desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell."
|
||||
icon_state = "nucgun"
|
||||
item_state = "nucgun"
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=4"
|
||||
var/fail_tick = 0
|
||||
charge_delay = 5
|
||||
can_charge = 0
|
||||
ammo_x_offset = 1
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler)
|
||||
selfcharge = 1
|
||||
|
||||
@@ -1,85 +1,85 @@
|
||||
/obj/item/gun/energy/pulse
|
||||
name = "pulse rifle"
|
||||
desc = "A heavy-duty, multifaceted energy rifle with three modes. Preferred by front-line combat personnel."
|
||||
icon_state = "pulse"
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
cell_type = /obj/item/stock_parts/cell/pulse
|
||||
|
||||
/obj/item/gun/energy/pulse/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/pulse/isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/gun/energy/pulse/cyborg
|
||||
|
||||
/obj/item/gun/energy/pulse/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/pulse/carbine
|
||||
name = "pulse carbine"
|
||||
desc = "A compact variant of the pulse rifle with less firepower but easier storage."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
slot_flags = SLOT_BELT
|
||||
icon_state = "pulse_carbine"
|
||||
item_state = "pulse"
|
||||
cell_type = /obj/item/stock_parts/cell/pulse/carbine
|
||||
can_flashlight = 1
|
||||
flight_x_offset = 18
|
||||
flight_y_offset = 12
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol
|
||||
name = "pulse pistol"
|
||||
desc = "A pulse rifle in an easily concealed handgun package with low capacity."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
icon_state = "pulse_pistol"
|
||||
item_state = "gun"
|
||||
cell_type = /obj/item/stock_parts/cell/pulse/pistol
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol/isHandgun()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/energy/pulse/destroyer
|
||||
name = "pulse destroyer"
|
||||
desc = "A heavy-duty, pulse-based energy weapon."
|
||||
cell_type = /obj/item/stock_parts/cell/infinite
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse)
|
||||
|
||||
/obj/item/gun/energy/pulse/destroyer/attack_self(mob/living/user)
|
||||
to_chat(user, "<span class='danger'>[name] has three settings, and they are all DESTROY.</span>")
|
||||
|
||||
/obj/item/gun/energy/pulse/destroyer/annihilator
|
||||
name = "pulse ANNIHILATOR"
|
||||
desc = "For when the situation calls for a little more than a pulse destroyer."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter/pulse)
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol/m1911
|
||||
name = "\improper M1911-P"
|
||||
desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people."
|
||||
icon_state = "m1911"
|
||||
item_state = "gun"
|
||||
cell_type = /obj/item/stock_parts/cell/infinite
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol/m1911/isHandgun()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/energy/pulse/turret
|
||||
name = "pulse turret gun"
|
||||
desc = "A heavy, turret-mounted pulse energy cannon."
|
||||
icon_state = "turretlaser"
|
||||
item_state = "turretlaser"
|
||||
slot_flags = null
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser/pulse)
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
can_flashlight = 0
|
||||
trigger_guard = TRIGGER_GUARD_NONE
|
||||
ammo_x_offset = 2
|
||||
/obj/item/gun/energy/pulse
|
||||
name = "pulse rifle"
|
||||
desc = "A heavy-duty, multifaceted energy rifle with three modes. Preferred by front-line combat personnel."
|
||||
icon_state = "pulse"
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
cell_type = /obj/item/stock_parts/cell/pulse
|
||||
|
||||
/obj/item/gun/energy/pulse/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/pulse/isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/gun/energy/pulse/cyborg
|
||||
|
||||
/obj/item/gun/energy/pulse/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/pulse/carbine
|
||||
name = "pulse carbine"
|
||||
desc = "A compact variant of the pulse rifle with less firepower but easier storage."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
slot_flags = SLOT_BELT
|
||||
icon_state = "pulse_carbine"
|
||||
item_state = "pulse"
|
||||
cell_type = /obj/item/stock_parts/cell/pulse/carbine
|
||||
can_flashlight = 1
|
||||
flight_x_offset = 18
|
||||
flight_y_offset = 12
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol
|
||||
name = "pulse pistol"
|
||||
desc = "A pulse rifle in an easily concealed handgun package with low capacity."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
icon_state = "pulse_pistol"
|
||||
item_state = "gun"
|
||||
cell_type = /obj/item/stock_parts/cell/pulse/pistol
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol/isHandgun()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/energy/pulse/destroyer
|
||||
name = "pulse destroyer"
|
||||
desc = "A heavy-duty, pulse-based energy weapon."
|
||||
cell_type = /obj/item/stock_parts/cell/infinite
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse)
|
||||
|
||||
/obj/item/gun/energy/pulse/destroyer/attack_self(mob/living/user)
|
||||
to_chat(user, "<span class='danger'>[name] has three settings, and they are all DESTROY.</span>")
|
||||
|
||||
/obj/item/gun/energy/pulse/destroyer/annihilator
|
||||
name = "pulse ANNIHILATOR"
|
||||
desc = "For when the situation calls for a little more than a pulse destroyer."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter/pulse)
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol/m1911
|
||||
name = "\improper M1911-P"
|
||||
desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people."
|
||||
icon_state = "m1911"
|
||||
item_state = "gun"
|
||||
cell_type = /obj/item/stock_parts/cell/infinite
|
||||
|
||||
/obj/item/gun/energy/pulse/pistol/m1911/isHandgun()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/energy/pulse/turret
|
||||
name = "pulse turret gun"
|
||||
desc = "A heavy, turret-mounted pulse energy cannon."
|
||||
icon_state = "turretlaser"
|
||||
item_state = "turretlaser"
|
||||
slot_flags = null
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser/pulse)
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
can_flashlight = 0
|
||||
trigger_guard = TRIGGER_GUARD_NONE
|
||||
ammo_x_offset = 2
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,60 +1,60 @@
|
||||
/obj/item/gun/energy/taser
|
||||
name = "taser gun"
|
||||
desc = "A small, low capacity gun used for non-lethal takedowns."
|
||||
icon_state = "taser"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/taser/mounted
|
||||
name = "mounted taser gun"
|
||||
selfcharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/gun/energy/shock_revolver
|
||||
name = "tesla revolver"
|
||||
desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers."
|
||||
icon_state = "stunrevolver"
|
||||
item_state = "gun"
|
||||
origin_tech = "combat=4;materials=4;powerstorage=4"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/shock_revolver)
|
||||
can_flashlight = 0
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser
|
||||
name = "hybrid taser"
|
||||
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
|
||||
icon_state = "advtaser"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
|
||||
origin_tech = "combat=4"
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser/cyborg
|
||||
name = "cyborg taser"
|
||||
desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The weapon contains a limiter to prevent the cyborg's power cell from overheating."
|
||||
can_flashlight = 0
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/disabler
|
||||
name = "disabler"
|
||||
desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse."
|
||||
icon_state = "disabler"
|
||||
item_state = null
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/disabler/cyborg
|
||||
name = "cyborg disabler"
|
||||
desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler/cyborg)
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/gun/energy/disabler/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
/obj/item/gun/energy/taser
|
||||
name = "taser gun"
|
||||
desc = "A small, low capacity gun used for non-lethal takedowns."
|
||||
icon_state = "taser"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/taser/mounted
|
||||
name = "mounted taser gun"
|
||||
selfcharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/gun/energy/shock_revolver
|
||||
name = "tesla revolver"
|
||||
desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers."
|
||||
icon_state = "stunrevolver"
|
||||
item_state = "gun"
|
||||
origin_tech = "combat=4;materials=4;powerstorage=4"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/shock_revolver)
|
||||
can_flashlight = 0
|
||||
shaded_charge = 1
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser
|
||||
name = "hybrid taser"
|
||||
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
|
||||
icon_state = "advtaser"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
|
||||
origin_tech = "combat=4"
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser/cyborg
|
||||
name = "cyborg taser"
|
||||
desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The weapon contains a limiter to prevent the cyborg's power cell from overheating."
|
||||
can_flashlight = 0
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
/obj/item/gun/energy/disabler
|
||||
name = "disabler"
|
||||
desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse."
|
||||
icon_state = "disabler"
|
||||
item_state = null
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/disabler/cyborg
|
||||
name = "cyborg disabler"
|
||||
desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler/cyborg)
|
||||
can_charge = 0
|
||||
|
||||
/obj/item/gun/energy/disabler/cyborg/newshot()
|
||||
..()
|
||||
robocharge()
|
||||
|
||||
@@ -127,4 +127,4 @@
|
||||
lightr = max(lightr - 1, 0)
|
||||
|
||||
/obj/item/projectile/blastwave/ex_act()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
item_state = "armcannonlase"
|
||||
force = 5
|
||||
selfcharge = 1
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
|
||||
@@ -1,214 +1,214 @@
|
||||
/obj/item/gun/projectile
|
||||
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason"
|
||||
name = "projectile gun"
|
||||
icon_state = "pistol"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
materials = list(MAT_METAL=1000)
|
||||
|
||||
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
|
||||
var/obj/item/ammo_box/magazine/magazine
|
||||
var/can_tactical = FALSE //check to see if the gun can tactically reload
|
||||
|
||||
/obj/item/gun/projectile/New()
|
||||
..()
|
||||
if(!magazine)
|
||||
magazine = new mag_type(src)
|
||||
chamber_round()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/update_icon()
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
|
||||
if(bayonet && can_bayonet)
|
||||
overlays += knife_overlay
|
||||
|
||||
/obj/item/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1)
|
||||
var/obj/item/ammo_casing/AC = chambered //Find chambered round
|
||||
if(isnull(AC) || !istype(AC))
|
||||
chamber_round()
|
||||
return
|
||||
if(eject_casing)
|
||||
AC.loc = get_turf(src) //Eject casing onto ground.
|
||||
AC.SpinAnimation(10, 1) //next gen special effects
|
||||
playsound(src, chambered.drop_sound, 100, 1)
|
||||
if(empty_chamber)
|
||||
chambered = null
|
||||
chamber_round()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/proc/chamber_round()
|
||||
if(chambered || !magazine)
|
||||
return
|
||||
else if(magazine.ammo_count())
|
||||
chambered = magazine.get_round()
|
||||
chambered.loc = src
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/can_shoot()
|
||||
if(!magazine || !magazine.ammo_count(0))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/proc/can_reload()
|
||||
return !magazine
|
||||
|
||||
/obj/item/gun/projectile/proc/reload(obj/item/ammo_box/magazine/AM, mob/user as mob)
|
||||
user.remove_from_mob(AM)
|
||||
magazine = AM
|
||||
magazine.loc = src
|
||||
playsound(src, magin_sound, 50, 1)
|
||||
chamber_round()
|
||||
AM.update_icon()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params)
|
||||
if(istype(A, /obj/item/ammo_box/magazine))
|
||||
var/obj/item/ammo_box/magazine/AM = A
|
||||
if(istype(AM, mag_type))
|
||||
if(can_reload())
|
||||
reload(AM, user)
|
||||
to_chat(user, "<span class='notice'>You load a new magazine into \the [src].</span>")
|
||||
return TRUE
|
||||
else if(!can_tactical)
|
||||
to_chat(user, "<span class='notice'>There's already a magazine in \the [src].</span>")
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>")
|
||||
magazine.loc = get_turf(loc)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
reload(AM, user)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't put this type of ammo in \the [src].</span>")
|
||||
return TRUE
|
||||
if(istype(A, /obj/item/suppressor))
|
||||
var/obj/item/suppressor/S = A
|
||||
if(can_suppress)
|
||||
if(!suppressed)
|
||||
if(!user.unEquip(A))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You screw [S] onto [src].</span>")
|
||||
suppressed = A
|
||||
S.oldsound = fire_sound
|
||||
S.initial_w_class = w_class
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_silenced.ogg'
|
||||
w_class = WEIGHT_CLASS_NORMAL //so pistols do not fit in pockets when suppressed
|
||||
A.loc = src
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] already has a suppressor.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't seem to figure out how to fit [S] on [src].</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(suppressed && can_unsuppress)
|
||||
var/obj/item/suppressor/S = suppressed
|
||||
if(user.l_hand != src && user.r_hand != src)
|
||||
..()
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You unscrew [suppressed] from [src].</span>")
|
||||
user.put_in_hands(suppressed)
|
||||
fire_sound = S.oldsound
|
||||
w_class = S.initial_w_class
|
||||
suppressed = 0
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/gun/projectile/attack_self(mob/living/user as mob)
|
||||
var/obj/item/ammo_casing/AC = chambered //Find chambered round
|
||||
if(magazine)
|
||||
magazine.loc = get_turf(loc)
|
||||
user.put_in_hands(magazine)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
to_chat(user, "<span class='notice'>You pull the magazine out of \the [src]!</span>")
|
||||
playsound(src, magout_sound, 50, 1)
|
||||
else if(chambered)
|
||||
AC.loc = get_turf(src)
|
||||
AC.SpinAnimation(10, 1)
|
||||
chambered = null
|
||||
to_chat(user, "<span class='notice'>You unload the round from \the [src]'s chamber.</span>")
|
||||
playsound(src, 'sound/weapons/gun_interactions/remove_bullet.ogg', 50, 1)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's no magazine in \the [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/examine(mob/user)
|
||||
. = ..()
|
||||
. += "Has [get_ammo()] round\s remaining."
|
||||
|
||||
/obj/item/gun/projectile/proc/get_ammo(countchambered = 1)
|
||||
var/boolets = 0 //mature var names for mature people
|
||||
if(chambered && countchambered)
|
||||
boolets++
|
||||
if(magazine)
|
||||
boolets += magazine.ammo_count()
|
||||
return boolets
|
||||
|
||||
/obj/item/gun/projectile/suicide_act(mob/user)
|
||||
if(chambered && chambered.BB && !chambered.BB.nodamage)
|
||||
user.visible_message("<span class='suicide'>[user] is putting the barrel of the [name] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
sleep(25)
|
||||
if(user.l_hand == src || user.r_hand == src)
|
||||
process_fire(user, user, 0, zone_override = "head")
|
||||
user.visible_message("<span class='suicide'>[user] blows [user.p_their()] brains out with the [name]!</span>")
|
||||
return BRUTELOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return OXYLOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!</b></span>")
|
||||
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
|
||||
return OXYLOSS
|
||||
|
||||
/obj/item/gun/projectile/proc/sawoff(mob/user)
|
||||
if(sawn_state == SAWN_OFF)
|
||||
to_chat(user, "<span class='warning'>\The [src] is already shortened!</span>")
|
||||
return
|
||||
if(bayonet)
|
||||
to_chat(user, "<span class='warning'>You cannot saw-off [src] with [bayonet] attached!</span>")
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.visible_message("[user] begins to shorten \the [src].", "<span class='notice'>You begin to shorten \the [src]...</span>")
|
||||
|
||||
//if there's any live ammo inside the gun, makes it go off
|
||||
if(blow_up(user))
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
if(sawn_state == SAWN_OFF)
|
||||
return
|
||||
user.visible_message("[user] shortens \the [src]!", "<span class='notice'>You shorten \the [src].</span>")
|
||||
name = "sawn-off [name]"
|
||||
desc = sawn_desc
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
item_state = "gun"//phil235 is it different with different skin?
|
||||
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)
|
||||
sawn_state = SAWN_OFF
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
// Sawing guns related proc
|
||||
/obj/item/gun/projectile/proc/blow_up(mob/user)
|
||||
. = 0
|
||||
for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
|
||||
if(AC.BB)
|
||||
process_fire(user, user,0)
|
||||
. = 1
|
||||
/obj/item/gun/projectile
|
||||
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason"
|
||||
name = "projectile gun"
|
||||
icon_state = "pistol"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
materials = list(MAT_METAL=1000)
|
||||
|
||||
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
|
||||
var/obj/item/ammo_box/magazine/magazine
|
||||
var/can_tactical = FALSE //check to see if the gun can tactically reload
|
||||
|
||||
/obj/item/gun/projectile/New()
|
||||
..()
|
||||
if(!magazine)
|
||||
magazine = new mag_type(src)
|
||||
chamber_round()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/update_icon()
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
|
||||
if(bayonet && can_bayonet)
|
||||
overlays += knife_overlay
|
||||
|
||||
/obj/item/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1)
|
||||
var/obj/item/ammo_casing/AC = chambered //Find chambered round
|
||||
if(isnull(AC) || !istype(AC))
|
||||
chamber_round()
|
||||
return
|
||||
if(eject_casing)
|
||||
AC.loc = get_turf(src) //Eject casing onto ground.
|
||||
AC.SpinAnimation(10, 1) //next gen special effects
|
||||
playsound(src, chambered.drop_sound, 100, 1)
|
||||
if(empty_chamber)
|
||||
chambered = null
|
||||
chamber_round()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/proc/chamber_round()
|
||||
if(chambered || !magazine)
|
||||
return
|
||||
else if(magazine.ammo_count())
|
||||
chambered = magazine.get_round()
|
||||
chambered.loc = src
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/can_shoot()
|
||||
if(!magazine || !magazine.ammo_count(0))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/proc/can_reload()
|
||||
return !magazine
|
||||
|
||||
/obj/item/gun/projectile/proc/reload(obj/item/ammo_box/magazine/AM, mob/user as mob)
|
||||
user.remove_from_mob(AM)
|
||||
magazine = AM
|
||||
magazine.loc = src
|
||||
playsound(src, magin_sound, 50, 1)
|
||||
chamber_round()
|
||||
AM.update_icon()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params)
|
||||
if(istype(A, /obj/item/ammo_box/magazine))
|
||||
var/obj/item/ammo_box/magazine/AM = A
|
||||
if(istype(AM, mag_type))
|
||||
if(can_reload())
|
||||
reload(AM, user)
|
||||
to_chat(user, "<span class='notice'>You load a new magazine into \the [src].</span>")
|
||||
return TRUE
|
||||
else if(!can_tactical)
|
||||
to_chat(user, "<span class='notice'>There's already a magazine in \the [src].</span>")
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>")
|
||||
magazine.loc = get_turf(loc)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
reload(AM, user)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't put this type of ammo in \the [src].</span>")
|
||||
return TRUE
|
||||
if(istype(A, /obj/item/suppressor))
|
||||
var/obj/item/suppressor/S = A
|
||||
if(can_suppress)
|
||||
if(!suppressed)
|
||||
if(!user.unEquip(A))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You screw [S] onto [src].</span>")
|
||||
suppressed = A
|
||||
S.oldsound = fire_sound
|
||||
S.initial_w_class = w_class
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_silenced.ogg'
|
||||
w_class = WEIGHT_CLASS_NORMAL //so pistols do not fit in pockets when suppressed
|
||||
A.loc = src
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] already has a suppressor.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't seem to figure out how to fit [S] on [src].</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(suppressed && can_unsuppress)
|
||||
var/obj/item/suppressor/S = suppressed
|
||||
if(user.l_hand != src && user.r_hand != src)
|
||||
..()
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You unscrew [suppressed] from [src].</span>")
|
||||
user.put_in_hands(suppressed)
|
||||
fire_sound = S.oldsound
|
||||
w_class = S.initial_w_class
|
||||
suppressed = 0
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/gun/projectile/attack_self(mob/living/user as mob)
|
||||
var/obj/item/ammo_casing/AC = chambered //Find chambered round
|
||||
if(magazine)
|
||||
magazine.loc = get_turf(loc)
|
||||
user.put_in_hands(magazine)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
to_chat(user, "<span class='notice'>You pull the magazine out of \the [src]!</span>")
|
||||
playsound(src, magout_sound, 50, 1)
|
||||
else if(chambered)
|
||||
AC.loc = get_turf(src)
|
||||
AC.SpinAnimation(10, 1)
|
||||
chambered = null
|
||||
to_chat(user, "<span class='notice'>You unload the round from \the [src]'s chamber.</span>")
|
||||
playsound(src, 'sound/weapons/gun_interactions/remove_bullet.ogg', 50, 1)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's no magazine in \the [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/examine(mob/user)
|
||||
. = ..()
|
||||
. += "Has [get_ammo()] round\s remaining."
|
||||
|
||||
/obj/item/gun/projectile/proc/get_ammo(countchambered = 1)
|
||||
var/boolets = 0 //mature var names for mature people
|
||||
if(chambered && countchambered)
|
||||
boolets++
|
||||
if(magazine)
|
||||
boolets += magazine.ammo_count()
|
||||
return boolets
|
||||
|
||||
/obj/item/gun/projectile/suicide_act(mob/user)
|
||||
if(chambered && chambered.BB && !chambered.BB.nodamage)
|
||||
user.visible_message("<span class='suicide'>[user] is putting the barrel of the [name] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
sleep(25)
|
||||
if(user.l_hand == src || user.r_hand == src)
|
||||
process_fire(user, user, 0, zone_override = "head")
|
||||
user.visible_message("<span class='suicide'>[user] blows [user.p_their()] brains out with the [name]!</span>")
|
||||
return BRUTELOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return OXYLOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!</b></span>")
|
||||
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
|
||||
return OXYLOSS
|
||||
|
||||
/obj/item/gun/projectile/proc/sawoff(mob/user)
|
||||
if(sawn_state == SAWN_OFF)
|
||||
to_chat(user, "<span class='warning'>\The [src] is already shortened!</span>")
|
||||
return
|
||||
if(bayonet)
|
||||
to_chat(user, "<span class='warning'>You cannot saw-off [src] with [bayonet] attached!</span>")
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.visible_message("[user] begins to shorten \the [src].", "<span class='notice'>You begin to shorten \the [src]...</span>")
|
||||
|
||||
//if there's any live ammo inside the gun, makes it go off
|
||||
if(blow_up(user))
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
if(sawn_state == SAWN_OFF)
|
||||
return
|
||||
user.visible_message("[user] shortens \the [src]!", "<span class='notice'>You shorten \the [src].</span>")
|
||||
name = "sawn-off [name]"
|
||||
desc = sawn_desc
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
item_state = "gun"//phil235 is it different with different skin?
|
||||
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)
|
||||
sawn_state = SAWN_OFF
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
// Sawing guns related proc
|
||||
/obj/item/gun/projectile/proc/blow_up(mob/user)
|
||||
. = 0
|
||||
for(var/obj/item/ammo_casing/AC in magazine.stored_ammo)
|
||||
if(AC.BB)
|
||||
process_fire(user, user,0)
|
||||
. = 1
|
||||
|
||||
@@ -1,306 +1,306 @@
|
||||
/obj/item/gun/projectile/automatic
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/alarmed = 0
|
||||
var/select = 1
|
||||
can_tactical = TRUE
|
||||
can_suppress = 1
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
|
||||
/obj/item/gun/projectile/automatic/isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/gun/projectile/automatic/update_icon()
|
||||
..()
|
||||
overlays.Cut()
|
||||
if(!select)
|
||||
overlays += "[initial(icon_state)]semi"
|
||||
if(select == 1)
|
||||
overlays += "[initial(icon_state)]burst"
|
||||
icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
if(bayonet && can_bayonet)
|
||||
overlays += knife_overlay
|
||||
|
||||
/obj/item/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(alarmed) // Did the empty clip alarm go off already?
|
||||
alarmed = 0 // Reset the alarm once a magazine is loaded
|
||||
return
|
||||
if(istype(A, /obj/item/ammo_box/magazine))
|
||||
var/obj/item/ammo_box/magazine/AM = A
|
||||
if(istype(AM, mag_type))
|
||||
if(magazine)
|
||||
to_chat(user, "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>")
|
||||
magazine.loc = get_turf(loc)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You insert the magazine into \the [src].</span>")
|
||||
if(alarmed)
|
||||
alarmed = 0
|
||||
user.remove_from_mob(AM)
|
||||
magazine = AM
|
||||
magazine.loc = src
|
||||
chamber_round()
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/automatic/ui_action_click()
|
||||
burst_select()
|
||||
|
||||
/obj/item/gun/projectile/automatic/proc/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
select = !select
|
||||
if(!select)
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
to_chat(user, "<span class='notice'>You switch to semi-automatic.</span>")
|
||||
else
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
to_chat(user, "<span class='notice'>You switch to [burst_size] round burst.</span>")
|
||||
|
||||
playsound(user, 'sound/weapons/gun_interactions/selector.ogg', 100, 1)
|
||||
update_icon()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/can_shoot()
|
||||
return get_ammo()
|
||||
|
||||
/obj/item/gun/projectile/automatic/proc/empty_alarm()
|
||||
if(!chambered && !get_ammo() && !alarmed)
|
||||
playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
update_icon()
|
||||
alarmed = 1
|
||||
|
||||
//Saber SMG//
|
||||
/obj/item/gun/projectile/automatic/proto
|
||||
name = "\improper Nanotrasen Saber SMG"
|
||||
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
|
||||
icon_state = "saber"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm9mm
|
||||
origin_tech = "combat=4;materials=2"
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
|
||||
//C-20r SMG//
|
||||
/obj/item/gun/projectile/automatic/c20r
|
||||
name = "\improper C-20r SMG"
|
||||
desc = "A two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
|
||||
icon_state = "c20r"
|
||||
item_state = "c20r"
|
||||
origin_tech = "combat=5;materials=2;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm45
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg'
|
||||
fire_delay = 2
|
||||
burst_size = 2
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 26
|
||||
knife_y_offset = 12
|
||||
|
||||
/obj/item/gun/projectile/automatic/c20r/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/c20r/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
empty_alarm()
|
||||
|
||||
/obj/item/gun/projectile/automatic/c20r/update_icon()
|
||||
..()
|
||||
icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
|
||||
//WT550//
|
||||
/obj/item/gun/projectile/automatic/wt550
|
||||
name = "security auto rifle"
|
||||
desc = "An outdated personal defense weapon utilized by law enforcement. The WT-550 Automatic Rifle fires 4.6x30mm rounds."
|
||||
icon_state = "wt550"
|
||||
item_state = "arg"
|
||||
mag_type = /obj/item/ammo_box/magazine/wt550m9
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
fire_delay = 2
|
||||
can_suppress = 0
|
||||
burst_size = 1
|
||||
actions_types = list()
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 25
|
||||
knife_y_offset = 12
|
||||
|
||||
/obj/item/gun/projectile/automatic/wt550/update_icon()
|
||||
..()
|
||||
icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]"
|
||||
|
||||
//Type-U3 Uzi//
|
||||
/obj/item/gun/projectile/automatic/mini_uzi
|
||||
name = "\improper 'Type U3' Uzi"
|
||||
desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds."
|
||||
icon_state = "mini-uzi"
|
||||
origin_tech = "combat=4;materials=2;syndicate=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/uzim9mm
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
burst_size = 2
|
||||
|
||||
//M-90gl Carbine//
|
||||
/obj/item/gun/projectile/automatic/m90
|
||||
name = "\improper M-90gl Carbine"
|
||||
desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off."
|
||||
icon_state = "m90"
|
||||
item_state = "m90-4"
|
||||
origin_tech = "combat=5;materials=2;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
var/obj/item/gun/projectile/revolver/grenadelauncher/underbarrel
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/New()
|
||||
..()
|
||||
underbarrel = new /obj/item/gun/projectile/revolver/grenadelauncher(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/afterattack(var/atom/target, var/mob/living/user, flag, params)
|
||||
if(select == 2)
|
||||
underbarrel.afterattack(target, user, flag, params)
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/attackby(var/obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/ammo_casing))
|
||||
if(istype(A, underbarrel.magazine.ammo_type))
|
||||
underbarrel.attack_self()
|
||||
underbarrel.attackby(A, user, params)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/update_icon()
|
||||
..()
|
||||
overlays.Cut()
|
||||
switch(select)
|
||||
if(0)
|
||||
overlays += "[initial(icon_state)]semi"
|
||||
if(1)
|
||||
overlays += "[initial(icon_state)]burst"
|
||||
if(2)
|
||||
overlays += "[initial(icon_state)]gren"
|
||||
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
|
||||
if(magazine)
|
||||
overlays += image(icon = icon, icon_state = "m90-[Ceiling(get_ammo(0)/6)*6]")
|
||||
item_state = "m90-[Ceiling(get_ammo(0)/7.5)]"
|
||||
else
|
||||
item_state = "m90-0"
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
switch(select)
|
||||
if(0)
|
||||
select = 1
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
to_chat(user, "<span class='notice'>You switch to [burst_size] round burst.</span>")
|
||||
if(1)
|
||||
select = 2
|
||||
to_chat(user, "<span class='notice'>You switch to grenades.</span>")
|
||||
if(2)
|
||||
select = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
to_chat(user, "<span class='notice'>You switch to semi-auto.</span>")
|
||||
playsound(user, 'sound/weapons/gun_interactions/selector.ogg', 100, 1)
|
||||
update_icon()
|
||||
|
||||
//Tommy Gun//
|
||||
/obj/item/gun/projectile/automatic/tommygun
|
||||
name = "\improper Thompson SMG"
|
||||
desc = "A genuine 'Chicago Typewriter'."
|
||||
icon_state = "tommygun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=5;materials=1;syndicate=3"
|
||||
mag_type = /obj/item/ammo_box/magazine/tommygunm45
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 4
|
||||
fire_delay = 1
|
||||
|
||||
//ARG Assault Rifle//
|
||||
/obj/item/gun/projectile/automatic/ar
|
||||
name = "ARG"
|
||||
desc = "A robust assault rile used by Nanotrasen fighting forces."
|
||||
icon_state = "arg"
|
||||
item_state = "arg"
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=6;engineering=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_mg.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
|
||||
// Bulldog shotgun //
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog
|
||||
name = "\improper 'Bulldog' Shotgun"
|
||||
desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines."
|
||||
icon_state = "bulldog"
|
||||
item_state = "bulldog"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "combat=6;materials=4;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m12g
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine()
|
||||
if(magazine)
|
||||
overlays.Cut()
|
||||
overlays += "[magazine.icon_state]"
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/update_icon()
|
||||
overlays.Cut()
|
||||
update_magazine()
|
||||
icon_state = "bulldog[chambered ? "" : "-e"]"
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
empty_alarm()
|
||||
|
||||
//Laser carbine//
|
||||
/obj/item/gun/projectile/automatic/lasercarbine
|
||||
name = "\improper IK-60 Laser Carbine"
|
||||
desc = "A short, compact carbine like rifle, relying more on battery cartridges rather than a built in power cell. Utilized by the Nanotrasen Navy for combat operations."
|
||||
icon_state = "lasercarbine"
|
||||
item_state = "laser"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "combat=4;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/laser
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_lascarbine.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 2
|
||||
|
||||
/obj/item/gun/projectile/automatic/lasercarbine/update_icon()
|
||||
..()
|
||||
icon_state = "lasercarbine[magazine ? "-[Ceiling(get_ammo(0)/5)*5]" : ""]"
|
||||
/obj/item/gun/projectile/automatic
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/alarmed = 0
|
||||
var/select = 1
|
||||
can_tactical = TRUE
|
||||
can_suppress = 1
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
|
||||
/obj/item/gun/projectile/automatic/isHandgun()
|
||||
return 0
|
||||
|
||||
/obj/item/gun/projectile/automatic/update_icon()
|
||||
..()
|
||||
overlays.Cut()
|
||||
if(!select)
|
||||
overlays += "[initial(icon_state)]semi"
|
||||
if(select == 1)
|
||||
overlays += "[initial(icon_state)]burst"
|
||||
icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
if(bayonet && can_bayonet)
|
||||
overlays += knife_overlay
|
||||
|
||||
/obj/item/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(alarmed) // Did the empty clip alarm go off already?
|
||||
alarmed = 0 // Reset the alarm once a magazine is loaded
|
||||
return
|
||||
if(istype(A, /obj/item/ammo_box/magazine))
|
||||
var/obj/item/ammo_box/magazine/AM = A
|
||||
if(istype(AM, mag_type))
|
||||
if(magazine)
|
||||
to_chat(user, "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>")
|
||||
magazine.loc = get_turf(loc)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You insert the magazine into \the [src].</span>")
|
||||
if(alarmed)
|
||||
alarmed = 0
|
||||
user.remove_from_mob(AM)
|
||||
magazine = AM
|
||||
magazine.loc = src
|
||||
chamber_round()
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/automatic/ui_action_click()
|
||||
burst_select()
|
||||
|
||||
/obj/item/gun/projectile/automatic/proc/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
select = !select
|
||||
if(!select)
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
to_chat(user, "<span class='notice'>You switch to semi-automatic.</span>")
|
||||
else
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
to_chat(user, "<span class='notice'>You switch to [burst_size] round burst.</span>")
|
||||
|
||||
playsound(user, 'sound/weapons/gun_interactions/selector.ogg', 100, 1)
|
||||
update_icon()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/can_shoot()
|
||||
return get_ammo()
|
||||
|
||||
/obj/item/gun/projectile/automatic/proc/empty_alarm()
|
||||
if(!chambered && !get_ammo() && !alarmed)
|
||||
playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
|
||||
update_icon()
|
||||
alarmed = 1
|
||||
|
||||
//Saber SMG//
|
||||
/obj/item/gun/projectile/automatic/proto
|
||||
name = "\improper Nanotrasen Saber SMG"
|
||||
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
|
||||
icon_state = "saber"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm9mm
|
||||
origin_tech = "combat=4;materials=2"
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
|
||||
//C-20r SMG//
|
||||
/obj/item/gun/projectile/automatic/c20r
|
||||
name = "\improper C-20r SMG"
|
||||
desc = "A two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
|
||||
icon_state = "c20r"
|
||||
item_state = "c20r"
|
||||
origin_tech = "combat=5;materials=2;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm45
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg'
|
||||
fire_delay = 2
|
||||
burst_size = 2
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 26
|
||||
knife_y_offset = 12
|
||||
|
||||
/obj/item/gun/projectile/automatic/c20r/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/c20r/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
empty_alarm()
|
||||
|
||||
/obj/item/gun/projectile/automatic/c20r/update_icon()
|
||||
..()
|
||||
icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
|
||||
//WT550//
|
||||
/obj/item/gun/projectile/automatic/wt550
|
||||
name = "security auto rifle"
|
||||
desc = "An outdated personal defense weapon utilized by law enforcement. The WT-550 Automatic Rifle fires 4.6x30mm rounds."
|
||||
icon_state = "wt550"
|
||||
item_state = "arg"
|
||||
mag_type = /obj/item/ammo_box/magazine/wt550m9
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
fire_delay = 2
|
||||
can_suppress = 0
|
||||
burst_size = 1
|
||||
actions_types = list()
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 25
|
||||
knife_y_offset = 12
|
||||
|
||||
/obj/item/gun/projectile/automatic/wt550/update_icon()
|
||||
..()
|
||||
icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]"
|
||||
|
||||
//Type-U3 Uzi//
|
||||
/obj/item/gun/projectile/automatic/mini_uzi
|
||||
name = "\improper 'Type U3' Uzi"
|
||||
desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds."
|
||||
icon_state = "mini-uzi"
|
||||
origin_tech = "combat=4;materials=2;syndicate=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/uzim9mm
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
burst_size = 2
|
||||
|
||||
//M-90gl Carbine//
|
||||
/obj/item/gun/projectile/automatic/m90
|
||||
name = "\improper M-90gl Carbine"
|
||||
desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off."
|
||||
icon_state = "m90"
|
||||
item_state = "m90-4"
|
||||
origin_tech = "combat=5;materials=2;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
var/obj/item/gun/projectile/revolver/grenadelauncher/underbarrel
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/New()
|
||||
..()
|
||||
underbarrel = new /obj/item/gun/projectile/revolver/grenadelauncher(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/afterattack(var/atom/target, var/mob/living/user, flag, params)
|
||||
if(select == 2)
|
||||
underbarrel.afterattack(target, user, flag, params)
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/attackby(var/obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/ammo_casing))
|
||||
if(istype(A, underbarrel.magazine.ammo_type))
|
||||
underbarrel.attack_self()
|
||||
underbarrel.attackby(A, user, params)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/update_icon()
|
||||
..()
|
||||
overlays.Cut()
|
||||
switch(select)
|
||||
if(0)
|
||||
overlays += "[initial(icon_state)]semi"
|
||||
if(1)
|
||||
overlays += "[initial(icon_state)]burst"
|
||||
if(2)
|
||||
overlays += "[initial(icon_state)]gren"
|
||||
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
|
||||
if(magazine)
|
||||
overlays += image(icon = icon, icon_state = "m90-[Ceiling(get_ammo(0)/6)*6]")
|
||||
item_state = "m90-[Ceiling(get_ammo(0)/7.5)]"
|
||||
else
|
||||
item_state = "m90-0"
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/automatic/m90/burst_select()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
switch(select)
|
||||
if(0)
|
||||
select = 1
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
to_chat(user, "<span class='notice'>You switch to [burst_size] round burst.</span>")
|
||||
if(1)
|
||||
select = 2
|
||||
to_chat(user, "<span class='notice'>You switch to grenades.</span>")
|
||||
if(2)
|
||||
select = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
to_chat(user, "<span class='notice'>You switch to semi-auto.</span>")
|
||||
playsound(user, 'sound/weapons/gun_interactions/selector.ogg', 100, 1)
|
||||
update_icon()
|
||||
|
||||
//Tommy Gun//
|
||||
/obj/item/gun/projectile/automatic/tommygun
|
||||
name = "\improper Thompson SMG"
|
||||
desc = "A genuine 'Chicago Typewriter'."
|
||||
icon_state = "tommygun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=5;materials=1;syndicate=3"
|
||||
mag_type = /obj/item/ammo_box/magazine/tommygunm45
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_smg.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 4
|
||||
fire_delay = 1
|
||||
|
||||
//ARG Assault Rifle//
|
||||
/obj/item/gun/projectile/automatic/ar
|
||||
name = "ARG"
|
||||
desc = "A robust assault rile used by Nanotrasen fighting forces."
|
||||
icon_state = "arg"
|
||||
item_state = "arg"
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=6;engineering=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_mg.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
|
||||
// Bulldog shotgun //
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog
|
||||
name = "\improper 'Bulldog' Shotgun"
|
||||
desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines."
|
||||
icon_state = "bulldog"
|
||||
item_state = "bulldog"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "combat=6;materials=4;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m12g
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine()
|
||||
if(magazine)
|
||||
overlays.Cut()
|
||||
overlays += "[magazine.icon_state]"
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/update_icon()
|
||||
overlays.Cut()
|
||||
update_magazine()
|
||||
icon_state = "bulldog[chambered ? "" : "-e"]"
|
||||
|
||||
/obj/item/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
|
||||
..()
|
||||
empty_alarm()
|
||||
|
||||
//Laser carbine//
|
||||
/obj/item/gun/projectile/automatic/lasercarbine
|
||||
name = "\improper IK-60 Laser Carbine"
|
||||
desc = "A short, compact carbine like rifle, relying more on battery cartridges rather than a built in power cell. Utilized by the Nanotrasen Navy for combat operations."
|
||||
icon_state = "lasercarbine"
|
||||
item_state = "laser"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "combat=4;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/laser
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_lascarbine.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 2
|
||||
|
||||
/obj/item/gun/projectile/automatic/lasercarbine/update_icon()
|
||||
..()
|
||||
icon_state = "lasercarbine[magazine ? "-[Ceiling(get_ammo(0)/5)*5]" : ""]"
|
||||
|
||||
@@ -1,118 +1,118 @@
|
||||
//Stetchkin//
|
||||
/obj/item/gun/projectile/automatic/pistol
|
||||
name = "stechkin pistol"
|
||||
desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors."
|
||||
icon_state = "pistol"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "combat=3;materials=2;syndicate=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/m10mm
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/pistol_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/pistol_magout.ogg'
|
||||
can_suppress = 1
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/isHandgun()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
return
|
||||
|
||||
//M1911//
|
||||
/obj/item/gun/projectile/automatic/pistol/m1911
|
||||
name = "\improper M1911"
|
||||
desc = "A classic .45 handgun with a small magazine capacity."
|
||||
icon_state = "m1911"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
mag_type = /obj/item/ammo_box/magazine/m45
|
||||
can_suppress = 0
|
||||
|
||||
//Enforcer//
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer
|
||||
name = "Enforcer"
|
||||
desc = "A pistol of modern design."
|
||||
icon_state = "enforcer_grey"
|
||||
force = 10
|
||||
mag_type = /obj/item/ammo_box/magazine/enforcer
|
||||
can_suppress = TRUE
|
||||
unique_reskin = TRUE
|
||||
can_flashlight = TRUE
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/New()
|
||||
..()
|
||||
options["Grey slide"] = "enforcer_grey"
|
||||
options["Red slide"] = "enforcer_red"
|
||||
options["Green slide"] = "enforcer_green"
|
||||
options["Tan slide"] = "enforcer_tan"
|
||||
options["Black slide"] = "enforcer_black"
|
||||
options["Green Handle"] = "enforcer_greengrip"
|
||||
options["Tan Handle"] = "enforcer_tangrip"
|
||||
options["Red Handle"] = "enforcer_redgrip"
|
||||
options["Cancel"] = null
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/update_icon()
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin][chambered ? "" : "-e"]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
|
||||
overlays.Cut()
|
||||
if(suppressed)
|
||||
overlays += image(icon = icon, icon_state = "enforcer_supp", pixel_x = 4)
|
||||
if(gun_light)
|
||||
var/iconF = "Enforcer_light"
|
||||
if(gun_light.on)
|
||||
iconF = "Enforcer_light-on"
|
||||
overlays += image(icon = icon, icon_state = iconF, pixel_x = 0)
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/ui_action_click()
|
||||
toggle_gunlight()
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/lethal
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/lethal/New()
|
||||
magazine = new/obj/item/ammo_box/magazine/enforcer/lethal
|
||||
..()
|
||||
|
||||
//Desert Eagle//
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle
|
||||
name = "desert eagle"
|
||||
desc = "A robust .50 AE handgun."
|
||||
icon_state = "deagle"
|
||||
force = 14.0
|
||||
mag_type = /obj/item/ammo_box/magazine/m50
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistolH.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/hpistol_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/hpistol_magout.ogg'
|
||||
can_suppress = 0
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle/gold
|
||||
desc = "A gold plated desert eagle folded over a million times by superior martian gunsmiths. Uses .50 AE ammo."
|
||||
icon_state = "deagleg"
|
||||
item_state = "deagleg"
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle/camo
|
||||
desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo."
|
||||
icon_state = "deaglecamo"
|
||||
item_state = "deagleg"
|
||||
|
||||
//APS Pistol//
|
||||
/obj/item/gun/projectile/automatic/pistol/APS
|
||||
name = "stechkin APS pistol"
|
||||
desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo."
|
||||
icon_state = "aps"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "combat=3;materials=2;syndicate=3"
|
||||
mag_type = /obj/item/ammo_box/magazine/pistolm9mm
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
//Stetchkin//
|
||||
/obj/item/gun/projectile/automatic/pistol
|
||||
name = "stechkin pistol"
|
||||
desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors."
|
||||
icon_state = "pistol"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "combat=3;materials=2;syndicate=4"
|
||||
mag_type = /obj/item/ammo_box/magazine/m10mm
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/pistol_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/pistol_magout.ogg'
|
||||
can_suppress = 1
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/isHandgun()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
|
||||
return
|
||||
|
||||
//M1911//
|
||||
/obj/item/gun/projectile/automatic/pistol/m1911
|
||||
name = "\improper M1911"
|
||||
desc = "A classic .45 handgun with a small magazine capacity."
|
||||
icon_state = "m1911"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
mag_type = /obj/item/ammo_box/magazine/m45
|
||||
can_suppress = 0
|
||||
|
||||
//Enforcer//
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer
|
||||
name = "Enforcer"
|
||||
desc = "A pistol of modern design."
|
||||
icon_state = "enforcer_grey"
|
||||
force = 10
|
||||
mag_type = /obj/item/ammo_box/magazine/enforcer
|
||||
can_suppress = TRUE
|
||||
unique_reskin = TRUE
|
||||
can_flashlight = TRUE
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/New()
|
||||
..()
|
||||
options["Grey slide"] = "enforcer_grey"
|
||||
options["Red slide"] = "enforcer_red"
|
||||
options["Green slide"] = "enforcer_green"
|
||||
options["Tan slide"] = "enforcer_tan"
|
||||
options["Black slide"] = "enforcer_black"
|
||||
options["Green Handle"] = "enforcer_greengrip"
|
||||
options["Tan Handle"] = "enforcer_tangrip"
|
||||
options["Red Handle"] = "enforcer_redgrip"
|
||||
options["Cancel"] = null
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/update_icon()
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin][chambered ? "" : "-e"]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
|
||||
overlays.Cut()
|
||||
if(suppressed)
|
||||
overlays += image(icon = icon, icon_state = "enforcer_supp", pixel_x = 4)
|
||||
if(gun_light)
|
||||
var/iconF = "Enforcer_light"
|
||||
if(gun_light.on)
|
||||
iconF = "Enforcer_light-on"
|
||||
overlays += image(icon = icon, icon_state = iconF, pixel_x = 0)
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/ui_action_click()
|
||||
toggle_gunlight()
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/lethal
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/enforcer/lethal/New()
|
||||
magazine = new/obj/item/ammo_box/magazine/enforcer/lethal
|
||||
..()
|
||||
|
||||
//Desert Eagle//
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle
|
||||
name = "desert eagle"
|
||||
desc = "A robust .50 AE handgun."
|
||||
icon_state = "deagle"
|
||||
force = 14.0
|
||||
mag_type = /obj/item/ammo_box/magazine/m50
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistolH.ogg'
|
||||
magin_sound = 'sound/weapons/gun_interactions/hpistol_magin.ogg'
|
||||
magout_sound = 'sound/weapons/gun_interactions/hpistol_magout.ogg'
|
||||
can_suppress = 0
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle/update_icon()
|
||||
..()
|
||||
icon_state = "[initial(icon_state)][magazine ? "" : "-e"]"
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle/gold
|
||||
desc = "A gold plated desert eagle folded over a million times by superior martian gunsmiths. Uses .50 AE ammo."
|
||||
icon_state = "deagleg"
|
||||
item_state = "deagleg"
|
||||
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle/camo
|
||||
desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo."
|
||||
icon_state = "deaglecamo"
|
||||
item_state = "deagleg"
|
||||
|
||||
//APS Pistol//
|
||||
/obj/item/gun/projectile/automatic/pistol/APS
|
||||
name = "stechkin APS pistol"
|
||||
desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo."
|
||||
icon_state = "aps"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "combat=3;materials=2;syndicate=3"
|
||||
mag_type = /obj/item/ammo_box/magazine/pistolm9mm
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
|
||||
@@ -1,473 +1,475 @@
|
||||
/obj/item/gun/projectile/revolver
|
||||
name = "\improper .357 revolver"
|
||||
desc = "A suspicious revolver. Uses .357 ammo."
|
||||
icon_state = "revolver"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
|
||||
origin_tech = "combat=3;materials=2"
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_strong.ogg'
|
||||
|
||||
/obj/item/gun/projectile/revolver/New()
|
||||
..()
|
||||
if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder))
|
||||
verbs -= /obj/item/gun/projectile/revolver/verb/spin
|
||||
|
||||
/obj/item/gun/projectile/revolver/chamber_round(var/spin = 1)
|
||||
if(spin)
|
||||
chambered = magazine.get_round(1)
|
||||
else
|
||||
chambered = magazine.stored_ammo[1]
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
..()
|
||||
chamber_round(1)
|
||||
|
||||
/obj/item/gun/projectile/revolver/process_chamber()
|
||||
return ..(0, 1)
|
||||
|
||||
/obj/item/gun/projectile/revolver/attackby(obj/item/A, mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/num_loaded = magazine.attackby(A, user, params, 1)
|
||||
if(num_loaded)
|
||||
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src].</span>")
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
chamber_round(0)
|
||||
|
||||
/obj/item/gun/projectile/revolver/attack_self(mob/living/user)
|
||||
var/num_unloaded = 0
|
||||
chambered = null
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
if(CB)
|
||||
CB.loc = get_turf(loc)
|
||||
CB.SpinAnimation(10, 1)
|
||||
CB.update_icon()
|
||||
playsound(get_turf(CB), "casingdrop", 60, 1)
|
||||
num_unloaded++
|
||||
if(num_unloaded)
|
||||
to_chat(user, "<span class='notice'>You unload [num_unloaded] shell\s from [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/verb/spin()
|
||||
set name = "Spin Chamber"
|
||||
set category = "Object"
|
||||
set desc = "Click to spin your revolver's chamber."
|
||||
|
||||
var/mob/M = usr
|
||||
|
||||
if(M.stat || !in_range(M,src))
|
||||
return
|
||||
|
||||
if(istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder))
|
||||
var/obj/item/ammo_box/magazine/internal/cylinder/C = magazine
|
||||
C.spin()
|
||||
chamber_round(0)
|
||||
playsound(loc, 'sound/weapons/revolver_spin.ogg', 50, 1)
|
||||
usr.visible_message("[usr] spins [src]'s chamber.", "<span class='notice'>You spin [src]'s chamber.</span>")
|
||||
else
|
||||
verbs -= /obj/item/gun/projectile/revolver/verb/spin
|
||||
|
||||
/obj/item/gun/projectile/revolver/can_shoot()
|
||||
return get_ammo(0,0)
|
||||
|
||||
/obj/item/gun/projectile/revolver/get_ammo(countchambered = 0, countempties = 1)
|
||||
var/boolets = 0 //mature var names for mature people
|
||||
if(chambered && countchambered)
|
||||
boolets++
|
||||
if(magazine)
|
||||
boolets += magazine.ammo_count(countempties)
|
||||
return boolets
|
||||
|
||||
/obj/item/gun/projectile/revolver/examine(mob/user)
|
||||
. = ..()
|
||||
. += "[get_ammo(0,0)] of those are live rounds."
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective
|
||||
desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds."
|
||||
name = "\improper .38 Mars Special"
|
||||
icon_state = "detective"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38
|
||||
unique_rename = 1
|
||||
unique_reskin = 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective/New()
|
||||
..()
|
||||
options["The Original"] = "detective"
|
||||
options["Leopard Spots"] = "detective_leopard"
|
||||
options["Black Panther"] = "detective_panther"
|
||||
options["Gold Trim"] = "detective_gold"
|
||||
options["The Peacemaker"] = "detective_peacemaker"
|
||||
options["Cancel"] = null
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "")
|
||||
if(magazine.caliber != initial(magazine.caliber))
|
||||
if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
to_chat(user, "<span class='userdanger'>[src] blows up in your face!</span>")
|
||||
user.take_organ_damage(0,20)
|
||||
user.unEquip(src)
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/screwdriver))
|
||||
if(magazine.caliber == "38")
|
||||
to_chat(user, "<span class='notice'>You begin to reinforce the barrel of [src]...</span>")
|
||||
if(magazine.ammo_count())
|
||||
afterattack(user, user) //you know the drill
|
||||
user.visible_message("<span class='danger'>[src] goes off!</span>", "<span class='userdanger'>[src] goes off in your face!</span>")
|
||||
return
|
||||
if(do_after(user, 30 * A.toolspeed, target = src))
|
||||
if(magazine.ammo_count())
|
||||
to_chat(user, "<span class='warning'>You can't modify it!</span>")
|
||||
return
|
||||
magazine.caliber = "357"
|
||||
desc = "The barrel and chamber assembly seems to have been modified."
|
||||
to_chat(user, "<span class='notice'>You reinforce the barrel of [src]. Now it will fire .357 rounds.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin to revert the modifications to [src]...</span>")
|
||||
if(magazine.ammo_count())
|
||||
afterattack(user, user) //and again
|
||||
user.visible_message("<span class='danger'>[src] goes off!</span>", "<span class='userdanger'>[src] goes off in your face!</span>")
|
||||
return
|
||||
if(do_after(user, 30 * A.toolspeed, target = src))
|
||||
if(magazine.ammo_count())
|
||||
to_chat(user, "<span class='warning'>You can't modify it!</span>")
|
||||
return
|
||||
magazine.caliber = "38"
|
||||
desc = initial(desc)
|
||||
to_chat(user, "<span class='notice'>You remove the modifications on [src]. Now it will fire .38 rounds.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun //Summoned by the Finger Gun spell, from advanced mimery traitor item
|
||||
name = "\improper finger gun"
|
||||
desc = "Bang bang bang!"
|
||||
icon_state = "fingergun"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38/invisible
|
||||
origin_tech = ""
|
||||
flags = ABSTRACT | NODROP | DROPDEL
|
||||
slot_flags = null
|
||||
fire_sound = null
|
||||
fire_sound_text = null
|
||||
lefthand_file = null
|
||||
righthand_file = null
|
||||
clumsy_check = 0 //Stole your uplink! Honk!
|
||||
needs_permit = 0 //go away beepsky
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/fake
|
||||
desc = "Pew pew pew!"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38/invisible/fake
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/New()
|
||||
..()
|
||||
verbs -= /obj/item/gun/projectile/revolver/verb/spin
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/shoot_with_empty_chamber(/*mob/living/user as mob|obj*/)
|
||||
to_chat(usr, "<span class='warning'>You are out of ammo! You holster your fingers.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!user.mind.miming)
|
||||
to_chat(usr, "<span class='warning'>You must dedicate yourself to silence first. Use your fingers if you wish to holster them.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/attackby(obj/item/A, mob/user, params)
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/attack_self(mob/living/user)
|
||||
to_chat(usr, "<span class='notice'>You holster your fingers. Another time.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/mateba
|
||||
name = "\improper Unica 6 auto-revolver"
|
||||
desc = "A retro high-powered autorevolver typically used by officers of the New Russia military. Uses .357 ammo." //>10mm hole >.357
|
||||
icon_state = "mateba"
|
||||
|
||||
/obj/item/gun/projectile/revolver/golden
|
||||
name = "\improper Golden revolver"
|
||||
desc = "This ain't no game, ain't never been no show, And I'll gladly gun down the oldest lady you know. Uses .357 ammo."
|
||||
icon_state = "goldrevolver"
|
||||
fire_sound = 'sound/weapons/resonator_blast.ogg'
|
||||
recoil = 8
|
||||
|
||||
/obj/item/gun/projectile/revolver/nagant
|
||||
name = "nagant revolver"
|
||||
desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo."
|
||||
icon_state = "nagant"
|
||||
origin_tech = "combat=3"
|
||||
can_suppress = 1
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762
|
||||
|
||||
// A gun to play Russian Roulette!
|
||||
// You can spin the chamber to randomize the position of the bullet.
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian
|
||||
name = "\improper Russian Revolver"
|
||||
desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull."
|
||||
origin_tech = "combat=2;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/rus357
|
||||
var/spun = 0
|
||||
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/New()
|
||||
..()
|
||||
Spin()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/proc/Spin()
|
||||
chambered = null
|
||||
var/random = rand(1, magazine.max_ammo)
|
||||
if(random <= get_ammo(0,0))
|
||||
chamber_round()
|
||||
spun = 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/attackby(obj/item/A, mob/user, params)
|
||||
var/num_loaded = ..()
|
||||
if(num_loaded)
|
||||
user.visible_message("[user] loads a single bullet into the revolver and spins the chamber.", "<span class='notice'>You load a single bullet into the chamber and spin it.</span>")
|
||||
else
|
||||
user.visible_message("[user] spins the chamber of the revolver.", "<span class='notice'>You spin the revolver's chamber.</span>")
|
||||
if(get_ammo() > 0)
|
||||
Spin()
|
||||
update_icon()
|
||||
A.update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/attack_self(mob/user)
|
||||
if(!spun && can_shoot())
|
||||
user.visible_message("[user] spins the chamber of the revolver.", "<span class='notice'>You spin the revolver's chamber.</span>")
|
||||
Spin()
|
||||
else
|
||||
var/num_unloaded = 0
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round()
|
||||
chambered = null
|
||||
CB.loc = get_turf(loc)
|
||||
CB.update_icon()
|
||||
playsound(get_turf(CB), "casingdrop", 60, 1)
|
||||
num_unloaded++
|
||||
if(num_unloaded)
|
||||
to_chat(user, "<span class='notice'>You unload [num_unloaded] shell\s from [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params)
|
||||
if(flag)
|
||||
if(!(target in user.contents) && ismob(target))
|
||||
if(user.a_intent == INTENT_HARM) // Flogging action
|
||||
return
|
||||
|
||||
if(isliving(user))
|
||||
if(!can_trigger_gun(user))
|
||||
return
|
||||
if(target != user)
|
||||
if(ismob(target))
|
||||
to_chat(user, "<span class='warning'>A mechanism prevents you from shooting anyone but yourself!</span>")
|
||||
return
|
||||
|
||||
if(ishuman(user))
|
||||
if(!spun)
|
||||
to_chat(user, "<span class='warning'>You need to spin the revolver's chamber first!</span>")
|
||||
return
|
||||
|
||||
spun = 0
|
||||
|
||||
if(chambered)
|
||||
var/obj/item/ammo_casing/AC = chambered
|
||||
if(AC.fire(user, user))
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
var/zone = check_zone(user.zone_selected)
|
||||
if(zone == "head" || zone == "eyes" || zone == "mouth")
|
||||
shoot_self(user, zone)
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user.name] cowardly fires [src] at [user.p_their()] [zone]!</span>", "<span class='userdanger'>You cowardly fire [src] at your [zone]!</span>", "<span class='italics'>You hear a gunshot!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>*click*</span>")
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head")
|
||||
user.apply_damage(300, BRUTE, affecting)
|
||||
user.visible_message("<span class='danger'>[user.name] fires [src] at [user.p_their()] head!</span>", "<span class='userdanger'>You fire [src] at your head!</span>", "<span class='italics'>You hear a gunshot!</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/soul
|
||||
name = "cursed Russian revolver"
|
||||
desc = "To play with this revolver requires wagering your very soul."
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/soul/shoot_self(mob/living/user)
|
||||
..()
|
||||
var/obj/item/soulstone/anybody/SS = new /obj/item/soulstone/anybody(get_turf(src))
|
||||
if(!SS.transfer_soul("FORCE", user)) //Something went wrong
|
||||
qdel(SS)
|
||||
return
|
||||
user.visible_message("<span class='danger'>[user.name]'s soul is captured by \the [src]!</span>", "<span class='userdanger'>You've lost the gamble! Your soul is forfeit!</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/capgun
|
||||
name = "cap gun"
|
||||
desc = "Looks almost like the real thing! Ages 8 and up."
|
||||
origin_tech = null
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/cap
|
||||
|
||||
/////////////////////////////
|
||||
// DOUBLE BARRELED SHOTGUN //
|
||||
/////////////////////////////
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel
|
||||
name = "double-barreled shotgun"
|
||||
desc = "A true classic."
|
||||
icon_state = "dshotgun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/dual
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
sawn_desc = "Omar's coming!"
|
||||
unique_rename = 1
|
||||
unique_reskin = 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/New()
|
||||
..()
|
||||
options["Default"] = "dshotgun"
|
||||
options["Dark Red Finish"] = "dshotgun-d"
|
||||
options["Ash"] = "dshotgun-f"
|
||||
options["Faded Grey"] = "dshotgun-g"
|
||||
options["Maple"] = "dshotgun-l"
|
||||
options["Rosewood"] = "dshotgun-p"
|
||||
options["Cancel"] = null
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing))
|
||||
chamber_round()
|
||||
if(istype(A, /obj/item/melee/energy))
|
||||
var/obj/item/melee/energy/W = A
|
||||
if(W.active)
|
||||
sawoff(user)
|
||||
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
|
||||
sawoff(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user)
|
||||
var/num_unloaded = 0
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
chambered = null
|
||||
CB.loc = get_turf(loc)
|
||||
CB.SpinAnimation(10, 1)
|
||||
CB.update_icon()
|
||||
playsound(get_turf(CB), 'sound/weapons/gun_interactions/shotgun_fall.ogg', 70, 1)
|
||||
num_unloaded++
|
||||
if(num_unloaded)
|
||||
to_chat(user, "<span class = 'notice'>You break open \the [src] and unload [num_unloaded] shell\s.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/isHandgun() //contrary to popular opinion, double barrels are not, shockingly, handguns
|
||||
return 0
|
||||
|
||||
// IMPROVISED SHOTGUN //
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised
|
||||
name = "improvised shotgun"
|
||||
desc = "Essentially a tube that aims shotgun shells."
|
||||
icon_state = "ishotgun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
slot_flags = null
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
sawn_desc = "I'm just here for the gasoline."
|
||||
unique_rename = 0
|
||||
unique_reskin = 0
|
||||
var/slung = 0
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/stack/cable_coil) && !sawn_state)
|
||||
var/obj/item/stack/cable_coil/C = A
|
||||
if(C.use(10))
|
||||
slot_flags = SLOT_BACK
|
||||
icon_state = "ishotgunsling"
|
||||
to_chat(user, "<span class='notice'>You tie the lengths of cable to the shotgun, making a sling.</span>")
|
||||
slung = 1
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need at least ten lengths of cable if you want to make a sling.</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/update_icon()
|
||||
..()
|
||||
if(slung && (slot_flags & SLOT_BELT) )
|
||||
slung = 0
|
||||
icon_state = "ishotgun-sawn"
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/sawoff(mob/user)
|
||||
. = ..()
|
||||
if(. && slung) //sawing off the gun removes the sling
|
||||
new /obj/item/stack/cable_coil(get_turf(src), 10)
|
||||
slung = 0
|
||||
update_icon()
|
||||
|
||||
//caneshotgun
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane
|
||||
name = "cane"
|
||||
desc = "A cane used by a true gentleman. Or a clown."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
icon_state = "cane"
|
||||
item_state = "stick"
|
||||
sawn_state = SAWN_OFF
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = 10
|
||||
can_unsuppress = 0
|
||||
slot_flags = null
|
||||
origin_tech = "" // NO GIVAWAYS
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised/cane
|
||||
sawn_desc = "I'm sorry, but why did you saw your cane in the first place?"
|
||||
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_silenced.ogg'
|
||||
suppressed = 1
|
||||
needs_permit = 0 //its just a cane beepsky.....
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/is_crutch()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/stack/cable_coil))
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/examine(mob/user) // HAD TO REPEAT EXAMINE CODE BECAUSE GUN CODE DOESNT STEALTH
|
||||
var/f_name = "\a [src]."
|
||||
if(blood_DNA && !istype(src, /obj/effect/decal))
|
||||
if(gender == PLURAL)
|
||||
f_name = "some "
|
||||
else
|
||||
f_name = "a "
|
||||
f_name += "<span class='danger'>blood-stained</span> [name]!"
|
||||
|
||||
. = list("[bicon(src)] That's [f_name]")
|
||||
|
||||
if(desc)
|
||||
. += desc
|
||||
/obj/item/gun/projectile/revolver
|
||||
name = "\improper .357 revolver"
|
||||
desc = "A suspicious revolver. Uses .357 ammo."
|
||||
icon_state = "revolver"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
|
||||
origin_tech = "combat=3;materials=2"
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_strong.ogg'
|
||||
|
||||
/obj/item/gun/projectile/revolver/New()
|
||||
..()
|
||||
if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder))
|
||||
verbs -= /obj/item/gun/projectile/revolver/verb/spin
|
||||
|
||||
/obj/item/gun/projectile/revolver/chamber_round(var/spin = 1)
|
||||
if(spin)
|
||||
chambered = magazine.get_round(1)
|
||||
else
|
||||
chambered = magazine.stored_ammo[1]
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
..()
|
||||
chamber_round(1)
|
||||
|
||||
/obj/item/gun/projectile/revolver/process_chamber()
|
||||
return ..(0, 1)
|
||||
|
||||
/obj/item/gun/projectile/revolver/attackby(obj/item/A, mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/num_loaded = magazine.attackby(A, user, params, 1)
|
||||
if(num_loaded)
|
||||
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src].</span>")
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
chamber_round(0)
|
||||
|
||||
/obj/item/gun/projectile/revolver/attack_self(mob/living/user)
|
||||
var/num_unloaded = 0
|
||||
chambered = null
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
if(CB)
|
||||
CB.loc = get_turf(loc)
|
||||
CB.SpinAnimation(10, 1)
|
||||
CB.update_icon()
|
||||
playsound(get_turf(CB), "casingdrop", 60, 1)
|
||||
num_unloaded++
|
||||
if(num_unloaded)
|
||||
to_chat(user, "<span class='notice'>You unload [num_unloaded] shell\s from [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/verb/spin()
|
||||
set name = "Spin Chamber"
|
||||
set category = "Object"
|
||||
set desc = "Click to spin your revolver's chamber."
|
||||
|
||||
var/mob/M = usr
|
||||
|
||||
if(M.stat || !in_range(M,src))
|
||||
return
|
||||
|
||||
if(istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder))
|
||||
var/obj/item/ammo_box/magazine/internal/cylinder/C = magazine
|
||||
C.spin()
|
||||
chamber_round(0)
|
||||
playsound(loc, 'sound/weapons/revolver_spin.ogg', 50, 1)
|
||||
usr.visible_message("[usr] spins [src]'s chamber.", "<span class='notice'>You spin [src]'s chamber.</span>")
|
||||
else
|
||||
verbs -= /obj/item/gun/projectile/revolver/verb/spin
|
||||
|
||||
/obj/item/gun/projectile/revolver/can_shoot()
|
||||
return get_ammo(0,0)
|
||||
|
||||
/obj/item/gun/projectile/revolver/get_ammo(countchambered = 0, countempties = 1)
|
||||
var/boolets = 0 //mature var names for mature people
|
||||
if(chambered && countchambered)
|
||||
boolets++
|
||||
if(magazine)
|
||||
boolets += magazine.ammo_count(countempties)
|
||||
return boolets
|
||||
|
||||
/obj/item/gun/projectile/revolver/examine(mob/user)
|
||||
. = ..()
|
||||
. += "[get_ammo(0,0)] of those are live rounds."
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective
|
||||
desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds."
|
||||
name = "\improper .38 Mars Special"
|
||||
icon_state = "detective"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38
|
||||
unique_rename = 1
|
||||
unique_reskin = 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective/New()
|
||||
..()
|
||||
options["The Original"] = "detective"
|
||||
options["Leopard Spots"] = "detective_leopard"
|
||||
options["Black Panther"] = "detective_panther"
|
||||
options["Gold Trim"] = "detective_gold"
|
||||
options["The Peacemaker"] = "detective_peacemaker"
|
||||
options["Cancel"] = null
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "")
|
||||
if(magazine.caliber != initial(magazine.caliber))
|
||||
if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
to_chat(user, "<span class='userdanger'>[src] blows up in your face!</span>")
|
||||
user.take_organ_damage(0,20)
|
||||
user.unEquip(src)
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/detective/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(magazine.caliber == "38")
|
||||
to_chat(user, "<span class='notice'>You begin to reinforce the barrel of [src]...</span>")
|
||||
if(magazine.ammo_count())
|
||||
afterattack(user, user) //you know the drill
|
||||
user.visible_message("<span class='danger'>[src] goes off!</span>", "<span class='userdanger'>[src] goes off in your face!</span>")
|
||||
return
|
||||
if(!I.use_tool(src, user, 30, volume = I.tool_volume))
|
||||
return
|
||||
if(magazine.ammo_count())
|
||||
to_chat(user, "<span class='warning'>You can't modify it!</span>")
|
||||
return
|
||||
magazine.caliber = "357"
|
||||
desc = "The barrel and chamber assembly seems to have been modified."
|
||||
to_chat(user, "<span class='notice'>You reinforce the barrel of [src]. Now it will fire .357 rounds.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin to revert the modifications to [src]...</span>")
|
||||
if(magazine.ammo_count())
|
||||
afterattack(user, user) //and again
|
||||
user.visible_message("<span class='danger'>[src] goes off!</span>", "<span class='userdanger'>[src] goes off in your face!</span>")
|
||||
return
|
||||
if(!I.use_tool(src, user, 30, volume = I.tool_volume))
|
||||
return
|
||||
if(magazine.ammo_count())
|
||||
to_chat(user, "<span class='warning'>You can't modify it!</span>")
|
||||
return
|
||||
magazine.caliber = "38"
|
||||
desc = initial(desc)
|
||||
to_chat(user, "<span class='notice'>You remove the modifications on [src]. Now it will fire .38 rounds.</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun //Summoned by the Finger Gun spell, from advanced mimery traitor item
|
||||
name = "\improper finger gun"
|
||||
desc = "Bang bang bang!"
|
||||
icon_state = "fingergun"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38/invisible
|
||||
origin_tech = ""
|
||||
flags = ABSTRACT | NODROP | DROPDEL
|
||||
slot_flags = null
|
||||
fire_sound = null
|
||||
fire_sound_text = null
|
||||
lefthand_file = null
|
||||
righthand_file = null
|
||||
clumsy_check = 0 //Stole your uplink! Honk!
|
||||
needs_permit = 0 //go away beepsky
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/fake
|
||||
desc = "Pew pew pew!"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38/invisible/fake
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/New()
|
||||
..()
|
||||
verbs -= /obj/item/gun/projectile/revolver/verb/spin
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/shoot_with_empty_chamber(/*mob/living/user as mob|obj*/)
|
||||
to_chat(usr, "<span class='warning'>You are out of ammo! You holster your fingers.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!user.mind.miming)
|
||||
to_chat(usr, "<span class='warning'>You must dedicate yourself to silence first. Use your fingers if you wish to holster them.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/attackby(obj/item/A, mob/user, params)
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/fingergun/attack_self(mob/living/user)
|
||||
to_chat(usr, "<span class='notice'>You holster your fingers. Another time.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/mateba
|
||||
name = "\improper Unica 6 auto-revolver"
|
||||
desc = "A retro high-powered autorevolver typically used by officers of the New Russia military. Uses .357 ammo." //>10mm hole >.357
|
||||
icon_state = "mateba"
|
||||
|
||||
/obj/item/gun/projectile/revolver/golden
|
||||
name = "\improper Golden revolver"
|
||||
desc = "This ain't no game, ain't never been no show, And I'll gladly gun down the oldest lady you know. Uses .357 ammo."
|
||||
icon_state = "goldrevolver"
|
||||
fire_sound = 'sound/weapons/resonator_blast.ogg'
|
||||
recoil = 8
|
||||
|
||||
/obj/item/gun/projectile/revolver/nagant
|
||||
name = "nagant revolver"
|
||||
desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo."
|
||||
icon_state = "nagant"
|
||||
origin_tech = "combat=3"
|
||||
can_suppress = 1
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762
|
||||
|
||||
// A gun to play Russian Roulette!
|
||||
// You can spin the chamber to randomize the position of the bullet.
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian
|
||||
name = "\improper Russian Revolver"
|
||||
desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull."
|
||||
origin_tech = "combat=2;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/rus357
|
||||
var/spun = 0
|
||||
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/New()
|
||||
..()
|
||||
Spin()
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/proc/Spin()
|
||||
chambered = null
|
||||
var/random = rand(1, magazine.max_ammo)
|
||||
if(random <= get_ammo(0,0))
|
||||
chamber_round()
|
||||
spun = 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/attackby(obj/item/A, mob/user, params)
|
||||
var/num_loaded = ..()
|
||||
if(num_loaded)
|
||||
user.visible_message("[user] loads a single bullet into the revolver and spins the chamber.", "<span class='notice'>You load a single bullet into the chamber and spin it.</span>")
|
||||
else
|
||||
user.visible_message("[user] spins the chamber of the revolver.", "<span class='notice'>You spin the revolver's chamber.</span>")
|
||||
if(get_ammo() > 0)
|
||||
Spin()
|
||||
update_icon()
|
||||
A.update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/attack_self(mob/user)
|
||||
if(!spun && can_shoot())
|
||||
user.visible_message("[user] spins the chamber of the revolver.", "<span class='notice'>You spin the revolver's chamber.</span>")
|
||||
Spin()
|
||||
else
|
||||
var/num_unloaded = 0
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round()
|
||||
chambered = null
|
||||
CB.loc = get_turf(loc)
|
||||
CB.update_icon()
|
||||
playsound(get_turf(CB), "casingdrop", 60, 1)
|
||||
num_unloaded++
|
||||
if(num_unloaded)
|
||||
to_chat(user, "<span class='notice'>You unload [num_unloaded] shell\s from [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params)
|
||||
if(flag)
|
||||
if(!(target in user.contents) && ismob(target))
|
||||
if(user.a_intent == INTENT_HARM) // Flogging action
|
||||
return
|
||||
|
||||
if(isliving(user))
|
||||
if(!can_trigger_gun(user))
|
||||
return
|
||||
if(target != user)
|
||||
if(ismob(target))
|
||||
to_chat(user, "<span class='warning'>A mechanism prevents you from shooting anyone but yourself!</span>")
|
||||
return
|
||||
|
||||
if(ishuman(user))
|
||||
if(!spun)
|
||||
to_chat(user, "<span class='warning'>You need to spin the revolver's chamber first!</span>")
|
||||
return
|
||||
|
||||
spun = 0
|
||||
|
||||
if(chambered)
|
||||
var/obj/item/ammo_casing/AC = chambered
|
||||
if(AC.fire(user, user))
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
var/zone = check_zone(user.zone_selected)
|
||||
if(zone == "head" || zone == "eyes" || zone == "mouth")
|
||||
shoot_self(user, zone)
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user.name] cowardly fires [src] at [user.p_their()] [zone]!</span>", "<span class='userdanger'>You cowardly fire [src] at your [zone]!</span>", "<span class='italics'>You hear a gunshot!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>*click*</span>")
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head")
|
||||
user.apply_damage(300, BRUTE, affecting)
|
||||
user.visible_message("<span class='danger'>[user.name] fires [src] at [user.p_their()] head!</span>", "<span class='userdanger'>You fire [src] at your head!</span>", "<span class='italics'>You hear a gunshot!</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/soul
|
||||
name = "cursed Russian revolver"
|
||||
desc = "To play with this revolver requires wagering your very soul."
|
||||
|
||||
/obj/item/gun/projectile/revolver/russian/soul/shoot_self(mob/living/user)
|
||||
..()
|
||||
var/obj/item/soulstone/anybody/SS = new /obj/item/soulstone/anybody(get_turf(src))
|
||||
if(!SS.transfer_soul("FORCE", user)) //Something went wrong
|
||||
qdel(SS)
|
||||
return
|
||||
user.visible_message("<span class='danger'>[user.name]'s soul is captured by \the [src]!</span>", "<span class='userdanger'>You've lost the gamble! Your soul is forfeit!</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/capgun
|
||||
name = "cap gun"
|
||||
desc = "Looks almost like the real thing! Ages 8 and up."
|
||||
origin_tech = null
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/cap
|
||||
|
||||
/////////////////////////////
|
||||
// DOUBLE BARRELED SHOTGUN //
|
||||
/////////////////////////////
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel
|
||||
name = "double-barreled shotgun"
|
||||
desc = "A true classic."
|
||||
icon_state = "dshotgun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/dual
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
sawn_desc = "Omar's coming!"
|
||||
unique_rename = 1
|
||||
unique_reskin = 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/New()
|
||||
..()
|
||||
options["Default"] = "dshotgun"
|
||||
options["Dark Red Finish"] = "dshotgun-d"
|
||||
options["Ash"] = "dshotgun-f"
|
||||
options["Faded Grey"] = "dshotgun-g"
|
||||
options["Maple"] = "dshotgun-l"
|
||||
options["Rosewood"] = "dshotgun-p"
|
||||
options["Cancel"] = null
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing))
|
||||
chamber_round()
|
||||
if(istype(A, /obj/item/melee/energy))
|
||||
var/obj/item/melee/energy/W = A
|
||||
if(W.active)
|
||||
sawoff(user)
|
||||
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
|
||||
sawoff(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user)
|
||||
var/num_unloaded = 0
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
chambered = null
|
||||
CB.loc = get_turf(loc)
|
||||
CB.SpinAnimation(10, 1)
|
||||
CB.update_icon()
|
||||
playsound(get_turf(CB), 'sound/weapons/gun_interactions/shotgun_fall.ogg', 70, 1)
|
||||
num_unloaded++
|
||||
if(num_unloaded)
|
||||
to_chat(user, "<span class = 'notice'>You break open \the [src] and unload [num_unloaded] shell\s.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/isHandgun() //contrary to popular opinion, double barrels are not, shockingly, handguns
|
||||
return 0
|
||||
|
||||
// IMPROVISED SHOTGUN //
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised
|
||||
name = "improvised shotgun"
|
||||
desc = "Essentially a tube that aims shotgun shells."
|
||||
icon_state = "ishotgun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
slot_flags = null
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
sawn_desc = "I'm just here for the gasoline."
|
||||
unique_rename = 0
|
||||
unique_reskin = 0
|
||||
var/slung = 0
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/stack/cable_coil) && !sawn_state)
|
||||
var/obj/item/stack/cable_coil/C = A
|
||||
if(C.use(10))
|
||||
slot_flags = SLOT_BACK
|
||||
icon_state = "ishotgunsling"
|
||||
to_chat(user, "<span class='notice'>You tie the lengths of cable to the shotgun, making a sling.</span>")
|
||||
slung = 1
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need at least ten lengths of cable if you want to make a sling.</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/update_icon()
|
||||
..()
|
||||
if(slung && (slot_flags & SLOT_BELT) )
|
||||
slung = 0
|
||||
icon_state = "ishotgun-sawn"
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/sawoff(mob/user)
|
||||
. = ..()
|
||||
if(. && slung) //sawing off the gun removes the sling
|
||||
new /obj/item/stack/cable_coil(get_turf(src), 10)
|
||||
slung = 0
|
||||
update_icon()
|
||||
|
||||
//caneshotgun
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane
|
||||
name = "cane"
|
||||
desc = "A cane used by a true gentleman. Or a clown."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
icon_state = "cane"
|
||||
item_state = "stick"
|
||||
sawn_state = SAWN_OFF
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = 10
|
||||
can_unsuppress = 0
|
||||
slot_flags = null
|
||||
origin_tech = "" // NO GIVAWAYS
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised/cane
|
||||
sawn_desc = "I'm sorry, but why did you saw your cane in the first place?"
|
||||
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_silenced.ogg'
|
||||
suppressed = 1
|
||||
needs_permit = 0 //its just a cane beepsky.....
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/is_crutch()
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/update_icon()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/stack/cable_coil))
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/revolver/doublebarrel/improvised/cane/examine(mob/user) // HAD TO REPEAT EXAMINE CODE BECAUSE GUN CODE DOESNT STEALTH
|
||||
var/f_name = "\a [src]."
|
||||
if(blood_DNA && !istype(src, /obj/effect/decal))
|
||||
if(gender == PLURAL)
|
||||
f_name = "some "
|
||||
else
|
||||
f_name = "a "
|
||||
f_name += "<span class='danger'>blood-stained</span> [name]!"
|
||||
|
||||
. = list("[bicon(src)] That's [f_name]")
|
||||
|
||||
if(desc)
|
||||
. += desc
|
||||
|
||||
@@ -1,331 +1,331 @@
|
||||
/obj/item/gun/projectile/shotgun
|
||||
name = "shotgun"
|
||||
desc = "A traditional shotgun with wood furniture and a four-shell capacity underneath."
|
||||
icon_state = "shotgun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
origin_tech = "combat=4;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
var/recentpump = 0 // to prevent spammage
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
|
||||
/obj/item/gun/projectile/shotgun/attackby(obj/item/A, mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/num_loaded = magazine.attackby(A, user, params, 1)
|
||||
if(num_loaded)
|
||||
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src]!</span>")
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/process_chamber()
|
||||
return ..(0, 0)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/chamber_round()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/shotgun/can_shoot()
|
||||
if(!chambered)
|
||||
return 0
|
||||
return (chambered.BB ? 1 : 0)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/attack_self(mob/living/user)
|
||||
if(recentpump)
|
||||
return
|
||||
pump(user)
|
||||
recentpump = 1
|
||||
spawn(10)
|
||||
recentpump = 0
|
||||
return
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/proc/pump(mob/M)
|
||||
playsound(M, 'sound/weapons/gun_interactions/shotgunpump.ogg', 60, 1)
|
||||
pump_unload(M)
|
||||
pump_reload(M)
|
||||
update_icon() //I.E. fix the desc
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/proc/pump_unload(mob/M)
|
||||
if(chambered)//We have a shell in the chamber
|
||||
chambered.loc = get_turf(src)//Eject casing
|
||||
chambered.SpinAnimation(5, 1)
|
||||
playsound(src, chambered.drop_sound, 60, 1)
|
||||
chambered = null
|
||||
|
||||
/obj/item/gun/projectile/shotgun/proc/pump_reload(mob/M)
|
||||
if(!magazine.ammo_count())
|
||||
return 0
|
||||
var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing.
|
||||
chambered = AC
|
||||
|
||||
/obj/item/gun/projectile/shotgun/examine(mob/user)
|
||||
. = ..()
|
||||
if(chambered)
|
||||
. += "A [chambered.BB ? "live" : "spent"] one is in the chamber."
|
||||
|
||||
/obj/item/gun/projectile/shotgun/isHandgun() //You cannot, in fact, holster a shotgun.
|
||||
return 0
|
||||
|
||||
/obj/item/gun/projectile/shotgun/lethal
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/lethal
|
||||
|
||||
// RIOT SHOTGUN //
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot //for spawn in the armory
|
||||
name = "riot shotgun"
|
||||
desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control."
|
||||
icon_state = "riotshotgun"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot
|
||||
sawn_desc = "Come with me if you want to live."
|
||||
sawn_state = SAWN_INTACT
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
|
||||
sawoff(user)
|
||||
if(istype(A, /obj/item/melee/energy))
|
||||
var/obj/item/melee/energy/W = A
|
||||
if(W.active)
|
||||
sawoff(user)
|
||||
if(istype(A, /obj/item/pipe))
|
||||
unsaw(A, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/sawoff(mob/user)
|
||||
if(sawn_state == SAWN_OFF)
|
||||
to_chat(user, "<span class='warning'>[src] has already been shortened!</span>")
|
||||
return
|
||||
if(istype(loc, /obj/item/storage)) //To prevent inventory exploits
|
||||
to_chat(user, "<span class='info'>How do you plan to modify [src] while it's in a bag.</span>")
|
||||
return
|
||||
if(chambered) //if the gun is chambering live ammo, shoot self, if chambering empty ammo, 'click'
|
||||
if(chambered.BB)
|
||||
afterattack(user, user)
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
else
|
||||
afterattack(user, user)
|
||||
user.visible_message("The [src] goes click!", "<span class='notice'>The [src] you are holding goes click.</span>")
|
||||
if(magazine.ammo_count()) //Spill the mag onto the floor
|
||||
user.visible_message("<span class='danger'>[user.name] opens [src] up and the shells go goes flying around!</span>", "<span class='userdanger'>You open [src] up and the shells go goes flying everywhere!!</span>")
|
||||
while(get_ammo(0) > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
if(CB)
|
||||
CB.loc = get_turf(loc)
|
||||
CB.update_icon()
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
user.visible_message("[user] shortens \the [src]!", "<span class='notice'>You shorten \the [src].</span>")
|
||||
post_sawoff()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/proc/post_sawoff()
|
||||
name = "assault shotgun"
|
||||
desc = sawn_desc
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
current_skin = "riotshotgun-short"
|
||||
item_state = "gun" //phil235 is it different with different skin?
|
||||
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)
|
||||
sawn_state = SAWN_OFF
|
||||
magazine.max_ammo = 3
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/proc/unsaw(obj/item/A, mob/user)
|
||||
if(sawn_state == SAWN_INTACT)
|
||||
to_chat(user, "<span class='warning'>[src] has not been shortened!</span>")
|
||||
return
|
||||
if(istype(loc, /obj/item/storage)) //To prevent inventory exploits
|
||||
to_chat(user, "<span class='info'>How do you plan to modify [src] while it's in a bag.</span>")
|
||||
return
|
||||
if(chambered) //if the gun is chambering live ammo, shoot self, if chambering empty ammo, 'click'
|
||||
if(chambered.BB)
|
||||
afterattack(user, user)
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
else
|
||||
afterattack(user, user)
|
||||
user.visible_message("The [src] goes click!", "<span class='notice'>The [src] you are holding goes click.</span>")
|
||||
if(magazine.ammo_count()) //Spill the mag onto the floor
|
||||
user.visible_message("<span class='danger'>[user.name] opens [src] up and the shells go goes flying around!</span>", "<span class='userdanger'>You open [src] up and the shells go goes flying everywhere!!</span>")
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
if(CB)
|
||||
CB.loc = get_turf(loc)
|
||||
CB.update_icon()
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
qdel(A)
|
||||
user.visible_message("<span class='notice'>[user] lengthens [src]!</span>", "<span class='notice'>You lengthen [src].</span>")
|
||||
post_unsaw(user)
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/proc/post_unsaw()
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
w_class = initial(w_class)
|
||||
current_skin = "riotshotgun"
|
||||
item_state = initial(item_state)
|
||||
slot_flags &= ~SLOT_BELT
|
||||
slot_flags |= SLOT_BACK
|
||||
sawn_state = SAWN_INTACT
|
||||
magazine.max_ammo = 6
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/update_icon() //Can't use the old proc as it makes it go to riotshotgun-short_sawn
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/short
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot/short
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/short/New()
|
||||
..()
|
||||
post_sawoff()
|
||||
|
||||
|
||||
|
||||
///////////////////////
|
||||
// BOLT ACTION RIFLE //
|
||||
///////////////////////
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction
|
||||
name = "\improper Mosin Nagant"
|
||||
desc = "This piece of junk looks like something that could have been used 700 years ago."
|
||||
icon_state = "moistnugget"
|
||||
item_state = "moistnugget"
|
||||
slot_flags = 0 //no SLOT_BACK sprite, alas
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
|
||||
var/bolt_open = 0
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 27
|
||||
knife_y_offset = 13
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/pump(mob/M)
|
||||
playsound(M, 'sound/weapons/gun_interactions/rifle_load.ogg', 60, 1)
|
||||
if(bolt_open)
|
||||
pump_reload(M)
|
||||
else
|
||||
pump_unload(M)
|
||||
bolt_open = !bolt_open
|
||||
update_icon() //I.E. fix the desc
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/blow_up(mob/user)
|
||||
. = 0
|
||||
if(chambered && chambered.BB)
|
||||
process_fire(user, user,0)
|
||||
. = 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/attackby(obj/item/A, mob/user, params)
|
||||
if(!bolt_open)
|
||||
to_chat(user, "<span class='notice'>The bolt is closed!</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/examine(mob/user)
|
||||
. = ..()
|
||||
. += "The bolt is [bolt_open ? "open" : "closed"]."
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted
|
||||
name = "enchanted bolt action rifle"
|
||||
desc = "Careful not to lose your head."
|
||||
var/guns_left = 30
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted
|
||||
can_bayonet = FALSE
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted/New()
|
||||
..()
|
||||
bolt_open = 1
|
||||
pump()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted/dropped()
|
||||
..()
|
||||
guns_left = 0
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
|
||||
..()
|
||||
if(guns_left)
|
||||
var/obj/item/gun/projectile/shotgun/boltaction/enchanted/GUN = new
|
||||
GUN.guns_left = guns_left - 1
|
||||
user.drop_item()
|
||||
user.swap_hand()
|
||||
user.put_in_hands(GUN)
|
||||
else
|
||||
user.drop_item()
|
||||
spawn(0)
|
||||
throw_at(pick(oview(7,get_turf(user))),1,1)
|
||||
user.visible_message("<span class='warning'>[user] tosses aside the spent rifle!</span>")
|
||||
|
||||
// Automatic Shotguns//
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj)
|
||||
..()
|
||||
pump(user)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/combat
|
||||
name = "combat shotgun"
|
||||
desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath."
|
||||
icon_state = "cshotgun"
|
||||
origin_tech = "combat=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
|
||||
//Dual Feed Shotgun
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube
|
||||
name = "cycler shotgun"
|
||||
desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types."
|
||||
icon_state = "cycler"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/tube
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/toggled = 0
|
||||
var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/New()
|
||||
..()
|
||||
if(!alternate_magazine)
|
||||
alternate_magazine = new mag_type(src)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/attack_self(mob/living/user)
|
||||
if(!chambered && magazine.contents.len)
|
||||
pump()
|
||||
else
|
||||
toggle_tube(user)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/proc/toggle_tube(mob/living/user)
|
||||
var/current_mag = magazine
|
||||
var/alt_mag = alternate_magazine
|
||||
magazine = alt_mag
|
||||
alternate_magazine = current_mag
|
||||
toggled = !toggled
|
||||
if(toggled)
|
||||
to_chat(user, "You switch to tube B.")
|
||||
else
|
||||
to_chat(user, "You switch to tube A.")
|
||||
playsound(user, 'sound/weapons/gun_interactions/selector.ogg', 100, 1)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/AltClick(mob/living/user)
|
||||
if(user.incapacitated() || !Adjacent(user) || !istype(user))
|
||||
return
|
||||
pump()
|
||||
|
||||
// DOUBLE BARRELED SHOTGUN, IMPROVISED SHOTGUN, and CANE SHOTGUN are in revolver.dm
|
||||
/obj/item/gun/projectile/shotgun
|
||||
name = "shotgun"
|
||||
desc = "A traditional shotgun with wood furniture and a four-shell capacity underneath."
|
||||
icon_state = "shotgun"
|
||||
item_state = "shotgun"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
origin_tech = "combat=4;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_shotgun.ogg'
|
||||
var/recentpump = 0 // to prevent spammage
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
|
||||
/obj/item/gun/projectile/shotgun/attackby(obj/item/A, mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/num_loaded = magazine.attackby(A, user, params, 1)
|
||||
if(num_loaded)
|
||||
to_chat(user, "<span class='notice'>You load [num_loaded] shell\s into \the [src]!</span>")
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/process_chamber()
|
||||
return ..(0, 0)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/chamber_round()
|
||||
return
|
||||
|
||||
/obj/item/gun/projectile/shotgun/can_shoot()
|
||||
if(!chambered)
|
||||
return 0
|
||||
return (chambered.BB ? 1 : 0)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/attack_self(mob/living/user)
|
||||
if(recentpump)
|
||||
return
|
||||
pump(user)
|
||||
recentpump = 1
|
||||
spawn(10)
|
||||
recentpump = 0
|
||||
return
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/proc/pump(mob/M)
|
||||
playsound(M, 'sound/weapons/gun_interactions/shotgunpump.ogg', 60, 1)
|
||||
pump_unload(M)
|
||||
pump_reload(M)
|
||||
update_icon() //I.E. fix the desc
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/proc/pump_unload(mob/M)
|
||||
if(chambered)//We have a shell in the chamber
|
||||
chambered.loc = get_turf(src)//Eject casing
|
||||
chambered.SpinAnimation(5, 1)
|
||||
playsound(src, chambered.drop_sound, 60, 1)
|
||||
chambered = null
|
||||
|
||||
/obj/item/gun/projectile/shotgun/proc/pump_reload(mob/M)
|
||||
if(!magazine.ammo_count())
|
||||
return 0
|
||||
var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing.
|
||||
chambered = AC
|
||||
|
||||
/obj/item/gun/projectile/shotgun/examine(mob/user)
|
||||
. = ..()
|
||||
if(chambered)
|
||||
. += "A [chambered.BB ? "live" : "spent"] one is in the chamber."
|
||||
|
||||
/obj/item/gun/projectile/shotgun/isHandgun() //You cannot, in fact, holster a shotgun.
|
||||
return 0
|
||||
|
||||
/obj/item/gun/projectile/shotgun/lethal
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/lethal
|
||||
|
||||
// RIOT SHOTGUN //
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot //for spawn in the armory
|
||||
name = "riot shotgun"
|
||||
desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control."
|
||||
icon_state = "riotshotgun"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot
|
||||
sawn_desc = "Come with me if you want to live."
|
||||
sawn_state = SAWN_INTACT
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params)
|
||||
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
|
||||
sawoff(user)
|
||||
if(istype(A, /obj/item/melee/energy))
|
||||
var/obj/item/melee/energy/W = A
|
||||
if(W.active)
|
||||
sawoff(user)
|
||||
if(istype(A, /obj/item/pipe))
|
||||
unsaw(A, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/sawoff(mob/user)
|
||||
if(sawn_state == SAWN_OFF)
|
||||
to_chat(user, "<span class='warning'>[src] has already been shortened!</span>")
|
||||
return
|
||||
if(istype(loc, /obj/item/storage)) //To prevent inventory exploits
|
||||
to_chat(user, "<span class='info'>How do you plan to modify [src] while it's in a bag.</span>")
|
||||
return
|
||||
if(chambered) //if the gun is chambering live ammo, shoot self, if chambering empty ammo, 'click'
|
||||
if(chambered.BB)
|
||||
afterattack(user, user)
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
else
|
||||
afterattack(user, user)
|
||||
user.visible_message("The [src] goes click!", "<span class='notice'>The [src] you are holding goes click.</span>")
|
||||
if(magazine.ammo_count()) //Spill the mag onto the floor
|
||||
user.visible_message("<span class='danger'>[user.name] opens [src] up and the shells go goes flying around!</span>", "<span class='userdanger'>You open [src] up and the shells go goes flying everywhere!!</span>")
|
||||
while(get_ammo(0) > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
if(CB)
|
||||
CB.loc = get_turf(loc)
|
||||
CB.update_icon()
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
user.visible_message("[user] shortens \the [src]!", "<span class='notice'>You shorten \the [src].</span>")
|
||||
post_sawoff()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/proc/post_sawoff()
|
||||
name = "assault shotgun"
|
||||
desc = sawn_desc
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
current_skin = "riotshotgun-short"
|
||||
item_state = "gun" //phil235 is it different with different skin?
|
||||
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)
|
||||
sawn_state = SAWN_OFF
|
||||
magazine.max_ammo = 3
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/proc/unsaw(obj/item/A, mob/user)
|
||||
if(sawn_state == SAWN_INTACT)
|
||||
to_chat(user, "<span class='warning'>[src] has not been shortened!</span>")
|
||||
return
|
||||
if(istype(loc, /obj/item/storage)) //To prevent inventory exploits
|
||||
to_chat(user, "<span class='info'>How do you plan to modify [src] while it's in a bag.</span>")
|
||||
return
|
||||
if(chambered) //if the gun is chambering live ammo, shoot self, if chambering empty ammo, 'click'
|
||||
if(chambered.BB)
|
||||
afterattack(user, user)
|
||||
user.visible_message("<span class='danger'>\The [src] goes off!</span>", "<span class='danger'>\The [src] goes off in your face!</span>")
|
||||
return
|
||||
else
|
||||
afterattack(user, user)
|
||||
user.visible_message("The [src] goes click!", "<span class='notice'>The [src] you are holding goes click.</span>")
|
||||
if(magazine.ammo_count()) //Spill the mag onto the floor
|
||||
user.visible_message("<span class='danger'>[user.name] opens [src] up and the shells go goes flying around!</span>", "<span class='userdanger'>You open [src] up and the shells go goes flying everywhere!!</span>")
|
||||
while(get_ammo() > 0)
|
||||
var/obj/item/ammo_casing/CB
|
||||
CB = magazine.get_round(0)
|
||||
if(CB)
|
||||
CB.loc = get_turf(loc)
|
||||
CB.update_icon()
|
||||
|
||||
if(do_after(user, 30, target = src))
|
||||
qdel(A)
|
||||
user.visible_message("<span class='notice'>[user] lengthens [src]!</span>", "<span class='notice'>You lengthen [src].</span>")
|
||||
post_unsaw(user)
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/proc/post_unsaw()
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
w_class = initial(w_class)
|
||||
current_skin = "riotshotgun"
|
||||
item_state = initial(item_state)
|
||||
slot_flags &= ~SLOT_BELT
|
||||
slot_flags |= SLOT_BACK
|
||||
sawn_state = SAWN_INTACT
|
||||
magazine.max_ammo = 6
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/update_icon() //Can't use the old proc as it makes it go to riotshotgun-short_sawn
|
||||
..()
|
||||
if(current_skin)
|
||||
icon_state = "[current_skin]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/short
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot/short
|
||||
|
||||
/obj/item/gun/projectile/shotgun/riot/short/New()
|
||||
..()
|
||||
post_sawoff()
|
||||
|
||||
|
||||
|
||||
///////////////////////
|
||||
// BOLT ACTION RIFLE //
|
||||
///////////////////////
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction
|
||||
name = "\improper Mosin Nagant"
|
||||
desc = "This piece of junk looks like something that could have been used 700 years ago."
|
||||
icon_state = "moistnugget"
|
||||
item_state = "moistnugget"
|
||||
slot_flags = 0 //no SLOT_BACK sprite, alas
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
|
||||
var/bolt_open = 0
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 27
|
||||
knife_y_offset = 13
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/pump(mob/M)
|
||||
playsound(M, 'sound/weapons/gun_interactions/rifle_load.ogg', 60, 1)
|
||||
if(bolt_open)
|
||||
pump_reload(M)
|
||||
else
|
||||
pump_unload(M)
|
||||
bolt_open = !bolt_open
|
||||
update_icon() //I.E. fix the desc
|
||||
return 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/blow_up(mob/user)
|
||||
. = 0
|
||||
if(chambered && chambered.BB)
|
||||
process_fire(user, user,0)
|
||||
. = 1
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/attackby(obj/item/A, mob/user, params)
|
||||
if(!bolt_open)
|
||||
to_chat(user, "<span class='notice'>The bolt is closed!</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/examine(mob/user)
|
||||
. = ..()
|
||||
. += "The bolt is [bolt_open ? "open" : "closed"]."
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted
|
||||
name = "enchanted bolt action rifle"
|
||||
desc = "Careful not to lose your head."
|
||||
var/guns_left = 30
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted
|
||||
can_bayonet = FALSE
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted/New()
|
||||
..()
|
||||
bolt_open = 1
|
||||
pump()
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted/dropped()
|
||||
..()
|
||||
guns_left = 0
|
||||
|
||||
/obj/item/gun/projectile/shotgun/boltaction/enchanted/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
|
||||
..()
|
||||
if(guns_left)
|
||||
var/obj/item/gun/projectile/shotgun/boltaction/enchanted/GUN = new
|
||||
GUN.guns_left = guns_left - 1
|
||||
user.drop_item()
|
||||
user.swap_hand()
|
||||
user.put_in_hands(GUN)
|
||||
else
|
||||
user.drop_item()
|
||||
spawn(0)
|
||||
throw_at(pick(oview(7,get_turf(user))),1,1)
|
||||
user.visible_message("<span class='warning'>[user] tosses aside the spent rifle!</span>")
|
||||
|
||||
// Automatic Shotguns//
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj)
|
||||
..()
|
||||
pump(user)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/combat
|
||||
name = "combat shotgun"
|
||||
desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath."
|
||||
icon_state = "cshotgun"
|
||||
origin_tech = "combat=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
|
||||
//Dual Feed Shotgun
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube
|
||||
name = "cycler shotgun"
|
||||
desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types."
|
||||
icon_state = "cycler"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/tube
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/toggled = 0
|
||||
var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/New()
|
||||
..()
|
||||
if(!alternate_magazine)
|
||||
alternate_magazine = new mag_type(src)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/attack_self(mob/living/user)
|
||||
if(!chambered && magazine.contents.len)
|
||||
pump()
|
||||
else
|
||||
toggle_tube(user)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/proc/toggle_tube(mob/living/user)
|
||||
var/current_mag = magazine
|
||||
var/alt_mag = alternate_magazine
|
||||
magazine = alt_mag
|
||||
alternate_magazine = current_mag
|
||||
toggled = !toggled
|
||||
if(toggled)
|
||||
to_chat(user, "You switch to tube B.")
|
||||
else
|
||||
to_chat(user, "You switch to tube A.")
|
||||
playsound(user, 'sound/weapons/gun_interactions/selector.ogg', 100, 1)
|
||||
|
||||
/obj/item/gun/projectile/shotgun/automatic/dual_tube/AltClick(mob/living/user)
|
||||
if(user.incapacitated() || !Adjacent(user) || !istype(user))
|
||||
return
|
||||
pump()
|
||||
|
||||
// DOUBLE BARRELED SHOTGUN, IMPROVISED SHOTGUN, and CANE SHOTGUN are in revolver.dm
|
||||
|
||||
@@ -208,4 +208,4 @@
|
||||
else if(ammo)
|
||||
overlays += image('icons/obj/ammo.dmi', icon_state = ".50mag-f")
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
@@ -133,4 +133,4 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/toy/sniper_rounds
|
||||
|
||||
/obj/item/gun/projectile/automatic/sniper_rifle/toy/process_chamber(eject_casing = 0, empty_chamber = 1)
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -1,355 +1,355 @@
|
||||
/obj/item/projectile
|
||||
name = "projectile"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "bullet"
|
||||
density = 0
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
anchored = 1 //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots.
|
||||
flags = ABSTRACT
|
||||
pass_flags = PASSTABLE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
hitsound = 'sound/weapons/pierce.ogg'
|
||||
var/hitsound_wall = ""
|
||||
var/def_zone = "" //Aiming at
|
||||
var/mob/firer = null//Who shot it
|
||||
var/obj/item/ammo_casing/ammo_casing = null
|
||||
var/suppressed = 0 //Attack message
|
||||
var/yo = null
|
||||
var/xo = null
|
||||
var/current = null
|
||||
var/atom/original = null // the original target clicked
|
||||
var/turf/starting = null // the projectile's starting turf
|
||||
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
|
||||
var/paused = FALSE //for suspending the projectile midair
|
||||
var/p_x = 16
|
||||
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
|
||||
var/speed = 1 //Amount of deciseconds it takes for projectile to travel
|
||||
var/Angle = null
|
||||
var/spread = 0 //amount (in degrees) of projectile spread
|
||||
var/legacy = FALSE //legacy projectile system
|
||||
animate_movement = 0
|
||||
|
||||
var/ignore_source_check = FALSE
|
||||
|
||||
var/damage = 10
|
||||
var/tile_dropoff = 0 //how much damage should be decremented as the bullet moves
|
||||
var/tile_dropoff_s = 0 //same as above but for stamina
|
||||
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
|
||||
var/nodamage = FALSE //Determines if the projectile will skip any damage inflictions
|
||||
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid
|
||||
var/projectile_type = "/obj/item/projectile"
|
||||
var/range = 50 //This will de-increment every step. When 0, it will delete the projectile.
|
||||
var/is_reflectable = FALSE // Can it be reflected or not?
|
||||
var/alwayslog = FALSE // ALWAYS log this projectile on hit even if it doesn't hit a living target. Useful for AOE explosion / EMP.
|
||||
//Effects
|
||||
var/stun = 0
|
||||
var/weaken = 0
|
||||
var/paralyze = 0
|
||||
var/irradiate = 0
|
||||
var/stutter = 0
|
||||
var/slur = 0
|
||||
var/eyeblur = 0
|
||||
var/drowsy = 0
|
||||
var/stamina = 0
|
||||
var/jitter = 0
|
||||
var/forcedodge = 0 //to pass through everything
|
||||
var/dismemberment = 0 //The higher the number, the greater the bonus to dismembering. 0 will not dismember at all.
|
||||
var/impact_effect_type //what type of impact effect to show when hitting something
|
||||
var/ricochets = 0
|
||||
var/ricochets_max = 2
|
||||
var/ricochet_chance = 30
|
||||
|
||||
var/log_override = FALSE //whether print to admin attack logs or just keep it in the diary
|
||||
|
||||
/obj/item/projectile/New()
|
||||
permutated = list()
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/proc/Range()
|
||||
range--
|
||||
if(damage && tile_dropoff)
|
||||
damage = max(0, damage - tile_dropoff) // decrement projectile damage based on dropoff value for each tile it moves
|
||||
if(stamina && tile_dropoff_s)
|
||||
stamina = max(0, stamina - tile_dropoff_s) // as above, but with stamina
|
||||
if(range <= 0 && loc)
|
||||
on_range()
|
||||
if(!damage && !stamina && (tile_dropoff || tile_dropoff_s))
|
||||
on_range()
|
||||
|
||||
/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/proc/prehit(atom/target)
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/proc/on_hit(atom/target, blocked = 0, hit_zone)
|
||||
var/turf/target_loca = get_turf(target)
|
||||
var/hitx
|
||||
var/hity
|
||||
if(target == original)
|
||||
hitx = target.pixel_x + p_x - 16
|
||||
hity = target.pixel_y + p_y - 16
|
||||
else
|
||||
hitx = target.pixel_x + rand(-8, 8)
|
||||
hity = target.pixel_y + rand(-8, 8)
|
||||
if(!nodamage && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_loca) && prob(75))
|
||||
var/turf/simulated/wall/W = target_loca
|
||||
if(impact_effect_type)
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
|
||||
W.add_dent(WALL_DENT_SHOT, hitx, hity)
|
||||
return 0
|
||||
if(alwayslog)
|
||||
add_attack_logs(firer, target, "Shot with a [type]")
|
||||
if(!isliving(target))
|
||||
if(impact_effect_type)
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
return 0
|
||||
var/mob/living/L = target
|
||||
var/mob/living/carbon/human/H
|
||||
if(blocked < 100) // not completely blocked
|
||||
if(damage && L.blood_volume && damage_type == BRUTE)
|
||||
var/splatter_dir = dir
|
||||
if(starting)
|
||||
splatter_dir = get_dir(starting, target_loca)
|
||||
if(isalien(L))
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
|
||||
else
|
||||
var/blood_color = "#C80000"
|
||||
if(ishuman(target))
|
||||
H = target
|
||||
blood_color = H.dna.species.blood_color
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color)
|
||||
if(prob(33))
|
||||
var/list/shift = list("x" = 0, "y" = 0)
|
||||
var/turf/step_over = get_step(target_loca, splatter_dir)
|
||||
|
||||
if(get_splatter_blockage(step_over, target, splatter_dir, target_loca)) //If you can't cross the tile or any of its relevant obstacles...
|
||||
shift = pixel_shift_dir(splatter_dir) //Pixel shift the blood there instead (so you can't see wallsplatter through walls).
|
||||
else
|
||||
target_loca = step_over
|
||||
L.add_splatter_floor(target_loca, shift_x = shift["x"], shift_y = shift["y"])
|
||||
if(istype(H))
|
||||
for(var/mob/living/carbon/human/M in step_over) //Bloody the mobs who're infront of the spray.
|
||||
M.bloody_hands(H)
|
||||
/* Uncomment when bloody_body stops randomly not transferring blood colour.
|
||||
M.bloody_body(H) */
|
||||
else if(impact_effect_type)
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
var/organ_hit_text = ""
|
||||
if(L.has_limbs)
|
||||
organ_hit_text = " in \the [parse_zone(def_zone)]"
|
||||
if(suppressed)
|
||||
playsound(loc, hitsound, 5, 1, -1)
|
||||
to_chat(L, "<span class='userdanger'>You're shot by \a [src][organ_hit_text]!</span>")
|
||||
else
|
||||
if(hitsound)
|
||||
var/volume = vol_by_damage()
|
||||
playsound(loc, hitsound, volume, 1, -1)
|
||||
L.visible_message("<span class='danger'>[L] is hit by \a [src][organ_hit_text]!</span>", \
|
||||
"<span class='userdanger'>[L] is hit by \a [src][organ_hit_text]!</span>") //X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
|
||||
var/reagent_note
|
||||
var/has_reagents = FALSE
|
||||
if(reagents && reagents.reagent_list)
|
||||
reagent_note = " REAGENTS:"
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
reagent_note += R.id + " ("
|
||||
reagent_note += num2text(R.volume) + ") "
|
||||
has_reagents = TRUE
|
||||
if(!log_override && firer && !alwayslog)
|
||||
if(has_reagents)
|
||||
add_attack_logs(firer, L, "Shot with a [type] (containing [reagent_note])")
|
||||
else
|
||||
add_attack_logs(firer, L, "Shot with a [type]")
|
||||
return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
|
||||
|
||||
/obj/item/projectile/proc/get_splatter_blockage(var/turf/step_over, var/atom/target, var/splatter_dir, var/target_loca) //Check whether the place we want to splatter blood is blocked (i.e. by windows).
|
||||
var/turf/step_cardinal = !(splatter_dir in list(NORTH, SOUTH, EAST, WEST)) ? get_step(target_loca, get_cardinal_dir(target_loca, step_over)) : null
|
||||
|
||||
if(step_over.density && !step_over.CanPass(target, step_over, 1)) //Preliminary simple check.
|
||||
return TRUE
|
||||
for(var/atom/movable/border_obstacle in step_over) //Check to see if we're blocked by a (non-full) window or some such. Do deeper investigation if we're splattering blood diagonally.
|
||||
if(border_obstacle.flags&ON_BORDER && get_dir(step_cardinal ? step_cardinal : target_loca, step_over) == turn(border_obstacle.dir, 180))
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/proc/vol_by_damage()
|
||||
if(damage)
|
||||
return Clamp((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
|
||||
else
|
||||
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
|
||||
|
||||
/obj/item/projectile/Bump(atom/A, yes)
|
||||
if(!yes) //prevents double bumps.
|
||||
return
|
||||
|
||||
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
|
||||
ricochets++
|
||||
if(A.handle_ricochet(src))
|
||||
on_ricochet(A)
|
||||
ignore_source_check = TRUE
|
||||
range = initial(range)
|
||||
return TRUE
|
||||
if(firer && !ignore_source_check)
|
||||
if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
|
||||
loc = A.loc
|
||||
return 0
|
||||
|
||||
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
|
||||
def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
|
||||
|
||||
if(isturf(A) && hitsound_wall)
|
||||
var/volume = Clamp(vol_by_damage() + 20, 0, 100)
|
||||
if(suppressed)
|
||||
volume = 5
|
||||
playsound(loc, hitsound_wall, volume, 1, -1)
|
||||
else if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
var/obj/item/organ/external/organ = H.get_organ(check_zone(def_zone))
|
||||
if(isnull(organ))
|
||||
return
|
||||
|
||||
var/turf/target_turf = get_turf(A)
|
||||
prehit(A)
|
||||
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
|
||||
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
|
||||
loc = target_turf
|
||||
if(A)
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
else
|
||||
if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
|
||||
var/list/mobs_list = list()
|
||||
for(var/mob/living/L in target_turf)
|
||||
mobs_list += L
|
||||
if(mobs_list.len)
|
||||
var/mob/living/picked_mob = pick(mobs_list)
|
||||
prehit(picked_mob)
|
||||
picked_mob.bullet_act(src, def_zone)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
|
||||
return 1 //Bullets don't drift in space
|
||||
|
||||
/obj/item/projectile/proc/fire(var/setAngle)
|
||||
if(setAngle)
|
||||
Angle = setAngle
|
||||
if(!legacy) //new projectiles
|
||||
set waitfor = 0
|
||||
while(loc)
|
||||
if(!paused)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
if(isnull(Angle))
|
||||
Angle=round(Get_Angle(src,current))
|
||||
if(spread)
|
||||
Angle += (rand() - 0.5) * spread
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
transform = M
|
||||
|
||||
var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2)
|
||||
var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2)
|
||||
var/pixel_x_offset = pixel_x + Pixel_x
|
||||
var/pixel_y_offset = pixel_y + Pixel_y
|
||||
var/new_x = x
|
||||
var/new_y = y
|
||||
|
||||
while(pixel_x_offset > 16)
|
||||
pixel_x_offset -= 32
|
||||
pixel_x -= 32
|
||||
new_x++// x++
|
||||
while(pixel_x_offset < -16)
|
||||
pixel_x_offset += 32
|
||||
pixel_x += 32
|
||||
new_x--
|
||||
|
||||
while(pixel_y_offset > 16)
|
||||
pixel_y_offset -= 32
|
||||
pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y_offset < -16)
|
||||
pixel_y_offset += 32
|
||||
pixel_y += 32
|
||||
new_y--
|
||||
|
||||
speed = round(speed)
|
||||
step_towards(src, locate(new_x, new_y, z))
|
||||
if(speed <= 1)
|
||||
pixel_x = pixel_x_offset
|
||||
pixel_y = pixel_y_offset
|
||||
else
|
||||
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed)))
|
||||
|
||||
if(original && (original.layer>=2.75) || ismob(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original, 1)
|
||||
Range()
|
||||
sleep(max(1, speed))
|
||||
else //old projectile system
|
||||
set waitfor = 0
|
||||
while(loc)
|
||||
if(!paused)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
step_towards(src, current)
|
||||
if(original && (original.layer>=2.75) || ismob(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original, 1)
|
||||
Range()
|
||||
sleep(1)
|
||||
|
||||
obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = list(0, 0, 0, 0, 0, -1, 1, -2, 2))
|
||||
if(starting)
|
||||
var/new_x = starting.x + pick(position_modifiers)
|
||||
var/new_y = starting.y + pick(position_modifiers)
|
||||
var/turf/curloc = get_turf(source)
|
||||
|
||||
if(ismob(source))
|
||||
firer = source // The reflecting mob will be the new firer
|
||||
else
|
||||
firer = null // Reflected by something other than a mob so firer will be null
|
||||
|
||||
// redirect the projectile
|
||||
original = locate(new_x, new_y, z)
|
||||
starting = curloc
|
||||
current = curloc
|
||||
yo = new_y - curloc.y
|
||||
xo = new_x - curloc.x
|
||||
Angle = null // Will be calculated in fire()
|
||||
|
||||
obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile with a projectile is hit by it.
|
||||
..()
|
||||
if(isliving(AM) && AM.density && !checkpass(PASSMOB))
|
||||
Bump(AM, 1)
|
||||
|
||||
/obj/item/projectile/Destroy()
|
||||
ammo_casing = null
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/proc/dumbfire(var/dir)
|
||||
current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better.
|
||||
fire()
|
||||
|
||||
|
||||
/obj/item/projectile/proc/on_ricochet(atom/A)
|
||||
return
|
||||
|
||||
/obj/item/projectile/proc/check_ricochet()
|
||||
if(prob(ricochet_chance))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/proc/check_ricochet_flag(atom/A)
|
||||
if(A.flags_2 & CHECK_RICOCHET_2)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides.
|
||||
Angle = new_angle
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/experience_pressure_difference()
|
||||
return
|
||||
/obj/item/projectile
|
||||
name = "projectile"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "bullet"
|
||||
density = 0
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
anchored = 1 //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots.
|
||||
flags = ABSTRACT
|
||||
pass_flags = PASSTABLE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
hitsound = 'sound/weapons/pierce.ogg'
|
||||
var/hitsound_wall = ""
|
||||
var/def_zone = "" //Aiming at
|
||||
var/mob/firer = null//Who shot it
|
||||
var/obj/item/ammo_casing/ammo_casing = null
|
||||
var/suppressed = 0 //Attack message
|
||||
var/yo = null
|
||||
var/xo = null
|
||||
var/current = null
|
||||
var/atom/original = null // the original target clicked
|
||||
var/turf/starting = null // the projectile's starting turf
|
||||
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
|
||||
var/paused = FALSE //for suspending the projectile midair
|
||||
var/p_x = 16
|
||||
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
|
||||
var/speed = 1 //Amount of deciseconds it takes for projectile to travel
|
||||
var/Angle = null
|
||||
var/spread = 0 //amount (in degrees) of projectile spread
|
||||
var/legacy = FALSE //legacy projectile system
|
||||
animate_movement = 0
|
||||
|
||||
var/ignore_source_check = FALSE
|
||||
|
||||
var/damage = 10
|
||||
var/tile_dropoff = 0 //how much damage should be decremented as the bullet moves
|
||||
var/tile_dropoff_s = 0 //same as above but for stamina
|
||||
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
|
||||
var/nodamage = FALSE //Determines if the projectile will skip any damage inflictions
|
||||
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid
|
||||
var/projectile_type = "/obj/item/projectile"
|
||||
var/range = 50 //This will de-increment every step. When 0, it will delete the projectile.
|
||||
var/is_reflectable = FALSE // Can it be reflected or not?
|
||||
var/alwayslog = FALSE // ALWAYS log this projectile on hit even if it doesn't hit a living target. Useful for AOE explosion / EMP.
|
||||
//Effects
|
||||
var/stun = 0
|
||||
var/weaken = 0
|
||||
var/paralyze = 0
|
||||
var/irradiate = 0
|
||||
var/stutter = 0
|
||||
var/slur = 0
|
||||
var/eyeblur = 0
|
||||
var/drowsy = 0
|
||||
var/stamina = 0
|
||||
var/jitter = 0
|
||||
var/forcedodge = 0 //to pass through everything
|
||||
var/dismemberment = 0 //The higher the number, the greater the bonus to dismembering. 0 will not dismember at all.
|
||||
var/impact_effect_type //what type of impact effect to show when hitting something
|
||||
var/ricochets = 0
|
||||
var/ricochets_max = 2
|
||||
var/ricochet_chance = 30
|
||||
|
||||
var/log_override = FALSE //whether print to admin attack logs or just keep it in the diary
|
||||
|
||||
/obj/item/projectile/New()
|
||||
permutated = list()
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/proc/Range()
|
||||
range--
|
||||
if(damage && tile_dropoff)
|
||||
damage = max(0, damage - tile_dropoff) // decrement projectile damage based on dropoff value for each tile it moves
|
||||
if(stamina && tile_dropoff_s)
|
||||
stamina = max(0, stamina - tile_dropoff_s) // as above, but with stamina
|
||||
if(range <= 0 && loc)
|
||||
on_range()
|
||||
if(!damage && !stamina && (tile_dropoff || tile_dropoff_s))
|
||||
on_range()
|
||||
|
||||
/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/proc/prehit(atom/target)
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/proc/on_hit(atom/target, blocked = 0, hit_zone)
|
||||
var/turf/target_loca = get_turf(target)
|
||||
var/hitx
|
||||
var/hity
|
||||
if(target == original)
|
||||
hitx = target.pixel_x + p_x - 16
|
||||
hity = target.pixel_y + p_y - 16
|
||||
else
|
||||
hitx = target.pixel_x + rand(-8, 8)
|
||||
hity = target.pixel_y + rand(-8, 8)
|
||||
if(!nodamage && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_loca) && prob(75))
|
||||
var/turf/simulated/wall/W = target_loca
|
||||
if(impact_effect_type)
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
|
||||
W.add_dent(WALL_DENT_SHOT, hitx, hity)
|
||||
return 0
|
||||
if(alwayslog)
|
||||
add_attack_logs(firer, target, "Shot with a [type]")
|
||||
if(!isliving(target))
|
||||
if(impact_effect_type)
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
return 0
|
||||
var/mob/living/L = target
|
||||
var/mob/living/carbon/human/H
|
||||
if(blocked < 100) // not completely blocked
|
||||
if(damage && L.blood_volume && damage_type == BRUTE)
|
||||
var/splatter_dir = dir
|
||||
if(starting)
|
||||
splatter_dir = get_dir(starting, target_loca)
|
||||
if(isalien(L))
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
|
||||
else
|
||||
var/blood_color = "#C80000"
|
||||
if(ishuman(target))
|
||||
H = target
|
||||
blood_color = H.dna.species.blood_color
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color)
|
||||
if(prob(33))
|
||||
var/list/shift = list("x" = 0, "y" = 0)
|
||||
var/turf/step_over = get_step(target_loca, splatter_dir)
|
||||
|
||||
if(get_splatter_blockage(step_over, target, splatter_dir, target_loca)) //If you can't cross the tile or any of its relevant obstacles...
|
||||
shift = pixel_shift_dir(splatter_dir) //Pixel shift the blood there instead (so you can't see wallsplatter through walls).
|
||||
else
|
||||
target_loca = step_over
|
||||
L.add_splatter_floor(target_loca, shift_x = shift["x"], shift_y = shift["y"])
|
||||
if(istype(H))
|
||||
for(var/mob/living/carbon/human/M in step_over) //Bloody the mobs who're infront of the spray.
|
||||
M.bloody_hands(H)
|
||||
/* Uncomment when bloody_body stops randomly not transferring blood colour.
|
||||
M.bloody_body(H) */
|
||||
else if(impact_effect_type)
|
||||
new impact_effect_type(target_loca, hitx, hity)
|
||||
var/organ_hit_text = ""
|
||||
if(L.has_limbs)
|
||||
organ_hit_text = " in \the [parse_zone(def_zone)]"
|
||||
if(suppressed)
|
||||
playsound(loc, hitsound, 5, 1, -1)
|
||||
to_chat(L, "<span class='userdanger'>You're shot by \a [src][organ_hit_text]!</span>")
|
||||
else
|
||||
if(hitsound)
|
||||
var/volume = vol_by_damage()
|
||||
playsound(loc, hitsound, volume, 1, -1)
|
||||
L.visible_message("<span class='danger'>[L] is hit by \a [src][organ_hit_text]!</span>", \
|
||||
"<span class='userdanger'>[L] is hit by \a [src][organ_hit_text]!</span>") //X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
|
||||
|
||||
var/reagent_note
|
||||
var/has_reagents = FALSE
|
||||
if(reagents && reagents.reagent_list)
|
||||
reagent_note = " REAGENTS:"
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
reagent_note += R.id + " ("
|
||||
reagent_note += num2text(R.volume) + ") "
|
||||
has_reagents = TRUE
|
||||
if(!log_override && firer && !alwayslog)
|
||||
if(has_reagents)
|
||||
add_attack_logs(firer, L, "Shot with a [type] (containing [reagent_note])")
|
||||
else
|
||||
add_attack_logs(firer, L, "Shot with a [type]")
|
||||
return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
|
||||
|
||||
/obj/item/projectile/proc/get_splatter_blockage(var/turf/step_over, var/atom/target, var/splatter_dir, var/target_loca) //Check whether the place we want to splatter blood is blocked (i.e. by windows).
|
||||
var/turf/step_cardinal = !(splatter_dir in list(NORTH, SOUTH, EAST, WEST)) ? get_step(target_loca, get_cardinal_dir(target_loca, step_over)) : null
|
||||
|
||||
if(step_over.density && !step_over.CanPass(target, step_over, 1)) //Preliminary simple check.
|
||||
return TRUE
|
||||
for(var/atom/movable/border_obstacle in step_over) //Check to see if we're blocked by a (non-full) window or some such. Do deeper investigation if we're splattering blood diagonally.
|
||||
if(border_obstacle.flags&ON_BORDER && get_dir(step_cardinal ? step_cardinal : target_loca, step_over) == turn(border_obstacle.dir, 180))
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/proc/vol_by_damage()
|
||||
if(damage)
|
||||
return Clamp((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
|
||||
else
|
||||
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
|
||||
|
||||
/obj/item/projectile/Bump(atom/A, yes)
|
||||
if(!yes) //prevents double bumps.
|
||||
return
|
||||
|
||||
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
|
||||
ricochets++
|
||||
if(A.handle_ricochet(src))
|
||||
on_ricochet(A)
|
||||
ignore_source_check = TRUE
|
||||
range = initial(range)
|
||||
return TRUE
|
||||
if(firer && !ignore_source_check)
|
||||
if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
|
||||
loc = A.loc
|
||||
return 0
|
||||
|
||||
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
|
||||
def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
|
||||
|
||||
if(isturf(A) && hitsound_wall)
|
||||
var/volume = Clamp(vol_by_damage() + 20, 0, 100)
|
||||
if(suppressed)
|
||||
volume = 5
|
||||
playsound(loc, hitsound_wall, volume, 1, -1)
|
||||
else if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
var/obj/item/organ/external/organ = H.get_organ(check_zone(def_zone))
|
||||
if(isnull(organ))
|
||||
return
|
||||
|
||||
var/turf/target_turf = get_turf(A)
|
||||
prehit(A)
|
||||
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
|
||||
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
|
||||
loc = target_turf
|
||||
if(A)
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
else
|
||||
if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
|
||||
var/list/mobs_list = list()
|
||||
for(var/mob/living/L in target_turf)
|
||||
mobs_list += L
|
||||
if(mobs_list.len)
|
||||
var/mob/living/picked_mob = pick(mobs_list)
|
||||
prehit(picked_mob)
|
||||
picked_mob.bullet_act(src, def_zone)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
|
||||
return 1 //Bullets don't drift in space
|
||||
|
||||
/obj/item/projectile/proc/fire(var/setAngle)
|
||||
if(setAngle)
|
||||
Angle = setAngle
|
||||
if(!legacy) //new projectiles
|
||||
set waitfor = 0
|
||||
while(loc)
|
||||
if(!paused)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
if(isnull(Angle))
|
||||
Angle=round(Get_Angle(src,current))
|
||||
if(spread)
|
||||
Angle += (rand() - 0.5) * spread
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
transform = M
|
||||
|
||||
var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2)
|
||||
var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2)
|
||||
var/pixel_x_offset = pixel_x + Pixel_x
|
||||
var/pixel_y_offset = pixel_y + Pixel_y
|
||||
var/new_x = x
|
||||
var/new_y = y
|
||||
|
||||
while(pixel_x_offset > 16)
|
||||
pixel_x_offset -= 32
|
||||
pixel_x -= 32
|
||||
new_x++// x++
|
||||
while(pixel_x_offset < -16)
|
||||
pixel_x_offset += 32
|
||||
pixel_x += 32
|
||||
new_x--
|
||||
|
||||
while(pixel_y_offset > 16)
|
||||
pixel_y_offset -= 32
|
||||
pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y_offset < -16)
|
||||
pixel_y_offset += 32
|
||||
pixel_y += 32
|
||||
new_y--
|
||||
|
||||
speed = round(speed)
|
||||
step_towards(src, locate(new_x, new_y, z))
|
||||
if(speed <= 1)
|
||||
pixel_x = pixel_x_offset
|
||||
pixel_y = pixel_y_offset
|
||||
else
|
||||
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed)))
|
||||
|
||||
if(original && (original.layer>=2.75) || ismob(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original, 1)
|
||||
Range()
|
||||
sleep(max(1, speed))
|
||||
else //old projectile system
|
||||
set waitfor = 0
|
||||
while(loc)
|
||||
if(!paused)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
step_towards(src, current)
|
||||
if(original && (original.layer>=2.75) || ismob(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
Bump(original, 1)
|
||||
Range()
|
||||
sleep(1)
|
||||
|
||||
obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = list(0, 0, 0, 0, 0, -1, 1, -2, 2))
|
||||
if(starting)
|
||||
var/new_x = starting.x + pick(position_modifiers)
|
||||
var/new_y = starting.y + pick(position_modifiers)
|
||||
var/turf/curloc = get_turf(source)
|
||||
|
||||
if(ismob(source))
|
||||
firer = source // The reflecting mob will be the new firer
|
||||
else
|
||||
firer = null // Reflected by something other than a mob so firer will be null
|
||||
|
||||
// redirect the projectile
|
||||
original = locate(new_x, new_y, z)
|
||||
starting = curloc
|
||||
current = curloc
|
||||
yo = new_y - curloc.y
|
||||
xo = new_x - curloc.x
|
||||
Angle = null // Will be calculated in fire()
|
||||
|
||||
obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile with a projectile is hit by it.
|
||||
..()
|
||||
if(isliving(AM) && AM.density && !checkpass(PASSMOB))
|
||||
Bump(AM, 1)
|
||||
|
||||
/obj/item/projectile/Destroy()
|
||||
ammo_casing = null
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/proc/dumbfire(var/dir)
|
||||
current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better.
|
||||
fire()
|
||||
|
||||
|
||||
/obj/item/projectile/proc/on_ricochet(atom/A)
|
||||
return
|
||||
|
||||
/obj/item/projectile/proc/check_ricochet()
|
||||
if(prob(ricochet_chance))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/proc/check_ricochet_flag(atom/A)
|
||||
if(A.flags_2 & CHECK_RICOCHET_2)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides.
|
||||
Angle = new_angle
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/experience_pressure_difference()
|
||||
return
|
||||
|
||||
@@ -1,171 +1,171 @@
|
||||
/obj/item/projectile/beam
|
||||
name = "laser"
|
||||
icon_state = "laser"
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
damage = 20
|
||||
damage_type = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
flag = "laser"
|
||||
eyeblur = 2
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
|
||||
is_reflectable = TRUE
|
||||
light_range = 2
|
||||
light_color = LIGHT_COLOR_RED
|
||||
ricochets_max = 50 //Honk!
|
||||
ricochet_chance = 80
|
||||
|
||||
/obj/item/projectile/beam/laser
|
||||
|
||||
/obj/item/projectile/beam/laser/heavylaser
|
||||
name = "heavy laser"
|
||||
icon_state = "heavylaser"
|
||||
damage = 40
|
||||
|
||||
/obj/item/projectile/beam/practice
|
||||
name = "practice laser"
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
log_override = TRUE
|
||||
|
||||
/obj/item/projectile/beam/scatter
|
||||
name = "laser pellet"
|
||||
icon_state = "scatterlaser"
|
||||
damage = 5
|
||||
|
||||
/obj/item/projectile/beam/xray
|
||||
name = "xray beam"
|
||||
icon_state = "xray"
|
||||
damage = 15
|
||||
tile_dropoff = 0.75
|
||||
irradiate = 30
|
||||
forcedodge = 1
|
||||
range = 15
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/item/projectile/beam/disabler
|
||||
name = "disabler beam"
|
||||
icon_state = "omnilaser"
|
||||
damage = 30
|
||||
damage_type = STAMINA
|
||||
flag = "energy"
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
eyeblur = 0
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
|
||||
/obj/item/projectile/beam/pulse
|
||||
name = "pulse"
|
||||
icon_state = "u_laser"
|
||||
damage = 50
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_DARKBLUE
|
||||
|
||||
/obj/item/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target,/turf/)||istype(target,/obj/structure/))
|
||||
target.ex_act(2)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/pulse/shot
|
||||
damage = 40
|
||||
|
||||
/obj/item/projectile/beam/emitter
|
||||
name = "emitter beam"
|
||||
icon_state = "emitter"
|
||||
damage = 30
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/item/projectile/beam/emitter/singularity_pull()
|
||||
return //don't want the emitters to miss
|
||||
|
||||
/obj/item/projectile/beam/lasertag
|
||||
name = "laser tag beam"
|
||||
icon_state = "omnilaser"
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
nodamage = 1
|
||||
damage_type = STAMINA
|
||||
flag = "laser"
|
||||
var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag)
|
||||
log_override = TRUE
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_DARKBLUE
|
||||
|
||||
/obj/item/projectile/beam/lasertag/on_hit(atom/target, blocked = 0)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(istype(M.wear_suit))
|
||||
if(M.wear_suit.type in suit_types)
|
||||
M.adjustStaminaLoss(34)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/beam/lasertag/omni
|
||||
name = "laser tag beam"
|
||||
icon_state = "omnilaser"
|
||||
|
||||
/obj/item/projectile/beam/lasertag/redtag
|
||||
icon_state = "laser"
|
||||
suit_types = list(/obj/item/clothing/suit/bluetag)
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/beam/lasertag/bluetag
|
||||
icon_state = "bluelaser"
|
||||
suit_types = list(/obj/item/clothing/suit/redtag)
|
||||
|
||||
/obj/item/projectile/beam/sniper
|
||||
name = "sniper beam"
|
||||
icon_state = "sniperlaser"
|
||||
damage = 60
|
||||
stun = 5
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
light_color = LIGHT_COLOR_PINK
|
||||
|
||||
/obj/item/projectile/beam/immolator
|
||||
name = "immolation beam"
|
||||
|
||||
/obj/item/projectile/beam/immolator/strong
|
||||
name = "heavy immolation beam"
|
||||
damage = 45
|
||||
icon_state = "heavylaser"
|
||||
|
||||
/obj/item/projectile/beam/immolator/weak
|
||||
name = "light immolation beam"
|
||||
damage = 8
|
||||
icon_state = "scatterlaser"
|
||||
|
||||
/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(istype(target, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.IgniteMob()
|
||||
|
||||
/obj/item/projectile/beam/instakill
|
||||
name = "instagib laser"
|
||||
icon_state = "purple_laser"
|
||||
damage = 200
|
||||
damage_type = BURN
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
light_color = LIGHT_COLOR_PURPLE
|
||||
|
||||
/obj/item/projectile/beam/instakill/blue
|
||||
icon_state = "blue_laser"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_DARKBLUE
|
||||
|
||||
/obj/item/projectile/beam/instakill/red
|
||||
icon_state = "red_laser"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/beam/instakill/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.visible_message("<span class='danger'>[L] explodes!</span>")
|
||||
L.gib()
|
||||
/obj/item/projectile/beam
|
||||
name = "laser"
|
||||
icon_state = "laser"
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
damage = 20
|
||||
damage_type = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
flag = "laser"
|
||||
eyeblur = 2
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
|
||||
is_reflectable = TRUE
|
||||
light_range = 2
|
||||
light_color = LIGHT_COLOR_RED
|
||||
ricochets_max = 50 //Honk!
|
||||
ricochet_chance = 80
|
||||
|
||||
/obj/item/projectile/beam/laser
|
||||
|
||||
/obj/item/projectile/beam/laser/heavylaser
|
||||
name = "heavy laser"
|
||||
icon_state = "heavylaser"
|
||||
damage = 40
|
||||
|
||||
/obj/item/projectile/beam/practice
|
||||
name = "practice laser"
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
log_override = TRUE
|
||||
|
||||
/obj/item/projectile/beam/scatter
|
||||
name = "laser pellet"
|
||||
icon_state = "scatterlaser"
|
||||
damage = 5
|
||||
|
||||
/obj/item/projectile/beam/xray
|
||||
name = "xray beam"
|
||||
icon_state = "xray"
|
||||
damage = 15
|
||||
tile_dropoff = 0.75
|
||||
irradiate = 30
|
||||
forcedodge = 1
|
||||
range = 15
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/item/projectile/beam/disabler
|
||||
name = "disabler beam"
|
||||
icon_state = "omnilaser"
|
||||
damage = 30
|
||||
damage_type = STAMINA
|
||||
flag = "energy"
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
eyeblur = 0
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
|
||||
/obj/item/projectile/beam/pulse
|
||||
name = "pulse"
|
||||
icon_state = "u_laser"
|
||||
damage = 50
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_DARKBLUE
|
||||
|
||||
/obj/item/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(istype(target,/turf/)||istype(target,/obj/structure/))
|
||||
target.ex_act(2)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/pulse/shot
|
||||
damage = 40
|
||||
|
||||
/obj/item/projectile/beam/emitter
|
||||
name = "emitter beam"
|
||||
icon_state = "emitter"
|
||||
damage = 30
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/item/projectile/beam/emitter/singularity_pull()
|
||||
return //don't want the emitters to miss
|
||||
|
||||
/obj/item/projectile/beam/lasertag
|
||||
name = "laser tag beam"
|
||||
icon_state = "omnilaser"
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
nodamage = 1
|
||||
damage_type = STAMINA
|
||||
flag = "laser"
|
||||
var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag)
|
||||
log_override = TRUE
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_DARKBLUE
|
||||
|
||||
/obj/item/projectile/beam/lasertag/on_hit(atom/target, blocked = 0)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(istype(M.wear_suit))
|
||||
if(M.wear_suit.type in suit_types)
|
||||
M.adjustStaminaLoss(34)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/beam/lasertag/omni
|
||||
name = "laser tag beam"
|
||||
icon_state = "omnilaser"
|
||||
|
||||
/obj/item/projectile/beam/lasertag/redtag
|
||||
icon_state = "laser"
|
||||
suit_types = list(/obj/item/clothing/suit/bluetag)
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/beam/lasertag/bluetag
|
||||
icon_state = "bluelaser"
|
||||
suit_types = list(/obj/item/clothing/suit/redtag)
|
||||
|
||||
/obj/item/projectile/beam/sniper
|
||||
name = "sniper beam"
|
||||
icon_state = "sniperlaser"
|
||||
damage = 60
|
||||
stun = 5
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
light_color = LIGHT_COLOR_PINK
|
||||
|
||||
/obj/item/projectile/beam/immolator
|
||||
name = "immolation beam"
|
||||
|
||||
/obj/item/projectile/beam/immolator/strong
|
||||
name = "heavy immolation beam"
|
||||
damage = 45
|
||||
icon_state = "heavylaser"
|
||||
|
||||
/obj/item/projectile/beam/immolator/weak
|
||||
name = "light immolation beam"
|
||||
damage = 8
|
||||
icon_state = "scatterlaser"
|
||||
|
||||
/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(istype(target, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.IgniteMob()
|
||||
|
||||
/obj/item/projectile/beam/instakill
|
||||
name = "instagib laser"
|
||||
icon_state = "purple_laser"
|
||||
damage = 200
|
||||
damage_type = BURN
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
light_color = LIGHT_COLOR_PURPLE
|
||||
|
||||
/obj/item/projectile/beam/instakill/blue
|
||||
icon_state = "blue_laser"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
|
||||
light_color = LIGHT_COLOR_DARKBLUE
|
||||
|
||||
/obj/item/projectile/beam/instakill/red
|
||||
icon_state = "red_laser"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/projectile/beam/instakill/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.visible_message("<span class='danger'>[L] explodes!</span>")
|
||||
L.gib()
|
||||
|
||||
@@ -1,300 +1,300 @@
|
||||
/obj/item/projectile/bullet
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
damage = 60
|
||||
damage_type = BRUTE
|
||||
flag = "bullet"
|
||||
hitsound_wall = "ricochet"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet //beanbag, heavy stamina damage
|
||||
name = "beanbag slug"
|
||||
damage = 5
|
||||
stamina = 80
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/booze
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/booze/on_hit(atom/target, blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.AdjustDizzy(20)
|
||||
M.AdjustSlur(20)
|
||||
M.AdjustConfused(20)
|
||||
M.AdjustEyeBlurry(20)
|
||||
M.AdjustDrowsy(20)
|
||||
for(var/datum/reagent/consumable/ethanol/A in M.reagents.reagent_list)
|
||||
M.AdjustParalysis(2)
|
||||
M.AdjustDizzy(10)
|
||||
M.AdjustSlur(10)
|
||||
M.AdjustConfused(10)
|
||||
M.AdjustEyeBlurry(10)
|
||||
M.AdjustDrowsy(10)
|
||||
A.volume += 5 //Because we can
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet2 //detective revolver instastuns, but multiple shots are better for keeping punks down
|
||||
name = "rubber bullet"
|
||||
damage = 5
|
||||
weaken = 3
|
||||
stamina = 60
|
||||
icon_state = "bullet-r"
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet2/invisible //finger gun bullets
|
||||
name = "invisible bullet"
|
||||
damage = 0
|
||||
icon_state = null
|
||||
hitsound_wall = null
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet2/invisible/fake
|
||||
weaken = 0
|
||||
stamina = 0
|
||||
nodamage = 1
|
||||
log_override = TRUE
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet3
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet4
|
||||
name = "rubber bullet"
|
||||
damage = 5
|
||||
stamina = 30
|
||||
icon_state = "bullet-r"
|
||||
|
||||
/obj/item/projectile/bullet/toxinbullet
|
||||
damage = 15
|
||||
damage_type = TOX
|
||||
|
||||
/obj/item/projectile/bullet/incendiary
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.adjust_fire_stacks(4)
|
||||
M.IgniteMob()
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/firebullet
|
||||
damage = 10
|
||||
|
||||
/obj/item/projectile/bullet/armourpiercing
|
||||
damage = 17
|
||||
armour_penetration = 10
|
||||
|
||||
/obj/item/projectile/bullet/pellet
|
||||
name = "pellet"
|
||||
damage = 12.5
|
||||
tile_dropoff = 0.75
|
||||
tile_dropoff_s = 1.25
|
||||
|
||||
/obj/item/projectile/bullet/pellet/rubber
|
||||
name = "rubber pellet"
|
||||
damage = 3
|
||||
stamina = 25
|
||||
icon_state = "bullet-r"
|
||||
|
||||
/obj/item/projectile/bullet/pellet/weak
|
||||
tile_dropoff = 0.55 //Come on it does 6 damage don't be like that.
|
||||
damage = 6
|
||||
|
||||
/obj/item/projectile/bullet/pellet/weak/New()
|
||||
range = rand(1, 8)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/pellet/weak/on_range()
|
||||
do_sparks(1, 1, src)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload
|
||||
damage = 3
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload/New()
|
||||
range = rand(1, 10)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/pellet/assassination
|
||||
damage = 12
|
||||
tile_dropoff = 1 // slightly less damage and greater damage falloff compared to normal buckshot
|
||||
|
||||
/obj/item/projectile/bullet/pellet/assassination/on_hit(atom/target, blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.AdjustSilence(2) // HELP MIME KILLING ME IN MAINT
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
explosion(target, 0, 0, 2)
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload/on_range()
|
||||
explosion(src, 0, 0, 2)
|
||||
do_sparks(3, 3, src)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/midbullet
|
||||
damage = 20
|
||||
stamina = 65 //two rounds from the c20r knocks people down
|
||||
|
||||
/obj/item/projectile/bullet/midbullet_r
|
||||
damage = 5
|
||||
stamina = 75 //Still two rounds to knock people down
|
||||
|
||||
/obj/item/projectile/bullet/midbullet2
|
||||
damage = 25
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3
|
||||
damage = 30
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3/hp
|
||||
damage = 40
|
||||
armour_penetration = -50
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3/ap
|
||||
damage = 27
|
||||
armour_penetration = 40
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3/fire/on_hit(atom/target, blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.IgniteMob()
|
||||
|
||||
/obj/item/projectile/bullet/heavybullet
|
||||
damage = 35
|
||||
|
||||
/obj/item/projectile/bullet/stunshot//taser slugs for shotguns, nothing special
|
||||
name = "stunshot"
|
||||
damage = 5
|
||||
stun = 5
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
jitter = 20
|
||||
range = 7
|
||||
icon_state = "spark"
|
||||
color = "#FFFF00"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shell
|
||||
name = "incendiary slug"
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shell/Move()
|
||||
..()
|
||||
var/turf/location = get_turf(src)
|
||||
if(location)
|
||||
new /obj/effect/hotspot(location)
|
||||
location.hotspot_expose(700, 50, 1)
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shell/dragonsbreath
|
||||
name = "dragonsbreath round"
|
||||
damage = 5
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "dust"
|
||||
damage = 30
|
||||
weaken = 8
|
||||
stun = 8
|
||||
hitsound = 'sound/effects/meteorimpact.ogg'
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
if(istype(target, /atom/movable))
|
||||
var/atom/movable/M = target
|
||||
var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src)))
|
||||
M.throw_at(throw_target, 3, 2)
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/New()
|
||||
..()
|
||||
SpinAnimation()
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/weak
|
||||
damage = 10
|
||||
weaken = 4
|
||||
stun = 4
|
||||
|
||||
/obj/item/projectile/bullet/mime
|
||||
damage = 0
|
||||
stun = 5
|
||||
weaken = 5
|
||||
slur = 20
|
||||
stutter = 20
|
||||
|
||||
/obj/item/projectile/bullet/mime/on_hit(var/atom/target, var/blocked = 0)
|
||||
..(target, blocked)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.Silence(10)
|
||||
else if(istype(target, /obj/mecha/combat/honker))
|
||||
var/obj/mecha/chassis = target
|
||||
chassis.occupant_message("A mimetech anti-honk bullet has hit \the [chassis]!")
|
||||
chassis.use_power(chassis.get_charge() / 2)
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/weapon/honker in chassis.equipment)
|
||||
honker.set_ready_state(0)
|
||||
|
||||
/obj/item/projectile/bullet/dart
|
||||
name = "dart"
|
||||
icon_state = "cbbolt"
|
||||
damage = 6
|
||||
var/piercing = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/dart/New()
|
||||
..()
|
||||
create_reagents(50)
|
||||
reagents.set_reacting(FALSE)
|
||||
|
||||
/obj/item/projectile/bullet/dart/on_hit(var/atom/target, var/blocked = 0, var/hit_zone)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
if(blocked != 100)
|
||||
if(M.can_inject(null, FALSE, hit_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
|
||||
..()
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
return 1
|
||||
else
|
||||
blocked = 100
|
||||
target.visible_message("<span class='danger'>The [name] was deflected!</span>", \
|
||||
"<span class='userdanger'>You were protected against the [name]!</span>")
|
||||
..(target, blocked, hit_zone)
|
||||
reagents.set_reacting(TRUE)
|
||||
reagents.handle_reactions()
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/dart/metalfoam
|
||||
|
||||
/obj/item/projectile/bullet/dart/metalfoam/New()
|
||||
..()
|
||||
reagents.add_reagent("aluminum", 15)
|
||||
reagents.add_reagent("fluorosurfactant", 5)
|
||||
reagents.add_reagent("sacid", 5)
|
||||
|
||||
//This one is for future syringe guns update
|
||||
/obj/item/projectile/bullet/dart/syringe
|
||||
name = "syringe"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "syringeproj"
|
||||
|
||||
/obj/item/projectile/bullet/dart/syringe/tranquilizer
|
||||
|
||||
/obj/item/projectile/bullet/dart/syringe/tranquilizer/New()
|
||||
..()
|
||||
reagents.add_reagent("haloperidol", 15)
|
||||
|
||||
/obj/item/projectile/bullet/neurotoxin
|
||||
name = "neurotoxin spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 5
|
||||
damage_type = TOX
|
||||
weaken = 5
|
||||
|
||||
/obj/item/projectile/bullet/neurotoxin/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isalien(target))
|
||||
weaken = 0
|
||||
nodamage = 1
|
||||
. = ..() // Execute the rest of the code.
|
||||
|
||||
/obj/item/projectile/bullet/cap
|
||||
name = "cap"
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
|
||||
/obj/item/projectile/bullet/cap/fire()
|
||||
loc = null
|
||||
qdel(src)
|
||||
/obj/item/projectile/bullet
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
damage = 60
|
||||
damage_type = BRUTE
|
||||
flag = "bullet"
|
||||
hitsound_wall = "ricochet"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet //beanbag, heavy stamina damage
|
||||
name = "beanbag slug"
|
||||
damage = 5
|
||||
stamina = 80
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/booze
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/booze/on_hit(atom/target, blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.AdjustDizzy(20)
|
||||
M.AdjustSlur(20)
|
||||
M.AdjustConfused(20)
|
||||
M.AdjustEyeBlurry(20)
|
||||
M.AdjustDrowsy(20)
|
||||
for(var/datum/reagent/consumable/ethanol/A in M.reagents.reagent_list)
|
||||
M.AdjustParalysis(2)
|
||||
M.AdjustDizzy(10)
|
||||
M.AdjustSlur(10)
|
||||
M.AdjustConfused(10)
|
||||
M.AdjustEyeBlurry(10)
|
||||
M.AdjustDrowsy(10)
|
||||
A.volume += 5 //Because we can
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet2 //detective revolver instastuns, but multiple shots are better for keeping punks down
|
||||
name = "rubber bullet"
|
||||
damage = 5
|
||||
weaken = 3
|
||||
stamina = 60
|
||||
icon_state = "bullet-r"
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet2/invisible //finger gun bullets
|
||||
name = "invisible bullet"
|
||||
damage = 0
|
||||
icon_state = null
|
||||
hitsound_wall = null
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet2/invisible/fake
|
||||
weaken = 0
|
||||
stamina = 0
|
||||
nodamage = 1
|
||||
log_override = TRUE
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet3
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet4
|
||||
name = "rubber bullet"
|
||||
damage = 5
|
||||
stamina = 30
|
||||
icon_state = "bullet-r"
|
||||
|
||||
/obj/item/projectile/bullet/toxinbullet
|
||||
damage = 15
|
||||
damage_type = TOX
|
||||
|
||||
/obj/item/projectile/bullet/incendiary
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.adjust_fire_stacks(4)
|
||||
M.IgniteMob()
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/firebullet
|
||||
damage = 10
|
||||
|
||||
/obj/item/projectile/bullet/armourpiercing
|
||||
damage = 17
|
||||
armour_penetration = 10
|
||||
|
||||
/obj/item/projectile/bullet/pellet
|
||||
name = "pellet"
|
||||
damage = 12.5
|
||||
tile_dropoff = 0.75
|
||||
tile_dropoff_s = 1.25
|
||||
|
||||
/obj/item/projectile/bullet/pellet/rubber
|
||||
name = "rubber pellet"
|
||||
damage = 3
|
||||
stamina = 25
|
||||
icon_state = "bullet-r"
|
||||
|
||||
/obj/item/projectile/bullet/pellet/weak
|
||||
tile_dropoff = 0.55 //Come on it does 6 damage don't be like that.
|
||||
damage = 6
|
||||
|
||||
/obj/item/projectile/bullet/pellet/weak/New()
|
||||
range = rand(1, 8)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/pellet/weak/on_range()
|
||||
do_sparks(1, 1, src)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload
|
||||
damage = 3
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload/New()
|
||||
range = rand(1, 10)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/pellet/assassination
|
||||
damage = 12
|
||||
tile_dropoff = 1 // slightly less damage and greater damage falloff compared to normal buckshot
|
||||
|
||||
/obj/item/projectile/bullet/pellet/assassination/on_hit(atom/target, blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.AdjustSilence(2) // HELP MIME KILLING ME IN MAINT
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
explosion(target, 0, 0, 2)
|
||||
|
||||
/obj/item/projectile/bullet/pellet/overload/on_range()
|
||||
explosion(src, 0, 0, 2)
|
||||
do_sparks(3, 3, src)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/midbullet
|
||||
damage = 20
|
||||
stamina = 65 //two rounds from the c20r knocks people down
|
||||
|
||||
/obj/item/projectile/bullet/midbullet_r
|
||||
damage = 5
|
||||
stamina = 75 //Still two rounds to knock people down
|
||||
|
||||
/obj/item/projectile/bullet/midbullet2
|
||||
damage = 25
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3
|
||||
damage = 30
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3/hp
|
||||
damage = 40
|
||||
armour_penetration = -50
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3/ap
|
||||
damage = 27
|
||||
armour_penetration = 40
|
||||
|
||||
/obj/item/projectile/bullet/midbullet3/fire/on_hit(atom/target, blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.IgniteMob()
|
||||
|
||||
/obj/item/projectile/bullet/heavybullet
|
||||
damage = 35
|
||||
|
||||
/obj/item/projectile/bullet/stunshot//taser slugs for shotguns, nothing special
|
||||
name = "stunshot"
|
||||
damage = 5
|
||||
stun = 5
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
jitter = 20
|
||||
range = 7
|
||||
icon_state = "spark"
|
||||
color = "#FFFF00"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shell
|
||||
name = "incendiary slug"
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shell/Move()
|
||||
..()
|
||||
var/turf/location = get_turf(src)
|
||||
if(location)
|
||||
new /obj/effect/hotspot(location)
|
||||
location.hotspot_expose(700, 50, 1)
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shell/dragonsbreath
|
||||
name = "dragonsbreath round"
|
||||
damage = 5
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "dust"
|
||||
damage = 30
|
||||
weaken = 8
|
||||
stun = 8
|
||||
hitsound = 'sound/effects/meteorimpact.ogg'
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
if(istype(target, /atom/movable))
|
||||
var/atom/movable/M = target
|
||||
var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src)))
|
||||
M.throw_at(throw_target, 3, 2)
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/New()
|
||||
..()
|
||||
SpinAnimation()
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/weak
|
||||
damage = 10
|
||||
weaken = 4
|
||||
stun = 4
|
||||
|
||||
/obj/item/projectile/bullet/mime
|
||||
damage = 0
|
||||
stun = 5
|
||||
weaken = 5
|
||||
slur = 20
|
||||
stutter = 20
|
||||
|
||||
/obj/item/projectile/bullet/mime/on_hit(var/atom/target, var/blocked = 0)
|
||||
..(target, blocked)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.Silence(10)
|
||||
else if(istype(target, /obj/mecha/combat/honker))
|
||||
var/obj/mecha/chassis = target
|
||||
chassis.occupant_message("A mimetech anti-honk bullet has hit \the [chassis]!")
|
||||
chassis.use_power(chassis.get_charge() / 2)
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/weapon/honker in chassis.equipment)
|
||||
honker.set_ready_state(0)
|
||||
|
||||
/obj/item/projectile/bullet/dart
|
||||
name = "dart"
|
||||
icon_state = "cbbolt"
|
||||
damage = 6
|
||||
var/piercing = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/dart/New()
|
||||
..()
|
||||
create_reagents(50)
|
||||
reagents.set_reacting(FALSE)
|
||||
|
||||
/obj/item/projectile/bullet/dart/on_hit(var/atom/target, var/blocked = 0, var/hit_zone)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
if(blocked != 100)
|
||||
if(M.can_inject(null, FALSE, hit_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
|
||||
..()
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
return 1
|
||||
else
|
||||
blocked = 100
|
||||
target.visible_message("<span class='danger'>The [name] was deflected!</span>", \
|
||||
"<span class='userdanger'>You were protected against the [name]!</span>")
|
||||
..(target, blocked, hit_zone)
|
||||
reagents.set_reacting(TRUE)
|
||||
reagents.handle_reactions()
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/dart/metalfoam
|
||||
|
||||
/obj/item/projectile/bullet/dart/metalfoam/New()
|
||||
..()
|
||||
reagents.add_reagent("aluminum", 15)
|
||||
reagents.add_reagent("fluorosurfactant", 5)
|
||||
reagents.add_reagent("sacid", 5)
|
||||
|
||||
//This one is for future syringe guns update
|
||||
/obj/item/projectile/bullet/dart/syringe
|
||||
name = "syringe"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "syringeproj"
|
||||
|
||||
/obj/item/projectile/bullet/dart/syringe/tranquilizer
|
||||
|
||||
/obj/item/projectile/bullet/dart/syringe/tranquilizer/New()
|
||||
..()
|
||||
reagents.add_reagent("haloperidol", 15)
|
||||
|
||||
/obj/item/projectile/bullet/neurotoxin
|
||||
name = "neurotoxin spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 5
|
||||
damage_type = TOX
|
||||
weaken = 5
|
||||
|
||||
/obj/item/projectile/bullet/neurotoxin/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isalien(target))
|
||||
weaken = 0
|
||||
nodamage = 1
|
||||
. = ..() // Execute the rest of the code.
|
||||
|
||||
/obj/item/projectile/bullet/cap
|
||||
name = "cap"
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
|
||||
/obj/item/projectile/bullet/cap/fire()
|
||||
loc = null
|
||||
qdel(src)
|
||||
|
||||
@@ -1,97 +1,97 @@
|
||||
/obj/item/projectile/energy
|
||||
name = "energy"
|
||||
icon_state = "spark"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
flag = "energy"
|
||||
is_reflectable = TRUE
|
||||
|
||||
/obj/item/projectile/energy/electrode
|
||||
name = "electrode"
|
||||
icon_state = "spark"
|
||||
color = "#FFFF00"
|
||||
nodamage = 1
|
||||
stun = 5
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
jitter = 20
|
||||
hitsound = 'sound/weapons/tase.ogg'
|
||||
range = 7
|
||||
//Damage will be handled on the MOB side, to prevent window shattering.
|
||||
|
||||
/obj/item/projectile/energy/electrode/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks!
|
||||
do_sparks(1, 1, src)
|
||||
else if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(HULK in C.mutations)
|
||||
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
|
||||
else if(C.status_flags & CANWEAKEN)
|
||||
spawn(5)
|
||||
C.do_jitter_animation(jitter)
|
||||
|
||||
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
|
||||
do_sparks(1, 1, src)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/energy/declone
|
||||
name = "declone"
|
||||
icon_state = "declone"
|
||||
damage = 20
|
||||
damage_type = CLONE
|
||||
irradiate = 10
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
|
||||
/obj/item/projectile/energy/dart
|
||||
name = "dart"
|
||||
icon_state = "toxin"
|
||||
damage = 5
|
||||
damage_type = TOX
|
||||
weaken = 5
|
||||
range = 7
|
||||
|
||||
/obj/item/projectile/energy/shuriken
|
||||
name = "shuriken"
|
||||
icon_state = "toxin"
|
||||
damage = 10
|
||||
damage_type = TOX
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
|
||||
/obj/item/projectile/energy/bolt
|
||||
name = "bolt"
|
||||
icon_state = "cbbolt"
|
||||
damage = 15
|
||||
damage_type = TOX
|
||||
nodamage = 0
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
|
||||
/obj/item/projectile/energy/bolt/large
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/energy/shock_revolver
|
||||
name = "shock bolt"
|
||||
icon_state = "purple_laser"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
var/chain
|
||||
|
||||
/obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
..()
|
||||
var/obj/item/projectile/energy/shock_revolver/P = BB
|
||||
spawn(1)
|
||||
P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30)
|
||||
|
||||
/obj/item/projectile/energy/shock_revolver/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
tesla_zap(src, 3, 10000)
|
||||
qdel(chain)
|
||||
|
||||
/obj/item/projectile/energy/toxplasma
|
||||
name = "plasma bolt"
|
||||
icon_state = "energy"
|
||||
damage = 20
|
||||
damage_type = TOX
|
||||
irradiate = 20
|
||||
/obj/item/projectile/energy
|
||||
name = "energy"
|
||||
icon_state = "spark"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
flag = "energy"
|
||||
is_reflectable = TRUE
|
||||
|
||||
/obj/item/projectile/energy/electrode
|
||||
name = "electrode"
|
||||
icon_state = "spark"
|
||||
color = "#FFFF00"
|
||||
nodamage = 1
|
||||
stun = 5
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
jitter = 20
|
||||
hitsound = 'sound/weapons/tase.ogg'
|
||||
range = 7
|
||||
//Damage will be handled on the MOB side, to prevent window shattering.
|
||||
|
||||
/obj/item/projectile/energy/electrode/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks!
|
||||
do_sparks(1, 1, src)
|
||||
else if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(HULK in C.mutations)
|
||||
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
|
||||
else if(C.status_flags & CANWEAKEN)
|
||||
spawn(5)
|
||||
C.do_jitter_animation(jitter)
|
||||
|
||||
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
|
||||
do_sparks(1, 1, src)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/energy/declone
|
||||
name = "declone"
|
||||
icon_state = "declone"
|
||||
damage = 20
|
||||
damage_type = CLONE
|
||||
irradiate = 10
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
|
||||
/obj/item/projectile/energy/dart
|
||||
name = "dart"
|
||||
icon_state = "toxin"
|
||||
damage = 5
|
||||
damage_type = TOX
|
||||
weaken = 5
|
||||
range = 7
|
||||
|
||||
/obj/item/projectile/energy/shuriken
|
||||
name = "shuriken"
|
||||
icon_state = "toxin"
|
||||
damage = 10
|
||||
damage_type = TOX
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
|
||||
/obj/item/projectile/energy/bolt
|
||||
name = "bolt"
|
||||
icon_state = "cbbolt"
|
||||
damage = 15
|
||||
damage_type = TOX
|
||||
nodamage = 0
|
||||
weaken = 5
|
||||
stutter = 5
|
||||
|
||||
/obj/item/projectile/energy/bolt/large
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/energy/shock_revolver
|
||||
name = "shock bolt"
|
||||
icon_state = "purple_laser"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
var/chain
|
||||
|
||||
/obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
..()
|
||||
var/obj/item/projectile/energy/shock_revolver/P = BB
|
||||
spawn(1)
|
||||
P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30)
|
||||
|
||||
/obj/item/projectile/energy/shock_revolver/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
tesla_zap(src, 3, 10000)
|
||||
qdel(chain)
|
||||
|
||||
/obj/item/projectile/energy/toxplasma
|
||||
name = "plasma bolt"
|
||||
icon_state = "energy"
|
||||
damage = 20
|
||||
damage_type = TOX
|
||||
irradiate = 20
|
||||
|
||||
@@ -344,4 +344,4 @@
|
||||
to_chat(target, "<span class='notice'>You get splatted by [src].</span>")
|
||||
M.Weaken(slip_weaken)
|
||||
M.Stun(slip_stun)
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
@@ -77,4 +77,4 @@
|
||||
icon_state = "foamdartsniper_riot"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/sniper/riot
|
||||
stamina = 100
|
||||
log_override = FALSE
|
||||
log_override = FALSE
|
||||
|
||||
@@ -1,348 +1,348 @@
|
||||
/obj/item/projectile/ion
|
||||
name = "ion bolt"
|
||||
icon_state = "ion"
|
||||
damage = 0
|
||||
alwayslog = TRUE
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/ion/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
empulse(target, 1, 1, 1, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/ion/weak
|
||||
|
||||
/obj/item/projectile/ion/weak/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
empulse(target, 0, 0, 1, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/gyro
|
||||
name ="explosive bolt"
|
||||
icon_state= "bolter"
|
||||
damage = 50
|
||||
alwayslog = TRUE
|
||||
flag = "bullet"
|
||||
|
||||
/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
explosion(target, -1, 0, 2, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/a40mm
|
||||
name ="40mm grenade"
|
||||
desc = "USE A WEEL GUN"
|
||||
icon_state= "bolter"
|
||||
alwayslog = TRUE
|
||||
damage = 60
|
||||
flag = "bullet"
|
||||
|
||||
/obj/item/projectile/bullet/a40mm/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
explosion(target, -1, 0, 2, 1, 0, flame_range = 3, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/temp
|
||||
name = "temperature beam"
|
||||
icon_state = "temp_4"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
flag = "energy"
|
||||
var/temperature = 300
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
|
||||
/obj/item/projectile/temp/New(loc, shot_temp)
|
||||
..()
|
||||
if(!isnull(shot_temp))
|
||||
temperature = shot_temp
|
||||
switch(temperature)
|
||||
if(501 to INFINITY)
|
||||
name = "searing beam" //if emagged
|
||||
icon_state = "temp_8"
|
||||
if(400 to 500)
|
||||
name = "burning beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_2
|
||||
icon_state = "temp_7"
|
||||
if(360 to 400)
|
||||
name = "hot beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_1
|
||||
icon_state = "temp_6"
|
||||
if(335 to 360)
|
||||
name = "warm beam" //temp at which players get notified of their high body temp
|
||||
icon_state = "temp_5"
|
||||
if(295 to 335)
|
||||
name = "ambient beam"
|
||||
icon_state = "temp_4"
|
||||
if(260 to 295)
|
||||
name = "cool beam" //temp at which players get notified of their low body temp
|
||||
icon_state = "temp_3"
|
||||
if(200 to 260)
|
||||
name = "cold beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_1
|
||||
icon_state = "temp_2"
|
||||
if(120 to 260)
|
||||
name = "ice beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_2
|
||||
icon_state = "temp_1"
|
||||
if(-INFINITY to 120)
|
||||
name = "freeze beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_3
|
||||
icon_state = "temp_0"
|
||||
else
|
||||
name = "temperature beam"//failsafe
|
||||
icon_state = "temp_4"
|
||||
|
||||
|
||||
/obj/item/projectile/temp/on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob
|
||||
..()
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
M.bodytemperature = temperature
|
||||
if(temperature > 500)//emagged
|
||||
M.adjust_fire_stacks(0.5)
|
||||
M.IgniteMob()
|
||||
playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/meteor
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "small"
|
||||
damage = 0
|
||||
damage_type = BRUTE
|
||||
nodamage = 1
|
||||
flag = "bullet"
|
||||
|
||||
/obj/item/projectile/meteor/Bump(atom/A, yes)
|
||||
if(yes)
|
||||
return
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return
|
||||
playsound(loc, 'sound/effects/meteorimpact.ogg', 40, 1)
|
||||
for(var/mob/M in urange(10, src))
|
||||
if(!M.stat)
|
||||
shake_camera(M, 3, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/energy/floramut
|
||||
name = "alpha somatoray"
|
||||
icon_state = "energy"
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
var/mob/living/M = target
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(IS_PLANT in H.dna.species.species_traits)
|
||||
if(prob(15))
|
||||
M.apply_effect((rand(30,80)),IRRADIATE)
|
||||
M.Weaken(5)
|
||||
M.visible_message("<span class='warning'>[M] writhes in pain as [M.p_their()] vacuoles boil.</span>", "<span class='userdanger'>You writhe in pain as your vacuoles boil!</span>", "<span class='italics'>You hear the crunching of leaves.</span>")
|
||||
if(prob(80))
|
||||
randmutb(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
randmutg(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
M.adjustFireLoss(rand(5,15))
|
||||
M.show_message("<span class='warning'>The radiation beam singes you!</span>")
|
||||
else if(iscarbon(target))
|
||||
M.show_message("<span class='notice'>The radiation beam dissipates harmlessly through your body.</span>")
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/energy/florayield
|
||||
name = "beta somatoray"
|
||||
icon_state = "energy2"
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
var/mob/M = target
|
||||
if(ishuman(target)) //These rays make plantmen fat.
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(IS_PLANT in H.dna.species.species_traits)
|
||||
H.set_nutrition(min(H.nutrition+30, NUTRITION_LEVEL_FULL))
|
||||
else if(iscarbon(target))
|
||||
M.show_message("<span class='notice'>The radiation beam dissipates harmlessly through your body.</span>")
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/projectile/beam/mindflayer
|
||||
name = "flayer ray"
|
||||
|
||||
/obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
M.adjustBrainLoss(20)
|
||||
M.AdjustHallucinate(20)
|
||||
|
||||
/obj/item/projectile/clown
|
||||
name = "snap-pop"
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "snappop"
|
||||
|
||||
/obj/item/projectile/clown/Bump(atom/A as mob|obj|turf|area)
|
||||
do_sparks(3, 1, src)
|
||||
new /obj/effect/decal/cleanable/ash(loc)
|
||||
visible_message("<span class='warning'>The [name] explodes!</span>","<span class='warning'>You hear a snap!</span>")
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/beam/wormhole
|
||||
name = "bluespace beam"
|
||||
icon_state = "spark"
|
||||
hitsound = "sparks"
|
||||
damage = 0
|
||||
var/obj/item/gun/energy/wormhole_projector/gun
|
||||
color = "#33CCFF"
|
||||
nodamage = TRUE
|
||||
|
||||
/obj/item/projectile/beam/wormhole/orange
|
||||
name = "orange bluespace beam"
|
||||
color = "#FF6600"
|
||||
|
||||
/obj/item/projectile/beam/wormhole/New(var/obj/item/ammo_casing/energy/wormhole/casing)
|
||||
if(casing)
|
||||
gun = casing.gun
|
||||
|
||||
/obj/item/projectile/beam/wormhole/on_hit(atom/target)
|
||||
if(ismob(target))
|
||||
if(is_teleport_allowed(target.z))
|
||||
var/turf/portal_destination = pick(orange(6, src))
|
||||
do_teleport(target, portal_destination)
|
||||
return ..()
|
||||
if(!gun)
|
||||
qdel(src)
|
||||
gun.create_portal(src)
|
||||
|
||||
/obj/item/projectile/bullet/frag12
|
||||
name ="explosive slug"
|
||||
damage = 25
|
||||
weaken = 5
|
||||
alwayslog = TRUE
|
||||
|
||||
/obj/item/projectile/bullet/frag12/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
explosion(target, -1, 0, 1)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/plasma
|
||||
name = "plasma blast"
|
||||
icon_state = "plasmacutter"
|
||||
damage_type = BRUTE
|
||||
damage = 5
|
||||
range = 3
|
||||
dismemberment = 20
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
|
||||
/obj/item/projectile/plasma/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(ismineralturf(target))
|
||||
forcedodge = 1
|
||||
var/turf/simulated/mineral/M = target
|
||||
M.gets_drilled(firer)
|
||||
else
|
||||
forcedodge = 0
|
||||
|
||||
/obj/item/projectile/plasma/adv
|
||||
damage = 7
|
||||
range = 5
|
||||
|
||||
/obj/item/projectile/plasma/adv/mech
|
||||
damage = 10
|
||||
range = 9
|
||||
|
||||
/obj/item/projectile/energy/teleport
|
||||
name = "teleportation burst"
|
||||
icon_state = "bluespace"
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
alwayslog = TRUE
|
||||
var/teleport_target = null
|
||||
|
||||
/obj/item/projectile/energy/teleport/New(loc, tele_target)
|
||||
..(loc)
|
||||
if(tele_target)
|
||||
teleport_target = tele_target
|
||||
|
||||
/obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isliving(target))
|
||||
if(teleport_target)
|
||||
do_teleport(target, teleport_target, 0)//teleport what's in the tile to the beacon
|
||||
else
|
||||
do_teleport(target, target, 15) //Otherwise it just warps you off somewhere.
|
||||
add_attack_logs(firer, target, "Shot with a [type] [teleport_target ? "(Destination: [teleport_target])" : ""]")
|
||||
|
||||
/obj/item/projectile/snowball
|
||||
name = "snowball"
|
||||
icon_state = "snowball"
|
||||
hitsound = 'sound/items/dodgeball.ogg'
|
||||
damage = 4
|
||||
damage_type = BURN
|
||||
|
||||
/obj/item/projectile/snowball/on_hit(atom/target) //chilling
|
||||
. = ..()
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/M = target
|
||||
M.bodytemperature = max(0, M.bodytemperature - 50) //each hit will drop your body temp, so don't get surrounded!
|
||||
M.ExtinguishMob() //bright side, they counter being on fire!
|
||||
|
||||
/obj/item/projectile/ornament
|
||||
name = "ornament"
|
||||
icon_state = "ornament-1"
|
||||
hitsound = 'sound/effects/glasshit.ogg'
|
||||
damage = 7
|
||||
damage_type = BRUTE
|
||||
|
||||
/obj/item/projectile/ornament/New()
|
||||
icon_state = pick("ornament-1", "ornament-2")
|
||||
..()
|
||||
|
||||
/obj/item/projectile/ornament/on_hit(atom/target) //knockback
|
||||
..()
|
||||
if(istype(target, /turf))
|
||||
return 0
|
||||
var/obj/T = target
|
||||
var/throwdir = get_dir(firer,target)
|
||||
T.throw_at(get_edge_target_turf(target, throwdir),10,10)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/mimic
|
||||
name = "googly-eyed gun"
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
damage_type = BURN
|
||||
flag = "melee"
|
||||
var/obj/item/gun/stored_gun
|
||||
|
||||
/obj/item/projectile/mimic/New(loc, mimic_type)
|
||||
..(loc)
|
||||
if(mimic_type)
|
||||
stored_gun = new mimic_type(src)
|
||||
icon = stored_gun.icon
|
||||
icon_state = stored_gun.icon_state
|
||||
overlays = stored_gun.overlays
|
||||
SpinAnimation(20, -1)
|
||||
|
||||
/obj/item/projectile/mimic/on_hit(atom/target)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/gun/G = stored_gun
|
||||
stored_gun = null
|
||||
G.forceMove(T)
|
||||
var/mob/living/simple_animal/hostile/mimic/copy/ranged/R = new /mob/living/simple_animal/hostile/mimic/copy/ranged(T, G, firer)
|
||||
if(ismob(target))
|
||||
R.target = target
|
||||
/obj/item/projectile/ion
|
||||
name = "ion bolt"
|
||||
icon_state = "ion"
|
||||
damage = 0
|
||||
alwayslog = TRUE
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/ion/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
empulse(target, 1, 1, 1, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/ion/weak
|
||||
|
||||
/obj/item/projectile/ion/weak/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
empulse(target, 0, 0, 1, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/gyro
|
||||
name ="explosive bolt"
|
||||
icon_state= "bolter"
|
||||
damage = 50
|
||||
alwayslog = TRUE
|
||||
flag = "bullet"
|
||||
|
||||
/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
explosion(target, -1, 0, 2, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/bullet/a40mm
|
||||
name ="40mm grenade"
|
||||
desc = "USE A WEEL GUN"
|
||||
icon_state= "bolter"
|
||||
alwayslog = TRUE
|
||||
damage = 60
|
||||
flag = "bullet"
|
||||
|
||||
/obj/item/projectile/bullet/a40mm/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
explosion(target, -1, 0, 2, 1, 0, flame_range = 3, cause = "[type] fired by [key_name(firer)]")
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/temp
|
||||
name = "temperature beam"
|
||||
icon_state = "temp_4"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
flag = "energy"
|
||||
var/temperature = 300
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
|
||||
/obj/item/projectile/temp/New(loc, shot_temp)
|
||||
..()
|
||||
if(!isnull(shot_temp))
|
||||
temperature = shot_temp
|
||||
switch(temperature)
|
||||
if(501 to INFINITY)
|
||||
name = "searing beam" //if emagged
|
||||
icon_state = "temp_8"
|
||||
if(400 to 500)
|
||||
name = "burning beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_2
|
||||
icon_state = "temp_7"
|
||||
if(360 to 400)
|
||||
name = "hot beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_1
|
||||
icon_state = "temp_6"
|
||||
if(335 to 360)
|
||||
name = "warm beam" //temp at which players get notified of their high body temp
|
||||
icon_state = "temp_5"
|
||||
if(295 to 335)
|
||||
name = "ambient beam"
|
||||
icon_state = "temp_4"
|
||||
if(260 to 295)
|
||||
name = "cool beam" //temp at which players get notified of their low body temp
|
||||
icon_state = "temp_3"
|
||||
if(200 to 260)
|
||||
name = "cold beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_1
|
||||
icon_state = "temp_2"
|
||||
if(120 to 260)
|
||||
name = "ice beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_2
|
||||
icon_state = "temp_1"
|
||||
if(-INFINITY to 120)
|
||||
name = "freeze beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_3
|
||||
icon_state = "temp_0"
|
||||
else
|
||||
name = "temperature beam"//failsafe
|
||||
icon_state = "temp_4"
|
||||
|
||||
|
||||
/obj/item/projectile/temp/on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob
|
||||
..()
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
M.bodytemperature = temperature
|
||||
if(temperature > 500)//emagged
|
||||
M.adjust_fire_stacks(0.5)
|
||||
M.IgniteMob()
|
||||
playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/meteor
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "small"
|
||||
damage = 0
|
||||
damage_type = BRUTE
|
||||
nodamage = 1
|
||||
flag = "bullet"
|
||||
|
||||
/obj/item/projectile/meteor/Bump(atom/A, yes)
|
||||
if(yes)
|
||||
return
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return
|
||||
playsound(loc, 'sound/effects/meteorimpact.ogg', 40, 1)
|
||||
for(var/mob/M in urange(10, src))
|
||||
if(!M.stat)
|
||||
shake_camera(M, 3, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/energy/floramut
|
||||
name = "alpha somatoray"
|
||||
icon_state = "energy"
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
var/mob/living/M = target
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(IS_PLANT in H.dna.species.species_traits)
|
||||
if(prob(15))
|
||||
M.apply_effect((rand(30,80)),IRRADIATE)
|
||||
M.Weaken(5)
|
||||
M.visible_message("<span class='warning'>[M] writhes in pain as [M.p_their()] vacuoles boil.</span>", "<span class='userdanger'>You writhe in pain as your vacuoles boil!</span>", "<span class='italics'>You hear the crunching of leaves.</span>")
|
||||
if(prob(80))
|
||||
randmutb(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
randmutg(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
M.adjustFireLoss(rand(5,15))
|
||||
M.show_message("<span class='warning'>The radiation beam singes you!</span>")
|
||||
else if(iscarbon(target))
|
||||
M.show_message("<span class='notice'>The radiation beam dissipates harmlessly through your body.</span>")
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/energy/florayield
|
||||
name = "beta somatoray"
|
||||
icon_state = "energy2"
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
var/mob/M = target
|
||||
if(ishuman(target)) //These rays make plantmen fat.
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(IS_PLANT in H.dna.species.species_traits)
|
||||
H.set_nutrition(min(H.nutrition+30, NUTRITION_LEVEL_FULL))
|
||||
else if(iscarbon(target))
|
||||
M.show_message("<span class='notice'>The radiation beam dissipates harmlessly through your body.</span>")
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/projectile/beam/mindflayer
|
||||
name = "flayer ray"
|
||||
|
||||
/obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
M.adjustBrainLoss(20)
|
||||
M.AdjustHallucinate(20)
|
||||
|
||||
/obj/item/projectile/clown
|
||||
name = "snap-pop"
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "snappop"
|
||||
|
||||
/obj/item/projectile/clown/Bump(atom/A as mob|obj|turf|area)
|
||||
do_sparks(3, 1, src)
|
||||
new /obj/effect/decal/cleanable/ash(loc)
|
||||
visible_message("<span class='warning'>The [name] explodes!</span>","<span class='warning'>You hear a snap!</span>")
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/beam/wormhole
|
||||
name = "bluespace beam"
|
||||
icon_state = "spark"
|
||||
hitsound = "sparks"
|
||||
damage = 0
|
||||
var/obj/item/gun/energy/wormhole_projector/gun
|
||||
color = "#33CCFF"
|
||||
nodamage = TRUE
|
||||
|
||||
/obj/item/projectile/beam/wormhole/orange
|
||||
name = "orange bluespace beam"
|
||||
color = "#FF6600"
|
||||
|
||||
/obj/item/projectile/beam/wormhole/New(var/obj/item/ammo_casing/energy/wormhole/casing)
|
||||
if(casing)
|
||||
gun = casing.gun
|
||||
|
||||
/obj/item/projectile/beam/wormhole/on_hit(atom/target)
|
||||
if(ismob(target))
|
||||
if(is_teleport_allowed(target.z))
|
||||
var/turf/portal_destination = pick(orange(6, src))
|
||||
do_teleport(target, portal_destination)
|
||||
return ..()
|
||||
if(!gun)
|
||||
qdel(src)
|
||||
gun.create_portal(src)
|
||||
|
||||
/obj/item/projectile/bullet/frag12
|
||||
name ="explosive slug"
|
||||
damage = 25
|
||||
weaken = 5
|
||||
alwayslog = TRUE
|
||||
|
||||
/obj/item/projectile/bullet/frag12/on_hit(atom/target, blocked = 0)
|
||||
..()
|
||||
explosion(target, -1, 0, 1)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/plasma
|
||||
name = "plasma blast"
|
||||
icon_state = "plasmacutter"
|
||||
damage_type = BRUTE
|
||||
damage = 5
|
||||
range = 3
|
||||
dismemberment = 20
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
|
||||
|
||||
/obj/item/projectile/plasma/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(ismineralturf(target))
|
||||
forcedodge = 1
|
||||
var/turf/simulated/mineral/M = target
|
||||
M.gets_drilled(firer)
|
||||
else
|
||||
forcedodge = 0
|
||||
|
||||
/obj/item/projectile/plasma/adv
|
||||
damage = 7
|
||||
range = 5
|
||||
|
||||
/obj/item/projectile/plasma/adv/mech
|
||||
damage = 10
|
||||
range = 9
|
||||
|
||||
/obj/item/projectile/energy/teleport
|
||||
name = "teleportation burst"
|
||||
icon_state = "bluespace"
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
alwayslog = TRUE
|
||||
var/teleport_target = null
|
||||
|
||||
/obj/item/projectile/energy/teleport/New(loc, tele_target)
|
||||
..(loc)
|
||||
if(tele_target)
|
||||
teleport_target = tele_target
|
||||
|
||||
/obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isliving(target))
|
||||
if(teleport_target)
|
||||
do_teleport(target, teleport_target, 0)//teleport what's in the tile to the beacon
|
||||
else
|
||||
do_teleport(target, target, 15) //Otherwise it just warps you off somewhere.
|
||||
add_attack_logs(firer, target, "Shot with a [type] [teleport_target ? "(Destination: [teleport_target])" : ""]")
|
||||
|
||||
/obj/item/projectile/snowball
|
||||
name = "snowball"
|
||||
icon_state = "snowball"
|
||||
hitsound = 'sound/items/dodgeball.ogg'
|
||||
damage = 4
|
||||
damage_type = BURN
|
||||
|
||||
/obj/item/projectile/snowball/on_hit(atom/target) //chilling
|
||||
. = ..()
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/M = target
|
||||
M.bodytemperature = max(0, M.bodytemperature - 50) //each hit will drop your body temp, so don't get surrounded!
|
||||
M.ExtinguishMob() //bright side, they counter being on fire!
|
||||
|
||||
/obj/item/projectile/ornament
|
||||
name = "ornament"
|
||||
icon_state = "ornament-1"
|
||||
hitsound = 'sound/effects/glasshit.ogg'
|
||||
damage = 7
|
||||
damage_type = BRUTE
|
||||
|
||||
/obj/item/projectile/ornament/New()
|
||||
icon_state = pick("ornament-1", "ornament-2")
|
||||
..()
|
||||
|
||||
/obj/item/projectile/ornament/on_hit(atom/target) //knockback
|
||||
..()
|
||||
if(istype(target, /turf))
|
||||
return 0
|
||||
var/obj/T = target
|
||||
var/throwdir = get_dir(firer,target)
|
||||
T.throw_at(get_edge_target_turf(target, throwdir),10,10)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/mimic
|
||||
name = "googly-eyed gun"
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
damage_type = BURN
|
||||
flag = "melee"
|
||||
var/obj/item/gun/stored_gun
|
||||
|
||||
/obj/item/projectile/mimic/New(loc, mimic_type)
|
||||
..(loc)
|
||||
if(mimic_type)
|
||||
stored_gun = new mimic_type(src)
|
||||
icon = stored_gun.icon
|
||||
icon_state = stored_gun.icon_state
|
||||
overlays = stored_gun.overlays
|
||||
SpinAnimation(20, -1)
|
||||
|
||||
/obj/item/projectile/mimic/on_hit(atom/target)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/gun/G = stored_gun
|
||||
stored_gun = null
|
||||
G.forceMove(T)
|
||||
var/mob/living/simple_animal/hostile/mimic/copy/ranged/R = new /mob/living/simple_animal/hostile/mimic/copy/ranged(T, G, firer)
|
||||
if(ismob(target))
|
||||
R.target = target
|
||||
|
||||
Reference in New Issue
Block a user