Merge branch 'ParadiseSS13/master' into runtime-fix-2

This commit is contained in:
joep van der velden
2020-03-18 16:59:49 +01:00
1748 changed files with 191532 additions and 184661 deletions
+222 -221
View File
@@ -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
+148 -148
View File
@@ -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
File diff suppressed because it is too large Load Diff
+220 -212
View File
@@ -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
+159 -159
View File
@@ -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)
+99 -99
View File
@@ -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
+85 -85
View File
@@ -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
+60 -60
View File
@@ -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
+1 -1
View File
@@ -17,4 +17,4 @@
item_state = "armcannonlase"
force = 5
selfcharge = 1
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
+214 -214
View File
@@ -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]" : ""]"
+118 -118
View File
@@ -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)
..()
..()
+355 -355
View File
@@ -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
+171 -171
View File
@@ -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()
+300 -300
View File
@@ -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)
+97 -97
View File
@@ -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
+1 -1
View File
@@ -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
+348 -348
View File
@@ -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