mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 19:47:47 +01:00
Whitespace Standardization [MDB IGNORE] (#15748)
* Update settings * Whitespace changes * Comment out merger hooks in gitattributes Corrupt maps would have to be resolved in repo before hooks could be updated * Revert "Whitespace changes" This reverts commitafbdd1d844. * Whitespace again minus example * Gitignore example changelog * Restore changelog merge setting * Keep older dmi hook attribute until hooks can be updated * update vscode settings too * Renormalize remaining * Revert "Gitignore example changelog" This reverts commitde22ad375d. * Attempt to normalize example.yml (and another file I guess) * Try again
This commit is contained in:
@@ -1,284 +1,284 @@
|
||||
/obj/item/ammo_casing
|
||||
name = "bullet casing"
|
||||
desc = "A bullet casing."
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "s-casing"
|
||||
randpixel = 10
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
throwforce = 1
|
||||
w_class = ITEMSIZE_TINY
|
||||
preserve_item = 1
|
||||
drop_sound = 'sound/items/drop/ring.ogg'
|
||||
pickup_sound = 'sound/items/pickup/ring.ogg'
|
||||
|
||||
var/leaves_residue = 1
|
||||
var/caliber = "" //Which kind of guns it can be loaded into
|
||||
var/projectile_type //The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet - make it so that the projectiles are created only when needed?
|
||||
var/caseless = null //Caseless ammo deletes its self once the projectile is fired.
|
||||
|
||||
/obj/item/ammo_casing/New()
|
||||
..()
|
||||
if(ispath(projectile_type))
|
||||
BB = new projectile_type(src)
|
||||
randpixel_xy()
|
||||
|
||||
//removes the projectile from the ammo casing
|
||||
/obj/item/ammo_casing/proc/expend()
|
||||
. = BB
|
||||
BB = null
|
||||
set_dir(pick(cardinal)) //spin spent casings
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(I.has_tool_quality(TOOL_SCREWDRIVER))
|
||||
if(!BB)
|
||||
to_chat(user, span_blue("There is no bullet in the casing to inscribe anything into."))
|
||||
return
|
||||
|
||||
var/tmp_label = ""
|
||||
var/label_text = sanitizeSafe(tgui_input_text(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label,MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(length(label_text) > 20)
|
||||
to_chat(user, span_red("The inscription can be at most 20 characters long."))
|
||||
else if(!label_text)
|
||||
to_chat(user, span_blue("You scratch the inscription off of [initial(BB)]."))
|
||||
BB.name = initial(BB.name)
|
||||
else
|
||||
to_chat(user, span_blue("You inscribe \"[label_text]\" into \the [initial(BB.name)]."))
|
||||
BB.name = "[initial(BB.name)] (\"[label_text]\")"
|
||||
else if(istype(I, /obj/item/ammo_magazine) && isturf(loc)) // Mass magazine reloading.
|
||||
var/obj/item/ammo_magazine/box = I
|
||||
if (!box.can_remove_ammo || box.reloading)
|
||||
return ..()
|
||||
|
||||
box.reloading = TRUE
|
||||
var/boolets = 0
|
||||
var/turf/floor = loc
|
||||
for(var/obj/item/ammo_casing/bullet in floor)
|
||||
if(box.stored_ammo.len >= box.max_ammo)
|
||||
break
|
||||
if(box.caliber == bullet.caliber && bullet.BB)
|
||||
if (boolets < 1)
|
||||
to_chat(user, "<span class='notice'>You start collecting shells.</span>") // Say it here so it doesn't get said if we don't find anything useful.
|
||||
if(do_after(user,5,box))
|
||||
if(box.stored_ammo.len >= box.max_ammo) // Double check because these can change during the wait.
|
||||
break
|
||||
if(bullet.loc != floor)
|
||||
continue
|
||||
bullet.forceMove(box)
|
||||
box.stored_ammo.Add(bullet)
|
||||
box.update_icon()
|
||||
boolets++
|
||||
else
|
||||
break
|
||||
|
||||
if(boolets > 0)
|
||||
to_chat(user, "<span class='notice'>You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to collect anything!</span>")
|
||||
box.reloading = FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/ammo_casing/update_icon()
|
||||
if(!BB)
|
||||
icon_state = "[initial(icon_state)]-spent"
|
||||
|
||||
/obj/item/ammo_casing/examine(mob/user)
|
||||
. = ..()
|
||||
if (!BB)
|
||||
. += "This one is spent."
|
||||
|
||||
//Gun loading types
|
||||
#define SINGLE_CASING 1 //The gun only accepts ammo_casings. ammo_magazines should never have this as their mag_type.
|
||||
#define SPEEDLOADER 2 //Transfers casings from the mag to the gun when used.
|
||||
#define MAGAZINE 4 //The magazine item itself goes inside the gun
|
||||
|
||||
//An item that holds casings and can be used to put them inside guns
|
||||
/obj/item/ammo_magazine
|
||||
name = "magazine"
|
||||
desc = "A magazine for some kind of gun."
|
||||
icon_state = ".357"
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "syringe_kit"
|
||||
matter = list(MAT_STEEL = 500)
|
||||
throwforce = 5
|
||||
w_class = ITEMSIZE_SMALL
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
preserve_item = 1
|
||||
|
||||
var/list/stored_ammo = list()
|
||||
var/mag_type = SPEEDLOADER //ammo_magazines can only be used with compatible guns. This is not a bitflag, the load_method var on guns is.
|
||||
var/caliber = ".357"
|
||||
var/max_ammo = 7
|
||||
|
||||
var/ammo_type = /obj/item/ammo_casing //ammo type that is initially loaded
|
||||
var/initial_ammo = null
|
||||
|
||||
var/can_remove_ammo = TRUE // Can this thing have bullets removed one-by-one? As of first implementation, only affects smart magazines
|
||||
var/reloading = FALSE // Is this magazine being reloaded, currently? - Currently only useful for automatic pickups, ignored by manual reloading.
|
||||
|
||||
var/multiple_sprites = 0
|
||||
//because BYOND doesn't support numbers as keys in associative lists
|
||||
var/list/icon_keys = list() //keys
|
||||
var/list/ammo_states = list() //values
|
||||
|
||||
/obj/item/ammo_magazine/New()
|
||||
..()
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
if(multiple_sprites)
|
||||
initialize_magazine_icondata(src)
|
||||
|
||||
if(isnull(initial_ammo))
|
||||
initial_ammo = max_ammo
|
||||
|
||||
if(initial_ammo)
|
||||
for(var/i in 1 to initial_ammo)
|
||||
stored_ammo += new ammo_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_magazine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = W
|
||||
if(C.caliber != caliber)
|
||||
to_chat(user, "<span class='warning'>[C] does not fit into [src].</span>")
|
||||
return
|
||||
if(stored_ammo.len >= max_ammo)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
user.remove_from_mob(C)
|
||||
C.forceMove(src)
|
||||
stored_ammo.Add(C)
|
||||
update_icon()
|
||||
if(istype(W, /obj/item/ammo_magazine/clip))
|
||||
var/obj/item/ammo_magazine/clip/L = W
|
||||
if(L.caliber != caliber)
|
||||
to_chat(user, "<span class='warning'>The ammo in [L] does not fit into [src].</span>")
|
||||
return
|
||||
if(!L.stored_ammo.len)
|
||||
to_chat(user, "<span class='warning'>There's no more ammo [L]!</span>")
|
||||
return
|
||||
if(stored_ammo.len >= max_ammo)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
var/obj/item/ammo_casing/AC = L.stored_ammo[1] //select the next casing.
|
||||
L.stored_ammo -= AC //Remove this casing from loaded list of the clip.
|
||||
AC.forceMove(src)
|
||||
stored_ammo.Insert(1, AC) //add it to the head of our magazine's list
|
||||
L.update_icon()
|
||||
playsound(src, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
update_icon()
|
||||
|
||||
// This dumps all the bullets right on the floor
|
||||
/obj/item/ammo_magazine/attack_self(mob/user)
|
||||
if(can_remove_ammo)
|
||||
if(!stored_ammo.len)
|
||||
to_chat(user, "<span class='notice'>[src] is already empty!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You empty [src].</span>")
|
||||
playsound(src, "casing_sound", 50, 1)
|
||||
spawn(7)
|
||||
playsound(src, "casing_sound", 50, 1)
|
||||
spawn(10)
|
||||
playsound(src, "casing_sound", 50, 1)
|
||||
for(var/obj/item/ammo_casing/C in stored_ammo)
|
||||
C.loc = user.loc
|
||||
C.set_dir(pick(cardinal))
|
||||
stored_ammo.Cut()
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] is not designed to be unloaded.</span>")
|
||||
return
|
||||
|
||||
// This puts one bullet from the magazine into your hand
|
||||
/obj/item/ammo_magazine/attack_hand(mob/user)
|
||||
if(can_remove_ammo) // For Smart Magazines
|
||||
if(user.get_inactive_hand() == src)
|
||||
if(stored_ammo.len)
|
||||
var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len]
|
||||
stored_ammo-=C
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("\The [user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/ammo_magazine/update_icon()
|
||||
if(multiple_sprites)
|
||||
//find the lowest key greater than or equal to stored_ammo.len
|
||||
var/new_state = null
|
||||
for(var/idx in 1 to icon_keys.len)
|
||||
var/ammo_count = icon_keys[idx]
|
||||
if (ammo_count >= stored_ammo.len)
|
||||
new_state = ammo_states[idx]
|
||||
break
|
||||
icon_state = (new_state)? new_state : initial(icon_state)
|
||||
|
||||
/obj/item/ammo_magazine/examine(mob/user)
|
||||
. = ..()
|
||||
. += "There [(stored_ammo.len == 1)? "is" : "are"] [stored_ammo.len] round\s left!"
|
||||
|
||||
//magazine icon state caching
|
||||
/var/global/list/magazine_icondata_keys = list()
|
||||
/var/global/list/magazine_icondata_states = list()
|
||||
|
||||
/proc/initialize_magazine_icondata(var/obj/item/ammo_magazine/M)
|
||||
var/typestr = M.type
|
||||
if(!(typestr in magazine_icondata_keys) || !(typestr in magazine_icondata_states))
|
||||
magazine_icondata_cache_add(M)
|
||||
|
||||
M.icon_keys = magazine_icondata_keys[typestr]
|
||||
M.ammo_states = magazine_icondata_states[typestr]
|
||||
|
||||
/proc/magazine_icondata_cache_add(var/obj/item/ammo_magazine/M)
|
||||
var/list/icon_keys = list()
|
||||
var/list/ammo_states = list()
|
||||
var/list/states = cached_icon_states(M.icon)
|
||||
for(var/i = 0, i <= M.max_ammo, i++)
|
||||
var/ammo_state = "[M.icon_state]-[i]"
|
||||
if(ammo_state in states)
|
||||
icon_keys += i
|
||||
ammo_states += ammo_state
|
||||
|
||||
magazine_icondata_keys[M.type] = icon_keys
|
||||
magazine_icondata_states[M.type] = ammo_states
|
||||
|
||||
/*
|
||||
* Ammo Boxes
|
||||
*/
|
||||
|
||||
/obj/item/ammo_magazine/ammo_box
|
||||
name = "ammo box"
|
||||
desc = "A box that holds some kind of ammo."
|
||||
icon = 'icons/obj/ammo_boxes.dmi'
|
||||
icon_state = "pistol"
|
||||
slot_flags = null //You can't fit a box on your belt
|
||||
item_state = "paper"
|
||||
matter = null
|
||||
throwforce = 3
|
||||
throw_speed = 5
|
||||
throw_range = 12
|
||||
preserve_item = 1
|
||||
caliber = ".357"
|
||||
drop_sound = 'sound/items/drop/matchbox.ogg'
|
||||
pickup_sound = 'sound/items/pickup/matchbox.ogg'
|
||||
|
||||
/obj/item/ammo_magazine/ammo_box/AltClick(mob/user)
|
||||
if(can_remove_ammo)
|
||||
if(isliving(user) && Adjacent(user))
|
||||
if(stored_ammo.len)
|
||||
var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len]
|
||||
stored_ammo-=C
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("\The [user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/ammo_magazine/ammo_box/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
. += to_chat(usr, "<span class='notice'>Alt-click to extract contents.</span>")
|
||||
/obj/item/ammo_casing
|
||||
name = "bullet casing"
|
||||
desc = "A bullet casing."
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "s-casing"
|
||||
randpixel = 10
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
throwforce = 1
|
||||
w_class = ITEMSIZE_TINY
|
||||
preserve_item = 1
|
||||
drop_sound = 'sound/items/drop/ring.ogg'
|
||||
pickup_sound = 'sound/items/pickup/ring.ogg'
|
||||
|
||||
var/leaves_residue = 1
|
||||
var/caliber = "" //Which kind of guns it can be loaded into
|
||||
var/projectile_type //The bullet type to create when New() is called
|
||||
var/obj/item/projectile/BB = null //The loaded bullet - make it so that the projectiles are created only when needed?
|
||||
var/caseless = null //Caseless ammo deletes its self once the projectile is fired.
|
||||
|
||||
/obj/item/ammo_casing/New()
|
||||
..()
|
||||
if(ispath(projectile_type))
|
||||
BB = new projectile_type(src)
|
||||
randpixel_xy()
|
||||
|
||||
//removes the projectile from the ammo casing
|
||||
/obj/item/ammo_casing/proc/expend()
|
||||
. = BB
|
||||
BB = null
|
||||
set_dir(pick(cardinal)) //spin spent casings
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(I.has_tool_quality(TOOL_SCREWDRIVER))
|
||||
if(!BB)
|
||||
to_chat(user, span_blue("There is no bullet in the casing to inscribe anything into."))
|
||||
return
|
||||
|
||||
var/tmp_label = ""
|
||||
var/label_text = sanitizeSafe(tgui_input_text(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label,MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(length(label_text) > 20)
|
||||
to_chat(user, span_red("The inscription can be at most 20 characters long."))
|
||||
else if(!label_text)
|
||||
to_chat(user, span_blue("You scratch the inscription off of [initial(BB)]."))
|
||||
BB.name = initial(BB.name)
|
||||
else
|
||||
to_chat(user, span_blue("You inscribe \"[label_text]\" into \the [initial(BB.name)]."))
|
||||
BB.name = "[initial(BB.name)] (\"[label_text]\")"
|
||||
else if(istype(I, /obj/item/ammo_magazine) && isturf(loc)) // Mass magazine reloading.
|
||||
var/obj/item/ammo_magazine/box = I
|
||||
if (!box.can_remove_ammo || box.reloading)
|
||||
return ..()
|
||||
|
||||
box.reloading = TRUE
|
||||
var/boolets = 0
|
||||
var/turf/floor = loc
|
||||
for(var/obj/item/ammo_casing/bullet in floor)
|
||||
if(box.stored_ammo.len >= box.max_ammo)
|
||||
break
|
||||
if(box.caliber == bullet.caliber && bullet.BB)
|
||||
if (boolets < 1)
|
||||
to_chat(user, "<span class='notice'>You start collecting shells.</span>") // Say it here so it doesn't get said if we don't find anything useful.
|
||||
if(do_after(user,5,box))
|
||||
if(box.stored_ammo.len >= box.max_ammo) // Double check because these can change during the wait.
|
||||
break
|
||||
if(bullet.loc != floor)
|
||||
continue
|
||||
bullet.forceMove(box)
|
||||
box.stored_ammo.Add(bullet)
|
||||
box.update_icon()
|
||||
boolets++
|
||||
else
|
||||
break
|
||||
|
||||
if(boolets > 0)
|
||||
to_chat(user, "<span class='notice'>You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to collect anything!</span>")
|
||||
box.reloading = FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/ammo_casing/update_icon()
|
||||
if(!BB)
|
||||
icon_state = "[initial(icon_state)]-spent"
|
||||
|
||||
/obj/item/ammo_casing/examine(mob/user)
|
||||
. = ..()
|
||||
if (!BB)
|
||||
. += "This one is spent."
|
||||
|
||||
//Gun loading types
|
||||
#define SINGLE_CASING 1 //The gun only accepts ammo_casings. ammo_magazines should never have this as their mag_type.
|
||||
#define SPEEDLOADER 2 //Transfers casings from the mag to the gun when used.
|
||||
#define MAGAZINE 4 //The magazine item itself goes inside the gun
|
||||
|
||||
//An item that holds casings and can be used to put them inside guns
|
||||
/obj/item/ammo_magazine
|
||||
name = "magazine"
|
||||
desc = "A magazine for some kind of gun."
|
||||
icon_state = ".357"
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "syringe_kit"
|
||||
matter = list(MAT_STEEL = 500)
|
||||
throwforce = 5
|
||||
w_class = ITEMSIZE_SMALL
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
preserve_item = 1
|
||||
|
||||
var/list/stored_ammo = list()
|
||||
var/mag_type = SPEEDLOADER //ammo_magazines can only be used with compatible guns. This is not a bitflag, the load_method var on guns is.
|
||||
var/caliber = ".357"
|
||||
var/max_ammo = 7
|
||||
|
||||
var/ammo_type = /obj/item/ammo_casing //ammo type that is initially loaded
|
||||
var/initial_ammo = null
|
||||
|
||||
var/can_remove_ammo = TRUE // Can this thing have bullets removed one-by-one? As of first implementation, only affects smart magazines
|
||||
var/reloading = FALSE // Is this magazine being reloaded, currently? - Currently only useful for automatic pickups, ignored by manual reloading.
|
||||
|
||||
var/multiple_sprites = 0
|
||||
//because BYOND doesn't support numbers as keys in associative lists
|
||||
var/list/icon_keys = list() //keys
|
||||
var/list/ammo_states = list() //values
|
||||
|
||||
/obj/item/ammo_magazine/New()
|
||||
..()
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
if(multiple_sprites)
|
||||
initialize_magazine_icondata(src)
|
||||
|
||||
if(isnull(initial_ammo))
|
||||
initial_ammo = max_ammo
|
||||
|
||||
if(initial_ammo)
|
||||
for(var/i in 1 to initial_ammo)
|
||||
stored_ammo += new ammo_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_magazine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = W
|
||||
if(C.caliber != caliber)
|
||||
to_chat(user, "<span class='warning'>[C] does not fit into [src].</span>")
|
||||
return
|
||||
if(stored_ammo.len >= max_ammo)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
user.remove_from_mob(C)
|
||||
C.forceMove(src)
|
||||
stored_ammo.Add(C)
|
||||
update_icon()
|
||||
if(istype(W, /obj/item/ammo_magazine/clip))
|
||||
var/obj/item/ammo_magazine/clip/L = W
|
||||
if(L.caliber != caliber)
|
||||
to_chat(user, "<span class='warning'>The ammo in [L] does not fit into [src].</span>")
|
||||
return
|
||||
if(!L.stored_ammo.len)
|
||||
to_chat(user, "<span class='warning'>There's no more ammo [L]!</span>")
|
||||
return
|
||||
if(stored_ammo.len >= max_ammo)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
var/obj/item/ammo_casing/AC = L.stored_ammo[1] //select the next casing.
|
||||
L.stored_ammo -= AC //Remove this casing from loaded list of the clip.
|
||||
AC.forceMove(src)
|
||||
stored_ammo.Insert(1, AC) //add it to the head of our magazine's list
|
||||
L.update_icon()
|
||||
playsound(src, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
update_icon()
|
||||
|
||||
// This dumps all the bullets right on the floor
|
||||
/obj/item/ammo_magazine/attack_self(mob/user)
|
||||
if(can_remove_ammo)
|
||||
if(!stored_ammo.len)
|
||||
to_chat(user, "<span class='notice'>[src] is already empty!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You empty [src].</span>")
|
||||
playsound(src, "casing_sound", 50, 1)
|
||||
spawn(7)
|
||||
playsound(src, "casing_sound", 50, 1)
|
||||
spawn(10)
|
||||
playsound(src, "casing_sound", 50, 1)
|
||||
for(var/obj/item/ammo_casing/C in stored_ammo)
|
||||
C.loc = user.loc
|
||||
C.set_dir(pick(cardinal))
|
||||
stored_ammo.Cut()
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] is not designed to be unloaded.</span>")
|
||||
return
|
||||
|
||||
// This puts one bullet from the magazine into your hand
|
||||
/obj/item/ammo_magazine/attack_hand(mob/user)
|
||||
if(can_remove_ammo) // For Smart Magazines
|
||||
if(user.get_inactive_hand() == src)
|
||||
if(stored_ammo.len)
|
||||
var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len]
|
||||
stored_ammo-=C
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("\The [user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/ammo_magazine/update_icon()
|
||||
if(multiple_sprites)
|
||||
//find the lowest key greater than or equal to stored_ammo.len
|
||||
var/new_state = null
|
||||
for(var/idx in 1 to icon_keys.len)
|
||||
var/ammo_count = icon_keys[idx]
|
||||
if (ammo_count >= stored_ammo.len)
|
||||
new_state = ammo_states[idx]
|
||||
break
|
||||
icon_state = (new_state)? new_state : initial(icon_state)
|
||||
|
||||
/obj/item/ammo_magazine/examine(mob/user)
|
||||
. = ..()
|
||||
. += "There [(stored_ammo.len == 1)? "is" : "are"] [stored_ammo.len] round\s left!"
|
||||
|
||||
//magazine icon state caching
|
||||
/var/global/list/magazine_icondata_keys = list()
|
||||
/var/global/list/magazine_icondata_states = list()
|
||||
|
||||
/proc/initialize_magazine_icondata(var/obj/item/ammo_magazine/M)
|
||||
var/typestr = M.type
|
||||
if(!(typestr in magazine_icondata_keys) || !(typestr in magazine_icondata_states))
|
||||
magazine_icondata_cache_add(M)
|
||||
|
||||
M.icon_keys = magazine_icondata_keys[typestr]
|
||||
M.ammo_states = magazine_icondata_states[typestr]
|
||||
|
||||
/proc/magazine_icondata_cache_add(var/obj/item/ammo_magazine/M)
|
||||
var/list/icon_keys = list()
|
||||
var/list/ammo_states = list()
|
||||
var/list/states = cached_icon_states(M.icon)
|
||||
for(var/i = 0, i <= M.max_ammo, i++)
|
||||
var/ammo_state = "[M.icon_state]-[i]"
|
||||
if(ammo_state in states)
|
||||
icon_keys += i
|
||||
ammo_states += ammo_state
|
||||
|
||||
magazine_icondata_keys[M.type] = icon_keys
|
||||
magazine_icondata_states[M.type] = ammo_states
|
||||
|
||||
/*
|
||||
* Ammo Boxes
|
||||
*/
|
||||
|
||||
/obj/item/ammo_magazine/ammo_box
|
||||
name = "ammo box"
|
||||
desc = "A box that holds some kind of ammo."
|
||||
icon = 'icons/obj/ammo_boxes.dmi'
|
||||
icon_state = "pistol"
|
||||
slot_flags = null //You can't fit a box on your belt
|
||||
item_state = "paper"
|
||||
matter = null
|
||||
throwforce = 3
|
||||
throw_speed = 5
|
||||
throw_range = 12
|
||||
preserve_item = 1
|
||||
caliber = ".357"
|
||||
drop_sound = 'sound/items/drop/matchbox.ogg'
|
||||
pickup_sound = 'sound/items/pickup/matchbox.ogg'
|
||||
|
||||
/obj/item/ammo_magazine/ammo_box/AltClick(mob/user)
|
||||
if(can_remove_ammo)
|
||||
if(isliving(user) && Adjacent(user))
|
||||
if(stored_ammo.len)
|
||||
var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len]
|
||||
stored_ammo-=C
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("\The [user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/ammo_magazine/ammo_box/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
. += to_chat(usr, "<span class='notice'>Alt-click to extract contents.</span>")
|
||||
|
||||
+802
-802
File diff suppressed because it is too large
Load Diff
@@ -1,266 +1,266 @@
|
||||
/obj/item/weapon/gun/energy
|
||||
name = "energy gun"
|
||||
desc = "A basic energy-based gun."
|
||||
icon_state = "energy"
|
||||
fire_sound_text = "laser blast"
|
||||
|
||||
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
|
||||
var/charge_cost = 240 //How much energy is needed to fire.
|
||||
|
||||
var/accept_cell_type = /obj/item/weapon/cell/device
|
||||
var/cell_type = /obj/item/weapon/cell/device/weapon
|
||||
projectile_type = /obj/item/projectile/beam/practice
|
||||
|
||||
var/modifystate
|
||||
var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge
|
||||
|
||||
reload_time = 5 //Energy weapons are slower to reload than ballistics by default, but this is no change from current values
|
||||
|
||||
//self-recharging
|
||||
var/self_recharge = 0 //if set, the weapon will recharge itself
|
||||
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
|
||||
var/use_organic_power = 0 // If set, the weapon will draw from nutrition or blood.
|
||||
var/recharge_time = 4
|
||||
var/charge_tick = 0
|
||||
var/charge_delay = 75 //delay between firing and charging
|
||||
var/shot_counter = TRUE // does this gun tell you how many shots it has?
|
||||
|
||||
var/battery_lock = 0 //If set, weapon cannot switch batteries
|
||||
var/random_start_ammo = FALSE //if TRUE, the weapon will spawn with randomly-determined ammo
|
||||
|
||||
/obj/item/weapon/gun/energy/New()
|
||||
..()
|
||||
if(self_recharge)
|
||||
power_supply = new /obj/item/weapon/cell/device/weapon(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
if(cell_type)
|
||||
power_supply = new cell_type(src)
|
||||
else
|
||||
power_supply = null
|
||||
//random starting power! gives us a random number of shots in the battery between 0 and the max possible
|
||||
if(random_start_ammo && cell_type)
|
||||
power_supply.charge = charge_cost*rand(0,power_supply.maxcharge/charge_cost)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/Destroy()
|
||||
if(self_recharge)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/energy/get_cell()
|
||||
return power_supply
|
||||
|
||||
/obj/item/weapon/gun/energy/process()
|
||||
if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the battery
|
||||
if(world.time > last_shot + charge_delay) //Doesn't work if you've fired recently
|
||||
if(!power_supply || power_supply.charge >= power_supply.maxcharge)
|
||||
return 0 // check if we actually need to recharge
|
||||
|
||||
charge_tick++
|
||||
if(charge_tick < recharge_time) return 0
|
||||
charge_tick = 0
|
||||
|
||||
var/rechargeamt = power_supply.maxcharge*0.2
|
||||
|
||||
if(use_external_power)
|
||||
var/obj/item/weapon/cell/external = get_external_power_supply()
|
||||
if(!external || !external.use(rechargeamt)) //Take power from the borg...
|
||||
return 0
|
||||
|
||||
if(use_organic_power)
|
||||
var/mob/living/carbon/human/H
|
||||
if(ishuman(loc))
|
||||
H = loc
|
||||
|
||||
if(istype(loc, /obj/item/organ))
|
||||
var/obj/item/organ/O = loc
|
||||
if(O.owner)
|
||||
H = O.owner
|
||||
|
||||
if(istype(H))
|
||||
var/start_nutrition = H.nutrition
|
||||
var/end_nutrition = 0
|
||||
|
||||
H.adjust_nutrition(-rechargeamt / 15)
|
||||
|
||||
end_nutrition = H.nutrition
|
||||
|
||||
if(start_nutrition - max(0, end_nutrition) < rechargeamt / 15)
|
||||
|
||||
if(H.isSynthetic())
|
||||
H.adjustToxLoss((rechargeamt / 15) - (start_nutrition - max(0, end_nutrition)))
|
||||
|
||||
else
|
||||
H.remove_blood((rechargeamt / 15) - (start_nutrition - max(0, end_nutrition)))
|
||||
|
||||
power_supply.give(rechargeamt) //... to recharge 1/5th the battery
|
||||
update_icon()
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD
|
||||
else
|
||||
charge_tick = 0
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/energy/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/switch_firemodes(mob/user)
|
||||
if(..())
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/emp_act(severity)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/consume_next_projectile()
|
||||
if(!power_supply) return null
|
||||
if(!ispath(projectile_type)) return null
|
||||
if(!power_supply.checked_use(charge_cost)) return null
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src)
|
||||
return new projectile_type(src)
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/load_ammo(var/obj/item/C, mob/user)
|
||||
if(istype(C, /obj/item/weapon/cell))
|
||||
if(self_recharge || battery_lock)
|
||||
to_chat(user, "<span class='notice'>[src] does not have a battery port.</span>")
|
||||
return
|
||||
if(istype(C, accept_cell_type))
|
||||
var/obj/item/weapon/cell/P = C
|
||||
if(power_supply)
|
||||
to_chat(user, "<span class='notice'>[src] already has a power cell.</span>")
|
||||
else
|
||||
user.visible_message("[user] is reloading [src].", "<span class='notice'>You start to insert [P] into [src].</span>")
|
||||
if(do_after(user, reload_time * P.w_class))
|
||||
user.remove_from_mob(P)
|
||||
power_supply = P
|
||||
P.loc = src
|
||||
user.visible_message("[user] inserts [P] into [src].", "<span class='notice'>You insert [P] into [src].</span>")
|
||||
playsound(src, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
update_icon()
|
||||
update_held_icon()
|
||||
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD
|
||||
else
|
||||
to_chat(user, "<span class='notice'>This cell is not fitted for [src].</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/unload_ammo(mob/user)
|
||||
if(self_recharge || battery_lock)
|
||||
to_chat(user, "<span class='notice'>[src] does not have a battery port.</span>")
|
||||
return
|
||||
if(power_supply)
|
||||
user.put_in_hands(power_supply)
|
||||
power_supply.update_icon()
|
||||
user.visible_message("[user] removes [power_supply] from [src].", "<span class='notice'>You remove [power_supply] from [src].</span>")
|
||||
power_supply = null
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
update_icon()
|
||||
update_held_icon()
|
||||
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] does not have a power cell.</span>")
|
||||
|
||||
/obj/item/weapon/gun/energy/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
..()
|
||||
load_ammo(A, user)
|
||||
|
||||
/obj/item/weapon/gun/energy/attack_hand(mob/user as mob)
|
||||
if(user.get_inactive_hand() == src)
|
||||
unload_ammo(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/get_external_power_supply()
|
||||
if(isrobot(src.loc))
|
||||
var/mob/living/silicon/robot/R = src.loc
|
||||
return R.cell
|
||||
if(istype(src.loc, /obj/item/rig_module))
|
||||
var/obj/item/rig_module/module = src.loc
|
||||
if(module.holder && module.holder.wearer)
|
||||
var/mob/living/carbon/human/H = module.holder.wearer
|
||||
if(istype(H) && H.get_rig())
|
||||
var/obj/item/weapon/rig/suit = H.get_rig()
|
||||
if(istype(suit))
|
||||
return suit.cell
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/energy/examine(mob/user)
|
||||
. = ..()
|
||||
if(shot_counter)
|
||||
if(power_supply)
|
||||
if(charge_cost)
|
||||
var/shots_remaining = round(power_supply.charge / max(1, charge_cost)) // Paranoia
|
||||
. += "Has [shots_remaining] shot\s remaining."
|
||||
else
|
||||
. += "Has infinite shots remaining."
|
||||
else
|
||||
. += "Does not have a power cell."
|
||||
|
||||
/obj/item/weapon/gun/energy/update_icon(var/ignore_inhands)
|
||||
if(power_supply == null)
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate]_open"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_open"
|
||||
return
|
||||
else if(charge_meter)
|
||||
var/ratio = power_supply.charge / power_supply.maxcharge
|
||||
|
||||
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
|
||||
if(power_supply.charge < charge_cost)
|
||||
ratio = 0
|
||||
else
|
||||
ratio = max(round(ratio, 0.25) * 100, 25)
|
||||
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate][ratio]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][ratio]"
|
||||
|
||||
else if(power_supply)
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
if(!ignore_inhands) update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/start_recharge()
|
||||
if(power_supply == null)
|
||||
power_supply = new /obj/item/weapon/cell/device/weapon(src)
|
||||
self_recharge = 1
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/get_description_interaction()
|
||||
var/list/results = list()
|
||||
|
||||
if(!battery_lock && !self_recharge)
|
||||
if(power_supply)
|
||||
results += "[desc_panel_image("offhand")]to remove the weapon cell."
|
||||
else
|
||||
results += "[desc_panel_image("weapon cell")]to add a new weapon cell."
|
||||
|
||||
results += ..()
|
||||
|
||||
return results
|
||||
|
||||
// TGMC AMMO HUD
|
||||
/obj/item/weapon/gun/energy/has_ammo_counter()
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/gun/energy/get_ammo_type()
|
||||
if(!projectile_type)
|
||||
return list("unknown", "unknown")
|
||||
else
|
||||
var/obj/item/projectile/P = projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
|
||||
/obj/item/weapon/gun/energy/get_ammo_count()
|
||||
if(!power_supply)
|
||||
return 0
|
||||
else
|
||||
/obj/item/weapon/gun/energy
|
||||
name = "energy gun"
|
||||
desc = "A basic energy-based gun."
|
||||
icon_state = "energy"
|
||||
fire_sound_text = "laser blast"
|
||||
|
||||
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
|
||||
var/charge_cost = 240 //How much energy is needed to fire.
|
||||
|
||||
var/accept_cell_type = /obj/item/weapon/cell/device
|
||||
var/cell_type = /obj/item/weapon/cell/device/weapon
|
||||
projectile_type = /obj/item/projectile/beam/practice
|
||||
|
||||
var/modifystate
|
||||
var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge
|
||||
|
||||
reload_time = 5 //Energy weapons are slower to reload than ballistics by default, but this is no change from current values
|
||||
|
||||
//self-recharging
|
||||
var/self_recharge = 0 //if set, the weapon will recharge itself
|
||||
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
|
||||
var/use_organic_power = 0 // If set, the weapon will draw from nutrition or blood.
|
||||
var/recharge_time = 4
|
||||
var/charge_tick = 0
|
||||
var/charge_delay = 75 //delay between firing and charging
|
||||
var/shot_counter = TRUE // does this gun tell you how many shots it has?
|
||||
|
||||
var/battery_lock = 0 //If set, weapon cannot switch batteries
|
||||
var/random_start_ammo = FALSE //if TRUE, the weapon will spawn with randomly-determined ammo
|
||||
|
||||
/obj/item/weapon/gun/energy/New()
|
||||
..()
|
||||
if(self_recharge)
|
||||
power_supply = new /obj/item/weapon/cell/device/weapon(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
if(cell_type)
|
||||
power_supply = new cell_type(src)
|
||||
else
|
||||
power_supply = null
|
||||
//random starting power! gives us a random number of shots in the battery between 0 and the max possible
|
||||
if(random_start_ammo && cell_type)
|
||||
power_supply.charge = charge_cost*rand(0,power_supply.maxcharge/charge_cost)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/Destroy()
|
||||
if(self_recharge)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/energy/get_cell()
|
||||
return power_supply
|
||||
|
||||
/obj/item/weapon/gun/energy/process()
|
||||
if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the battery
|
||||
if(world.time > last_shot + charge_delay) //Doesn't work if you've fired recently
|
||||
if(!power_supply || power_supply.charge >= power_supply.maxcharge)
|
||||
return 0 // check if we actually need to recharge
|
||||
|
||||
charge_tick++
|
||||
if(charge_tick < recharge_time) return 0
|
||||
charge_tick = 0
|
||||
|
||||
var/rechargeamt = power_supply.maxcharge*0.2
|
||||
|
||||
if(use_external_power)
|
||||
var/obj/item/weapon/cell/external = get_external_power_supply()
|
||||
if(!external || !external.use(rechargeamt)) //Take power from the borg...
|
||||
return 0
|
||||
|
||||
if(use_organic_power)
|
||||
var/mob/living/carbon/human/H
|
||||
if(ishuman(loc))
|
||||
H = loc
|
||||
|
||||
if(istype(loc, /obj/item/organ))
|
||||
var/obj/item/organ/O = loc
|
||||
if(O.owner)
|
||||
H = O.owner
|
||||
|
||||
if(istype(H))
|
||||
var/start_nutrition = H.nutrition
|
||||
var/end_nutrition = 0
|
||||
|
||||
H.adjust_nutrition(-rechargeamt / 15)
|
||||
|
||||
end_nutrition = H.nutrition
|
||||
|
||||
if(start_nutrition - max(0, end_nutrition) < rechargeamt / 15)
|
||||
|
||||
if(H.isSynthetic())
|
||||
H.adjustToxLoss((rechargeamt / 15) - (start_nutrition - max(0, end_nutrition)))
|
||||
|
||||
else
|
||||
H.remove_blood((rechargeamt / 15) - (start_nutrition - max(0, end_nutrition)))
|
||||
|
||||
power_supply.give(rechargeamt) //... to recharge 1/5th the battery
|
||||
update_icon()
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD
|
||||
else
|
||||
charge_tick = 0
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/energy/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/switch_firemodes(mob/user)
|
||||
if(..())
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/emp_act(severity)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/consume_next_projectile()
|
||||
if(!power_supply) return null
|
||||
if(!ispath(projectile_type)) return null
|
||||
if(!power_supply.checked_use(charge_cost)) return null
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src)
|
||||
return new projectile_type(src)
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/load_ammo(var/obj/item/C, mob/user)
|
||||
if(istype(C, /obj/item/weapon/cell))
|
||||
if(self_recharge || battery_lock)
|
||||
to_chat(user, "<span class='notice'>[src] does not have a battery port.</span>")
|
||||
return
|
||||
if(istype(C, accept_cell_type))
|
||||
var/obj/item/weapon/cell/P = C
|
||||
if(power_supply)
|
||||
to_chat(user, "<span class='notice'>[src] already has a power cell.</span>")
|
||||
else
|
||||
user.visible_message("[user] is reloading [src].", "<span class='notice'>You start to insert [P] into [src].</span>")
|
||||
if(do_after(user, reload_time * P.w_class))
|
||||
user.remove_from_mob(P)
|
||||
power_supply = P
|
||||
P.loc = src
|
||||
user.visible_message("[user] inserts [P] into [src].", "<span class='notice'>You insert [P] into [src].</span>")
|
||||
playsound(src, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
update_icon()
|
||||
update_held_icon()
|
||||
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD
|
||||
else
|
||||
to_chat(user, "<span class='notice'>This cell is not fitted for [src].</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/unload_ammo(mob/user)
|
||||
if(self_recharge || battery_lock)
|
||||
to_chat(user, "<span class='notice'>[src] does not have a battery port.</span>")
|
||||
return
|
||||
if(power_supply)
|
||||
user.put_in_hands(power_supply)
|
||||
power_supply.update_icon()
|
||||
user.visible_message("[user] removes [power_supply] from [src].", "<span class='notice'>You remove [power_supply] from [src].</span>")
|
||||
power_supply = null
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
update_icon()
|
||||
update_held_icon()
|
||||
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] does not have a power cell.</span>")
|
||||
|
||||
/obj/item/weapon/gun/energy/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
..()
|
||||
load_ammo(A, user)
|
||||
|
||||
/obj/item/weapon/gun/energy/attack_hand(mob/user as mob)
|
||||
if(user.get_inactive_hand() == src)
|
||||
unload_ammo(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/get_external_power_supply()
|
||||
if(isrobot(src.loc))
|
||||
var/mob/living/silicon/robot/R = src.loc
|
||||
return R.cell
|
||||
if(istype(src.loc, /obj/item/rig_module))
|
||||
var/obj/item/rig_module/module = src.loc
|
||||
if(module.holder && module.holder.wearer)
|
||||
var/mob/living/carbon/human/H = module.holder.wearer
|
||||
if(istype(H) && H.get_rig())
|
||||
var/obj/item/weapon/rig/suit = H.get_rig()
|
||||
if(istype(suit))
|
||||
return suit.cell
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/energy/examine(mob/user)
|
||||
. = ..()
|
||||
if(shot_counter)
|
||||
if(power_supply)
|
||||
if(charge_cost)
|
||||
var/shots_remaining = round(power_supply.charge / max(1, charge_cost)) // Paranoia
|
||||
. += "Has [shots_remaining] shot\s remaining."
|
||||
else
|
||||
. += "Has infinite shots remaining."
|
||||
else
|
||||
. += "Does not have a power cell."
|
||||
|
||||
/obj/item/weapon/gun/energy/update_icon(var/ignore_inhands)
|
||||
if(power_supply == null)
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate]_open"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_open"
|
||||
return
|
||||
else if(charge_meter)
|
||||
var/ratio = power_supply.charge / power_supply.maxcharge
|
||||
|
||||
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
|
||||
if(power_supply.charge < charge_cost)
|
||||
ratio = 0
|
||||
else
|
||||
ratio = max(round(ratio, 0.25) * 100, 25)
|
||||
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate][ratio]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][ratio]"
|
||||
|
||||
else if(power_supply)
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
if(!ignore_inhands) update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/start_recharge()
|
||||
if(power_supply == null)
|
||||
power_supply = new /obj/item/weapon/cell/device/weapon(src)
|
||||
self_recharge = 1
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/get_description_interaction()
|
||||
var/list/results = list()
|
||||
|
||||
if(!battery_lock && !self_recharge)
|
||||
if(power_supply)
|
||||
results += "[desc_panel_image("offhand")]to remove the weapon cell."
|
||||
else
|
||||
results += "[desc_panel_image("weapon cell")]to add a new weapon cell."
|
||||
|
||||
results += ..()
|
||||
|
||||
return results
|
||||
|
||||
// TGMC AMMO HUD
|
||||
/obj/item/weapon/gun/energy/has_ammo_counter()
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/gun/energy/get_ammo_type()
|
||||
if(!projectile_type)
|
||||
return list("unknown", "unknown")
|
||||
else
|
||||
var/obj/item/projectile/P = projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
|
||||
/obj/item/weapon/gun/energy/get_ammo_count()
|
||||
if(!power_supply)
|
||||
return 0
|
||||
else
|
||||
return FLOOR(power_supply.charge / max(charge_cost, 1), 1)
|
||||
@@ -1,166 +1,166 @@
|
||||
/*
|
||||
* Energy Gun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun
|
||||
name = "energy gun"
|
||||
desc = "Another bestseller of Lawson Arms, the LAEP80 Thor is a versatile energy based pistol, capable of switching between low and high \
|
||||
capacity projectile settings. In other words: Stun or Kill."
|
||||
description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile \
|
||||
weapons to security and law enforcement agencies."
|
||||
icon_state = "egunstun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
fire_delay = 8
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
|
||||
modifystate = "egunstun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Rifle
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/rifle
|
||||
name = "energy rifle"
|
||||
desc = "Another bestseller of Lawson Arms, the LAEP100 Svarog is a versatile energy rifle, capable of switching between low and high capacity \
|
||||
projectile settings. In other words: Stun or Kill."
|
||||
icon_state = "riflestun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
wielded_item_state = "riflestun-wielded"
|
||||
force = 8
|
||||
w_class = ITEMSIZE_LARGE
|
||||
fire_delay = 6
|
||||
one_handed_penalty = 30
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 3)
|
||||
modifystate = "riflestun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="riflestun", fire_sound='sound/weapons/Taser.ogg', wielded_item_state="riflestun-wielded", charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="riflekill", fire_sound='sound/weapons/Laser.ogg', wielded_item_state="riflekill-wielded", charge_cost = 240),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Carbine (Burst Laser)
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/burst
|
||||
name = "energy carbine"
|
||||
desc = "The Lawson Arms FM-2t is a versatile energy based carbine made from modifying the original LAEP100 design. It is capable of switching \
|
||||
between stun or kill with a three round burst option for both settings."
|
||||
icon_state = "energystun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
force = 8
|
||||
w_class = ITEMSIZE_LARGE
|
||||
fire_delay = 6
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/weak
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 2, TECH_ILLEGAL = 3)
|
||||
modifystate = "energystun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="energystun", charge_cost = 100),
|
||||
list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="energystun"),
|
||||
list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="energykill", charge_cost = 200),
|
||||
list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="energykill"),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Thompson (RCW)
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/etommy
|
||||
name = "Energy RCW"
|
||||
desc = "The Lawson Arms experimental Rapid Capacitor Weapon is a highly reguarded and deadly peice of military hardware. Using a large drum shaped \
|
||||
capacitor bank the weapon is capable of accurate, rapid burst fire."
|
||||
description_fluff = "The Rapid Capacitor Weapon is one of a few weapons that never saw full production. IT was an experimental Shock Trooper weapon developed by \
|
||||
Lawsom Arms during the Hegemony Conflict. While only a few hundred were made it didn't take long for smaller arms dealers to break apart stolen units and revese engineer \
|
||||
the tech used in their design. While they're an uncommon sight, they're known to be used by roving bands in the Salthan Fyrds as a forms of personal protection because \
|
||||
of their ease of use and firepower."
|
||||
icon_state = "etommy"
|
||||
item_state = "fm-2tkill"
|
||||
force = 8
|
||||
w_class = ITEMSIZE_LARGE
|
||||
fire_delay = 7
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/burstlaser
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MAGNET = 3, TECH_ILLEGAL = 4)
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, charge_cost = 200),
|
||||
list(mode_name="lethal burst", burst=4, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy PDW (Martin)
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/compact
|
||||
name = "personal energy weapon"
|
||||
desc = "The RayZar EW20 \"Martin\" personal energy weapon - or PEW - is Ward-Takahasi's entry into the variable capacity energy gun market. \
|
||||
New users are advised to 'set RayZars to stun'."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist \
|
||||
energy weapons of various types and quality primarily for the civilian market."
|
||||
icon_state = "PDWstun"
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
w_class = ITEMSIZE_SMALL
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 3)
|
||||
modifystate = "PDWstun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="PDWstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="PDWkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Luger
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/eluger
|
||||
name = "energy Luger"
|
||||
desc = "The finest sidearm produced by RauMauser. Although its battery cannot be removed, its ergonomic design makes it easy to shoot, allowing \
|
||||
for rapid follow-up shots. It also has the ability to toggle between stun and kill."
|
||||
icon_state = "ep08stun"
|
||||
item_state = "gun"
|
||||
fire_delay = null // Lugers are quite comfortable to shoot, thus allowing for more controlled follow-up shots. Rate of fire similar to a laser carbine.
|
||||
battery_lock = 1 // In exchange for balance, you cannot remove the battery. Also there's no sprite for that and I fucking suck at sprites. -Ace
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2, TECH_ILLEGAL = 2)
|
||||
modifystate = "ep08stun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="ep08stun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam/eluger, modifystate="ep08kill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 240),
|
||||
)
|
||||
|
||||
/*
|
||||
* Mounted Energy Gun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/mounted
|
||||
name = "mounted energy gun"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/*
|
||||
* Nuclear Energy Gun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/nuclear
|
||||
name = "advanced energy gun"
|
||||
desc = "An energy gun with an experimental miniaturized reactor, based on a Lawson Arms platform."
|
||||
icon_state = "nucgunstun"
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3)
|
||||
slot_flags = SLOT_BELT
|
||||
force = 8 //looks heavier than a pistol
|
||||
w_class = ITEMSIZE_LARGE //Looks bigger than a pistol, too.
|
||||
fire_delay = 6 //This one's not a handgun, it should have the same fire delay as everything else
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
modifystate = null
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="nucgunstun", charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="nucgunkill", charge_cost = 480),
|
||||
/*
|
||||
* Energy Gun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun
|
||||
name = "energy gun"
|
||||
desc = "Another bestseller of Lawson Arms, the LAEP80 Thor is a versatile energy based pistol, capable of switching between low and high \
|
||||
capacity projectile settings. In other words: Stun or Kill."
|
||||
description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile \
|
||||
weapons to security and law enforcement agencies."
|
||||
icon_state = "egunstun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
fire_delay = 8
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
|
||||
modifystate = "egunstun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Rifle
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/rifle
|
||||
name = "energy rifle"
|
||||
desc = "Another bestseller of Lawson Arms, the LAEP100 Svarog is a versatile energy rifle, capable of switching between low and high capacity \
|
||||
projectile settings. In other words: Stun or Kill."
|
||||
icon_state = "riflestun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
wielded_item_state = "riflestun-wielded"
|
||||
force = 8
|
||||
w_class = ITEMSIZE_LARGE
|
||||
fire_delay = 6
|
||||
one_handed_penalty = 30
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 3)
|
||||
modifystate = "riflestun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="riflestun", fire_sound='sound/weapons/Taser.ogg', wielded_item_state="riflestun-wielded", charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="riflekill", fire_sound='sound/weapons/Laser.ogg', wielded_item_state="riflekill-wielded", charge_cost = 240),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Carbine (Burst Laser)
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/burst
|
||||
name = "energy carbine"
|
||||
desc = "The Lawson Arms FM-2t is a versatile energy based carbine made from modifying the original LAEP100 design. It is capable of switching \
|
||||
between stun or kill with a three round burst option for both settings."
|
||||
icon_state = "energystun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
force = 8
|
||||
w_class = ITEMSIZE_LARGE
|
||||
fire_delay = 6
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/weak
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 2, TECH_ILLEGAL = 3)
|
||||
modifystate = "energystun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="energystun", charge_cost = 100),
|
||||
list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="energystun"),
|
||||
list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="energykill", charge_cost = 200),
|
||||
list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="energykill"),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Thompson (RCW)
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/etommy
|
||||
name = "Energy RCW"
|
||||
desc = "The Lawson Arms experimental Rapid Capacitor Weapon is a highly reguarded and deadly peice of military hardware. Using a large drum shaped \
|
||||
capacitor bank the weapon is capable of accurate, rapid burst fire."
|
||||
description_fluff = "The Rapid Capacitor Weapon is one of a few weapons that never saw full production. IT was an experimental Shock Trooper weapon developed by \
|
||||
Lawsom Arms during the Hegemony Conflict. While only a few hundred were made it didn't take long for smaller arms dealers to break apart stolen units and revese engineer \
|
||||
the tech used in their design. While they're an uncommon sight, they're known to be used by roving bands in the Salthan Fyrds as a forms of personal protection because \
|
||||
of their ease of use and firepower."
|
||||
icon_state = "etommy"
|
||||
item_state = "fm-2tkill"
|
||||
force = 8
|
||||
w_class = ITEMSIZE_LARGE
|
||||
fire_delay = 7
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/burstlaser
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MAGNET = 3, TECH_ILLEGAL = 4)
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, charge_cost = 200),
|
||||
list(mode_name="lethal burst", burst=4, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy PDW (Martin)
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/compact
|
||||
name = "personal energy weapon"
|
||||
desc = "The RayZar EW20 \"Martin\" personal energy weapon - or PEW - is Ward-Takahasi's entry into the variable capacity energy gun market. \
|
||||
New users are advised to 'set RayZars to stun'."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist \
|
||||
energy weapons of various types and quality primarily for the civilian market."
|
||||
icon_state = "PDWstun"
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
w_class = ITEMSIZE_SMALL
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 3)
|
||||
modifystate = "PDWstun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="PDWstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="PDWkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
|
||||
)
|
||||
|
||||
/*
|
||||
* Energy Luger
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/eluger
|
||||
name = "energy Luger"
|
||||
desc = "The finest sidearm produced by RauMauser. Although its battery cannot be removed, its ergonomic design makes it easy to shoot, allowing \
|
||||
for rapid follow-up shots. It also has the ability to toggle between stun and kill."
|
||||
icon_state = "ep08stun"
|
||||
item_state = "gun"
|
||||
fire_delay = null // Lugers are quite comfortable to shoot, thus allowing for more controlled follow-up shots. Rate of fire similar to a laser carbine.
|
||||
battery_lock = 1 // In exchange for balance, you cannot remove the battery. Also there's no sprite for that and I fucking suck at sprites. -Ace
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2, TECH_ILLEGAL = 2)
|
||||
modifystate = "ep08stun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="ep08stun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam/eluger, modifystate="ep08kill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 240),
|
||||
)
|
||||
|
||||
/*
|
||||
* Mounted Energy Gun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/mounted
|
||||
name = "mounted energy gun"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/*
|
||||
* Nuclear Energy Gun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/gun/nuclear
|
||||
name = "advanced energy gun"
|
||||
desc = "An energy gun with an experimental miniaturized reactor, based on a Lawson Arms platform."
|
||||
icon_state = "nucgunstun"
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3)
|
||||
slot_flags = SLOT_BELT
|
||||
force = 8 //looks heavier than a pistol
|
||||
w_class = ITEMSIZE_LARGE //Looks bigger than a pistol, too.
|
||||
fire_delay = 6 //This one's not a handgun, it should have the same fire delay as everything else
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
modifystate = null
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="nucgunstun", charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="nucgunkill", charge_cost = 480),
|
||||
)
|
||||
@@ -1,82 +1,82 @@
|
||||
/*
|
||||
* Pulse Rifle
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle
|
||||
name = "\improper LP1 Locust Rifle"
|
||||
desc = "The Bishamonten LP1 is a weapon that uses advanced pulse-based beam generation technology to emit powerful laser blasts. \
|
||||
Because of its complexity and cost, it is rarely seen in use except by specialists."
|
||||
icon_state = "pulse"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
force = 10
|
||||
projectile_type = /obj/item/projectile/beam
|
||||
charge_cost = 120
|
||||
fire_delay = 8
|
||||
sel_mode = 2
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 240),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/mounted
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/*
|
||||
* Pulse Destroyer
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/destroyer
|
||||
name = "\improper LP1 MkII"
|
||||
desc = "A more heavy-duty version of the Bishamonten LP1. It's had all its safety functions ripped out to facilitate the perfect killing machine."
|
||||
icon_state = "pulsedest"
|
||||
projectile_type=/obj/item/projectile/beam/pulse
|
||||
charge_cost = 120
|
||||
fire_delay = 12
|
||||
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/destroyer/attack_self(mob/living/user as mob)
|
||||
to_chat(user, "<span class='warning'>[src.name] has three settings, and they are all DESTROY.</span>")
|
||||
|
||||
/*
|
||||
* Pulse Carbine
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/carbine
|
||||
name = "\improper LP2 Grasshopper Carbine"
|
||||
desc = "The Bishamonten LP2 is a sleek, compact version of the LP1. Because of its smaller design it takes less time to charge a shot."
|
||||
icon_state = "pulsecarbine"
|
||||
charge_cost = 480
|
||||
fire_delay = 2
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 240),
|
||||
)
|
||||
|
||||
/*
|
||||
* Pulse Pistol
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/compact
|
||||
name = "\improper LP4 Mantis Compact"
|
||||
desc = "The Bishamonten LP4 was once the weapon of choice for military officers during the Hegemony War. Today it is little more than a collectors item."
|
||||
description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for \
|
||||
bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. Focused on sleek ‘futurist’ designs which have \
|
||||
largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. Bishamonten weapons \
|
||||
tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons and used very standard \
|
||||
firing mechanisms.The Grasshopper remains one of the smallest production laser pistols ever produced that is still capable of causing significant \
|
||||
damage to organic tissue."
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
icon_state = "pulsepistol"
|
||||
charge_cost = 480
|
||||
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/compact/admin
|
||||
name = "\improper LP4 Mantis Deluxe"
|
||||
desc = "It's not the size of the gun, it's the size of the hole it puts through people."
|
||||
charge_cost = 240
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 240),
|
||||
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 480),
|
||||
/*
|
||||
* Pulse Rifle
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle
|
||||
name = "\improper LP1 Locust Rifle"
|
||||
desc = "The Bishamonten LP1 is a weapon that uses advanced pulse-based beam generation technology to emit powerful laser blasts. \
|
||||
Because of its complexity and cost, it is rarely seen in use except by specialists."
|
||||
icon_state = "pulse"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
force = 10
|
||||
projectile_type = /obj/item/projectile/beam
|
||||
charge_cost = 120
|
||||
fire_delay = 8
|
||||
sel_mode = 2
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 240),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/mounted
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/*
|
||||
* Pulse Destroyer
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/destroyer
|
||||
name = "\improper LP1 MkII"
|
||||
desc = "A more heavy-duty version of the Bishamonten LP1. It's had all its safety functions ripped out to facilitate the perfect killing machine."
|
||||
icon_state = "pulsedest"
|
||||
projectile_type=/obj/item/projectile/beam/pulse
|
||||
charge_cost = 120
|
||||
fire_delay = 12
|
||||
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/destroyer/attack_self(mob/living/user as mob)
|
||||
to_chat(user, "<span class='warning'>[src.name] has three settings, and they are all DESTROY.</span>")
|
||||
|
||||
/*
|
||||
* Pulse Carbine
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/carbine
|
||||
name = "\improper LP2 Grasshopper Carbine"
|
||||
desc = "The Bishamonten LP2 is a sleek, compact version of the LP1. Because of its smaller design it takes less time to charge a shot."
|
||||
icon_state = "pulsecarbine"
|
||||
charge_cost = 480
|
||||
fire_delay = 2
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 120),
|
||||
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 240),
|
||||
)
|
||||
|
||||
/*
|
||||
* Pulse Pistol
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/compact
|
||||
name = "\improper LP4 Mantis Compact"
|
||||
desc = "The Bishamonten LP4 was once the weapon of choice for military officers during the Hegemony War. Today it is little more than a collectors item."
|
||||
description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for \
|
||||
bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. Focused on sleek ‘futurist’ designs which have \
|
||||
largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. Bishamonten weapons \
|
||||
tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons and used very standard \
|
||||
firing mechanisms.The Grasshopper remains one of the smallest production laser pistols ever produced that is still capable of causing significant \
|
||||
damage to organic tissue."
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
icon_state = "pulsepistol"
|
||||
charge_cost = 480
|
||||
|
||||
/obj/item/weapon/gun/energy/pulse_rifle/compact/admin
|
||||
name = "\improper LP4 Mantis Deluxe"
|
||||
desc = "It's not the size of the gun, it's the size of the hole it puts through people."
|
||||
charge_cost = 240
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_delay=null, charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_delay=null, charge_cost = 240),
|
||||
list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_delay=null, charge_cost = 480),
|
||||
)
|
||||
@@ -1,334 +1,334 @@
|
||||
/obj/item/weapon/gun/energy/ionrifle
|
||||
name = "ion rifle"
|
||||
desc = "The RayZar Mk60 EW Halicon is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. Not the best of its type."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market."
|
||||
icon_state = "ionrifle"
|
||||
item_state = "ionrifle"
|
||||
wielded_item_state = "ionrifle-wielded"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 4)
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/ion
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/emp_act(severity)
|
||||
..(max(severity, 4)) //so it doesn't EMP itself, I guess
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/empty
|
||||
cell_type = null
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/pistol
|
||||
name = "ion pistol"
|
||||
desc = "The RayZar Mk63 EW Pan is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. This model sacrifices capacity for portability."
|
||||
icon_state = "ionpistol"
|
||||
item_state = null
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
force = 5
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
charge_cost = 480
|
||||
projectile_type = /obj/item/projectile/ion/pistol
|
||||
|
||||
/obj/item/weapon/gun/energy/decloner
|
||||
name = "biological demolecularisor"
|
||||
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
|
||||
icon_state = "decloner"
|
||||
item_state = "decloner"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_POWER = 3)
|
||||
projectile_type = /obj/item/projectile/energy/declone
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun
|
||||
name = "floral somatoray"
|
||||
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
|
||||
description_fluff = "The floral somatoray is a relatively recent invention of the NanoTrasen corporation, turning a process that once involved transferring plants to massive mutating racks, into a remote interface. Do not look directly into the transmission end."
|
||||
icon_state = "floramut100"
|
||||
item_state = "floramut"
|
||||
projectile_type = /obj/item/projectile/energy/floramut
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
|
||||
modifystate = "floramut"
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
|
||||
var/decl/plantgene/gene = null
|
||||
var/obj/item/weapon/stock_parts/micro_laser/emitter
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="induce mutations", projectile_type=/obj/item/projectile/energy/floramut, modifystate="floramut"),
|
||||
list(mode_name="increase yield", projectile_type=/obj/item/projectile/energy/florayield, modifystate="florayield"),
|
||||
list(mode_name="induce specific mutations", projectile_type=/obj/item/projectile/energy/floramut/gene, modifystate="floramut"),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/Initialize()
|
||||
. = ..()
|
||||
emitter = new(src)
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/examine(var/mob/user)
|
||||
. = ..()
|
||||
if(Adjacent(user))
|
||||
. += "It has [emitter ? emitter : "no micro laser"] installed."
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/stock_parts/micro_laser))
|
||||
if(!emitter)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
emitter = W
|
||||
to_chat(user, "<span class='notice'>You install a [emitter.name] in [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] already has a laser.</span>")
|
||||
|
||||
else if(W.has_tool_quality(TOOL_SCREWDRIVER))
|
||||
if(emitter)
|
||||
to_chat(user, "<span class='notice'>You remove the [emitter.name] from the [src].</span>")
|
||||
emitter.loc = get_turf(src.loc)
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
emitter = null
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There is no micro laser in this [src].</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag)
|
||||
//allow shooting into adjacent hydrotrays regardless of intent
|
||||
if(!emitter)
|
||||
to_chat(user, "<span class='notice'>The [src] has no laser! </span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
return
|
||||
if(adjacent_flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics))
|
||||
user.visible_message("<span class='danger'>\The [user] fires \the [src] into \the [target]!</span>")
|
||||
Fire(target,user)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/verb/select_gene()
|
||||
set name = "Select Gene"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
var/genemask = tgui_input_list(usr, "Choose a gene to modify.", "Gene Choice", SSplants.plant_gene_datums)
|
||||
|
||||
if(!genemask)
|
||||
return
|
||||
|
||||
gene = SSplants.plant_gene_datums[genemask]
|
||||
|
||||
to_chat(usr, "<span class='info'>You set the [src]'s targeted genetic area to [genemask].</span>")
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/consume_next_projectile()
|
||||
. = ..()
|
||||
var/obj/item/projectile/energy/floramut/gene/G = .
|
||||
var/obj/item/projectile/energy/florayield/GY = .
|
||||
var/obj/item/projectile/energy/floramut/GM = .
|
||||
// Inserting the upgrade level of the gun to the projectile as there isn't a better way to do this.
|
||||
if(istype(G))
|
||||
G.gene = gene
|
||||
G.lasermod = emitter.rating
|
||||
else if(istype(GY))
|
||||
GY.lasermod = emitter.rating
|
||||
else if(istype(GM))
|
||||
GM.lasermod = emitter.rating
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun
|
||||
name = "meteor gun"
|
||||
desc = "For the love of god, make sure you're aiming this the right way!"
|
||||
icon_state = "riotgun"
|
||||
item_state = "c20r"
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
w_class = ITEMSIZE_LARGE
|
||||
projectile_type = /obj/item/projectile/meteor
|
||||
cell_type = /obj/item/weapon/cell/potato
|
||||
charge_cost = 100
|
||||
self_recharge = 1
|
||||
recharge_time = 5 //Time it takes for shots to recharge (in ticks)
|
||||
charge_meter = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun/pen
|
||||
name = "meteor pen"
|
||||
desc = "The pen is mightier than the sword."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "pen"
|
||||
item_state = "pen"
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/mindflayer
|
||||
name = "mind flayer"
|
||||
desc = "A custom-built weapon of some kind."
|
||||
icon_state = "xray"
|
||||
projectile_type = /obj/item/projectile/beam/mindflayer
|
||||
|
||||
/obj/item/weapon/gun/energy/toxgun
|
||||
name = "phoron pistol"
|
||||
desc = "A specialized firearm designed to fire lethal bolts of phoron."
|
||||
icon_state = "toxgun"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4)
|
||||
projectile_type = /obj/item/projectile/energy/phoron
|
||||
|
||||
/* Staves */
|
||||
|
||||
/obj/item/weapon/gun/energy/staff
|
||||
name = "staff of change"
|
||||
desc = "An artifact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
item_icons = null
|
||||
icon_state = "staffofchange"
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = ITEMSIZE_LARGE
|
||||
charge_cost = 480
|
||||
projectile_type = /obj/item/projectile/change
|
||||
origin_tech = null
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
charge_meter = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/staff/special_check(var/mob/user)
|
||||
if((user.mind && !wizards.is_antagonist(user.mind)))
|
||||
to_chat(usr, "<span class='warning'>You focus your mind on \the [src], but nothing happens!</span>")
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/energy/staff/handle_click_empty(mob/user = null)
|
||||
if (user)
|
||||
user.visible_message("*fizzle*", "<span class='danger'>*fizzle*</span>")
|
||||
else
|
||||
src.visible_message("*fizzle*")
|
||||
playsound(src, 'sound/effects/sparks1.ogg', 100, 1)
|
||||
/*
|
||||
/obj/item/weapon/gun/energy/staff/animate
|
||||
name = "staff of animation"
|
||||
desc = "An artifact that spits bolts of life force, which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
|
||||
projectile_type = /obj/item/projectile/animate
|
||||
charge_cost = 240
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/staff/focus
|
||||
name = "mental focus"
|
||||
desc = "An artifact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "focus"
|
||||
slot_flags = SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/forcebolt
|
||||
/*
|
||||
attack_self(mob/living/user as mob)
|
||||
if(projectile_type == "/obj/item/projectile/forcebolt")
|
||||
charge_cost = 400
|
||||
to_chat(user, "<span class='warning'>The [src.name] will now strike a small area.</span>")
|
||||
projectile_type = "/obj/item/projectile/forcebolt/strong"
|
||||
else
|
||||
charge_cost = 200
|
||||
to_chat(user, "<span class='warning'>The [src.name] will now strike only a single person.</span>")
|
||||
projectile_type = "/obj/item/projectile/forcebolt"
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/energy/dakkalaser
|
||||
name = "suppression gun"
|
||||
desc = "A massive weapon designed to pressure the opposition by raining down a torrent of energy pellets."
|
||||
icon_state = "dakkalaser"
|
||||
item_state = "dakkalaser"
|
||||
wielded_item_state = "dakkalaser-wielded"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
charge_cost = 24 // 100 shots, it's a spray and pray (to RNGesus) weapon.
|
||||
projectile_type = /obj/item/projectile/energy/blue_pellet
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
accuracy = 75 // Suppressive weapons don't work too well if there's no risk of being hit.
|
||||
burst_delay = 1 // Burst faster than average.
|
||||
origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_ILLEGAL = 6)
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="single shot", burst = 1, burst_accuracy = list(75), dispersion = list(0), charge_cost = 24),
|
||||
list(mode_name="five shot burst", burst = 5, burst_accuracy = list(75,75,75,75,75), dispersion = list(1,1,1,1,1)),
|
||||
list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(75,75,75,75,75,75,75,75,75,75), dispersion = list(2,2,2,2,2,2,2,2,2,2)),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer
|
||||
name = "portable MHD howitzer"
|
||||
desc = "A massive weapon designed to destroy fortifications with a stream of molten tungsten."
|
||||
description_fluff = "A weapon designed by joint cooperation of NanoTrasen, Hephaestus, and SCG scientists. Everything else is red tape and black highlighters."
|
||||
description_info = "This weapon requires a wind-up period before being able to fire. Clicking on a target will create a beam between you and its turf, starting the timer. Upon completion, it will fire at the designated location."
|
||||
icon_state = "mhdhowitzer"
|
||||
item_state = "mhdhowitzer"
|
||||
wielded_item_state = "mhdhowitzer-wielded"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
|
||||
charge_cost = 10000 // Uses large cells, can at max have 3 shots.
|
||||
projectile_type = /obj/item/projectile/beam/tungsten
|
||||
cell_type = /obj/item/weapon/cell/high
|
||||
accept_cell_type = /obj/item/weapon/cell
|
||||
|
||||
accuracy = 75
|
||||
charge_meter = 0
|
||||
one_handed_penalty = 30
|
||||
|
||||
var/power_cycle = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer/proc/pick_random_target(var/turf/T)
|
||||
var/foundmob = FALSE
|
||||
var/foundmobs = list()
|
||||
for(var/mob/living/L in T.contents)
|
||||
foundmob = TRUE
|
||||
foundmobs += L
|
||||
if(foundmob)
|
||||
var/return_target = pick(foundmobs)
|
||||
return return_target
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer/attack(atom/A, mob/living/user, def_zone)
|
||||
if(power_cycle)
|
||||
to_chat(user, "<span class='notice'>\The [src] is already powering up!</span>")
|
||||
return 0
|
||||
var/turf/target_turf = get_turf(A)
|
||||
var/beameffect = user.Beam(target_turf,icon_state="sat_beam",icon='icons/effects/beam.dmi',time=31, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
||||
if(beameffect)
|
||||
user.visible_message("<span class='cult'>[user] aims \the [src] at \the [A].</span>")
|
||||
if(power_supply && power_supply.charge >= charge_cost) //Do a delay for pointblanking too.
|
||||
power_cycle = TRUE
|
||||
if(do_after(user, 30))
|
||||
if(A.loc == target_turf)
|
||||
..(A, user, def_zone)
|
||||
else
|
||||
var/rand_target = pick_random_target(target_turf)
|
||||
if(rand_target)
|
||||
..(rand_target, user, def_zone)
|
||||
else
|
||||
..(target_turf, user, def_zone)
|
||||
else
|
||||
if(beameffect)
|
||||
qdel(beameffect)
|
||||
power_cycle = FALSE
|
||||
else
|
||||
..(A, user, def_zone) //If it can't fire, just bash with no delay.
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer/afterattack(atom/A, mob/living/user, adjacent, params)
|
||||
if(power_cycle)
|
||||
to_chat(user, "<span class='notice'>\The [src] is already powering up!</span>")
|
||||
return 0
|
||||
|
||||
var/turf/target_turf = get_turf(A)
|
||||
|
||||
var/beameffect = user.Beam(target_turf,icon_state="sat_beam",icon='icons/effects/beam.dmi',time=31, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
||||
|
||||
if(beameffect)
|
||||
user.visible_message("<span class='cult'>[user] aims \the [src] at \the [A].</span>")
|
||||
|
||||
if(!power_cycle)
|
||||
power_cycle = TRUE
|
||||
if(do_after(user, 30))
|
||||
if(A.loc == target_turf)
|
||||
..(A, user, adjacent, params)
|
||||
else
|
||||
var/rand_target = pick_random_target(target_turf)
|
||||
if(rand_target)
|
||||
..(rand_target, user, adjacent, params)
|
||||
else
|
||||
..(target_turf, user, adjacent, params)
|
||||
else
|
||||
if(beameffect)
|
||||
qdel(beameffect)
|
||||
handle_click_empty(user)
|
||||
power_cycle = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] is already powering up!</span>")
|
||||
/obj/item/weapon/gun/energy/ionrifle
|
||||
name = "ion rifle"
|
||||
desc = "The RayZar Mk60 EW Halicon is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. Not the best of its type."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market."
|
||||
icon_state = "ionrifle"
|
||||
item_state = "ionrifle"
|
||||
wielded_item_state = "ionrifle-wielded"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 4)
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/ion
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/emp_act(severity)
|
||||
..(max(severity, 4)) //so it doesn't EMP itself, I guess
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/empty
|
||||
cell_type = null
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/pistol
|
||||
name = "ion pistol"
|
||||
desc = "The RayZar Mk63 EW Pan is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. This model sacrifices capacity for portability."
|
||||
icon_state = "ionpistol"
|
||||
item_state = null
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
force = 5
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
charge_cost = 480
|
||||
projectile_type = /obj/item/projectile/ion/pistol
|
||||
|
||||
/obj/item/weapon/gun/energy/decloner
|
||||
name = "biological demolecularisor"
|
||||
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
|
||||
icon_state = "decloner"
|
||||
item_state = "decloner"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_POWER = 3)
|
||||
projectile_type = /obj/item/projectile/energy/declone
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun
|
||||
name = "floral somatoray"
|
||||
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
|
||||
description_fluff = "The floral somatoray is a relatively recent invention of the NanoTrasen corporation, turning a process that once involved transferring plants to massive mutating racks, into a remote interface. Do not look directly into the transmission end."
|
||||
icon_state = "floramut100"
|
||||
item_state = "floramut"
|
||||
projectile_type = /obj/item/projectile/energy/floramut
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
|
||||
modifystate = "floramut"
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
|
||||
var/decl/plantgene/gene = null
|
||||
var/obj/item/weapon/stock_parts/micro_laser/emitter
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="induce mutations", projectile_type=/obj/item/projectile/energy/floramut, modifystate="floramut"),
|
||||
list(mode_name="increase yield", projectile_type=/obj/item/projectile/energy/florayield, modifystate="florayield"),
|
||||
list(mode_name="induce specific mutations", projectile_type=/obj/item/projectile/energy/floramut/gene, modifystate="floramut"),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/Initialize()
|
||||
. = ..()
|
||||
emitter = new(src)
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/examine(var/mob/user)
|
||||
. = ..()
|
||||
if(Adjacent(user))
|
||||
. += "It has [emitter ? emitter : "no micro laser"] installed."
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/stock_parts/micro_laser))
|
||||
if(!emitter)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
emitter = W
|
||||
to_chat(user, "<span class='notice'>You install a [emitter.name] in [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] already has a laser.</span>")
|
||||
|
||||
else if(W.has_tool_quality(TOOL_SCREWDRIVER))
|
||||
if(emitter)
|
||||
to_chat(user, "<span class='notice'>You remove the [emitter.name] from the [src].</span>")
|
||||
emitter.loc = get_turf(src.loc)
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
emitter = null
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There is no micro laser in this [src].</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag)
|
||||
//allow shooting into adjacent hydrotrays regardless of intent
|
||||
if(!emitter)
|
||||
to_chat(user, "<span class='notice'>The [src] has no laser! </span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
return
|
||||
if(adjacent_flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics))
|
||||
user.visible_message("<span class='danger'>\The [user] fires \the [src] into \the [target]!</span>")
|
||||
Fire(target,user)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/verb/select_gene()
|
||||
set name = "Select Gene"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
var/genemask = tgui_input_list(usr, "Choose a gene to modify.", "Gene Choice", SSplants.plant_gene_datums)
|
||||
|
||||
if(!genemask)
|
||||
return
|
||||
|
||||
gene = SSplants.plant_gene_datums[genemask]
|
||||
|
||||
to_chat(usr, "<span class='info'>You set the [src]'s targeted genetic area to [genemask].</span>")
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/consume_next_projectile()
|
||||
. = ..()
|
||||
var/obj/item/projectile/energy/floramut/gene/G = .
|
||||
var/obj/item/projectile/energy/florayield/GY = .
|
||||
var/obj/item/projectile/energy/floramut/GM = .
|
||||
// Inserting the upgrade level of the gun to the projectile as there isn't a better way to do this.
|
||||
if(istype(G))
|
||||
G.gene = gene
|
||||
G.lasermod = emitter.rating
|
||||
else if(istype(GY))
|
||||
GY.lasermod = emitter.rating
|
||||
else if(istype(GM))
|
||||
GM.lasermod = emitter.rating
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun
|
||||
name = "meteor gun"
|
||||
desc = "For the love of god, make sure you're aiming this the right way!"
|
||||
icon_state = "riotgun"
|
||||
item_state = "c20r"
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
w_class = ITEMSIZE_LARGE
|
||||
projectile_type = /obj/item/projectile/meteor
|
||||
cell_type = /obj/item/weapon/cell/potato
|
||||
charge_cost = 100
|
||||
self_recharge = 1
|
||||
recharge_time = 5 //Time it takes for shots to recharge (in ticks)
|
||||
charge_meter = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun/pen
|
||||
name = "meteor pen"
|
||||
desc = "The pen is mightier than the sword."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "pen"
|
||||
item_state = "pen"
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/mindflayer
|
||||
name = "mind flayer"
|
||||
desc = "A custom-built weapon of some kind."
|
||||
icon_state = "xray"
|
||||
projectile_type = /obj/item/projectile/beam/mindflayer
|
||||
|
||||
/obj/item/weapon/gun/energy/toxgun
|
||||
name = "phoron pistol"
|
||||
desc = "A specialized firearm designed to fire lethal bolts of phoron."
|
||||
icon_state = "toxgun"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4)
|
||||
projectile_type = /obj/item/projectile/energy/phoron
|
||||
|
||||
/* Staves */
|
||||
|
||||
/obj/item/weapon/gun/energy/staff
|
||||
name = "staff of change"
|
||||
desc = "An artifact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
item_icons = null
|
||||
icon_state = "staffofchange"
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = ITEMSIZE_LARGE
|
||||
charge_cost = 480
|
||||
projectile_type = /obj/item/projectile/change
|
||||
origin_tech = null
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
charge_meter = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/staff/special_check(var/mob/user)
|
||||
if((user.mind && !wizards.is_antagonist(user.mind)))
|
||||
to_chat(usr, "<span class='warning'>You focus your mind on \the [src], but nothing happens!</span>")
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/energy/staff/handle_click_empty(mob/user = null)
|
||||
if (user)
|
||||
user.visible_message("*fizzle*", "<span class='danger'>*fizzle*</span>")
|
||||
else
|
||||
src.visible_message("*fizzle*")
|
||||
playsound(src, 'sound/effects/sparks1.ogg', 100, 1)
|
||||
/*
|
||||
/obj/item/weapon/gun/energy/staff/animate
|
||||
name = "staff of animation"
|
||||
desc = "An artifact that spits bolts of life force, which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
|
||||
projectile_type = /obj/item/projectile/animate
|
||||
charge_cost = 240
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/staff/focus
|
||||
name = "mental focus"
|
||||
desc = "An artifact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "focus"
|
||||
slot_flags = SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/forcebolt
|
||||
/*
|
||||
attack_self(mob/living/user as mob)
|
||||
if(projectile_type == "/obj/item/projectile/forcebolt")
|
||||
charge_cost = 400
|
||||
to_chat(user, "<span class='warning'>The [src.name] will now strike a small area.</span>")
|
||||
projectile_type = "/obj/item/projectile/forcebolt/strong"
|
||||
else
|
||||
charge_cost = 200
|
||||
to_chat(user, "<span class='warning'>The [src.name] will now strike only a single person.</span>")
|
||||
projectile_type = "/obj/item/projectile/forcebolt"
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/energy/dakkalaser
|
||||
name = "suppression gun"
|
||||
desc = "A massive weapon designed to pressure the opposition by raining down a torrent of energy pellets."
|
||||
icon_state = "dakkalaser"
|
||||
item_state = "dakkalaser"
|
||||
wielded_item_state = "dakkalaser-wielded"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
charge_cost = 24 // 100 shots, it's a spray and pray (to RNGesus) weapon.
|
||||
projectile_type = /obj/item/projectile/energy/blue_pellet
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
accuracy = 75 // Suppressive weapons don't work too well if there's no risk of being hit.
|
||||
burst_delay = 1 // Burst faster than average.
|
||||
origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_ILLEGAL = 6)
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="single shot", burst = 1, burst_accuracy = list(75), dispersion = list(0), charge_cost = 24),
|
||||
list(mode_name="five shot burst", burst = 5, burst_accuracy = list(75,75,75,75,75), dispersion = list(1,1,1,1,1)),
|
||||
list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(75,75,75,75,75,75,75,75,75,75), dispersion = list(2,2,2,2,2,2,2,2,2,2)),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer
|
||||
name = "portable MHD howitzer"
|
||||
desc = "A massive weapon designed to destroy fortifications with a stream of molten tungsten."
|
||||
description_fluff = "A weapon designed by joint cooperation of NanoTrasen, Hephaestus, and SCG scientists. Everything else is red tape and black highlighters."
|
||||
description_info = "This weapon requires a wind-up period before being able to fire. Clicking on a target will create a beam between you and its turf, starting the timer. Upon completion, it will fire at the designated location."
|
||||
icon_state = "mhdhowitzer"
|
||||
item_state = "mhdhowitzer"
|
||||
wielded_item_state = "mhdhowitzer-wielded"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
|
||||
charge_cost = 10000 // Uses large cells, can at max have 3 shots.
|
||||
projectile_type = /obj/item/projectile/beam/tungsten
|
||||
cell_type = /obj/item/weapon/cell/high
|
||||
accept_cell_type = /obj/item/weapon/cell
|
||||
|
||||
accuracy = 75
|
||||
charge_meter = 0
|
||||
one_handed_penalty = 30
|
||||
|
||||
var/power_cycle = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer/proc/pick_random_target(var/turf/T)
|
||||
var/foundmob = FALSE
|
||||
var/foundmobs = list()
|
||||
for(var/mob/living/L in T.contents)
|
||||
foundmob = TRUE
|
||||
foundmobs += L
|
||||
if(foundmob)
|
||||
var/return_target = pick(foundmobs)
|
||||
return return_target
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer/attack(atom/A, mob/living/user, def_zone)
|
||||
if(power_cycle)
|
||||
to_chat(user, "<span class='notice'>\The [src] is already powering up!</span>")
|
||||
return 0
|
||||
var/turf/target_turf = get_turf(A)
|
||||
var/beameffect = user.Beam(target_turf,icon_state="sat_beam",icon='icons/effects/beam.dmi',time=31, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
||||
if(beameffect)
|
||||
user.visible_message("<span class='cult'>[user] aims \the [src] at \the [A].</span>")
|
||||
if(power_supply && power_supply.charge >= charge_cost) //Do a delay for pointblanking too.
|
||||
power_cycle = TRUE
|
||||
if(do_after(user, 30))
|
||||
if(A.loc == target_turf)
|
||||
..(A, user, def_zone)
|
||||
else
|
||||
var/rand_target = pick_random_target(target_turf)
|
||||
if(rand_target)
|
||||
..(rand_target, user, def_zone)
|
||||
else
|
||||
..(target_turf, user, def_zone)
|
||||
else
|
||||
if(beameffect)
|
||||
qdel(beameffect)
|
||||
power_cycle = FALSE
|
||||
else
|
||||
..(A, user, def_zone) //If it can't fire, just bash with no delay.
|
||||
|
||||
/obj/item/weapon/gun/energy/maghowitzer/afterattack(atom/A, mob/living/user, adjacent, params)
|
||||
if(power_cycle)
|
||||
to_chat(user, "<span class='notice'>\The [src] is already powering up!</span>")
|
||||
return 0
|
||||
|
||||
var/turf/target_turf = get_turf(A)
|
||||
|
||||
var/beameffect = user.Beam(target_turf,icon_state="sat_beam",icon='icons/effects/beam.dmi',time=31, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
||||
|
||||
if(beameffect)
|
||||
user.visible_message("<span class='cult'>[user] aims \the [src] at \the [A].</span>")
|
||||
|
||||
if(!power_cycle)
|
||||
power_cycle = TRUE
|
||||
if(do_after(user, 30))
|
||||
if(A.loc == target_turf)
|
||||
..(A, user, adjacent, params)
|
||||
else
|
||||
var/rand_target = pick_random_target(target_turf)
|
||||
if(rand_target)
|
||||
..(rand_target, user, adjacent, params)
|
||||
else
|
||||
..(target_turf, user, adjacent, params)
|
||||
else
|
||||
if(beameffect)
|
||||
qdel(beameffect)
|
||||
handle_click_empty(user)
|
||||
power_cycle = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] is already powering up!</span>")
|
||||
|
||||
@@ -1,102 +1,102 @@
|
||||
/obj/item/weapon/gun/energy/ionrifle/pistol
|
||||
projectile_type = /obj/item/projectile/ion/pistol // still packs a punch but no AoE
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/weak
|
||||
projectile_type = /obj/item/projectile/ion/small
|
||||
|
||||
/obj/item/weapon/gun/energy/medigun //Adminspawn/ERT etc
|
||||
name = "directed restoration system"
|
||||
desc = "The BL-3 'Phoenix' is an adaptation on the ML-3 'Medbeam' design that channels the power of the beam into a single healing laser. It is highly energy-inefficient, but its medical power cannot be denied."
|
||||
force = 5
|
||||
icon_state = "medbeam"
|
||||
item_state = "medbeam"
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi',
|
||||
)
|
||||
slot_flags = SLOT_BELT
|
||||
accuracy = 100
|
||||
fire_delay = 12
|
||||
fire_sound = 'sound/weapons/eluger.ogg'
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/medigun
|
||||
|
||||
accept_cell_type = /obj/item/weapon/cell
|
||||
cell_type = /obj/item/weapon/cell/high
|
||||
charge_cost = 2500
|
||||
|
||||
/obj/item/weapon/gun/energy/bfgtaser
|
||||
name = "9000-series Ball Lightning Taser"
|
||||
desc = "The brainchild of Hephaestus Industries Civil Pacification Division, the BLT-9000 was intended for riot control but despite enthusiastic interest from law-enforcement agencies across the Commonwealth and beyond, its indiscriminate nature led to it being banned from civilian use in virtually all jurisdictions. As a result, most pieces are found in the hands of collectors."
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "BFG"
|
||||
fire_sound = 'sound/effects/phasein.ogg'
|
||||
item_state = "mhdhowitzer"
|
||||
wielded_item_state = "mhdhowitzer-wielded" //Placeholder
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/bullet/BFGtaser
|
||||
fire_delay = 20
|
||||
w_class = ITEMSIZE_LARGE
|
||||
one_handed_penalty = 90 // The thing's heavy and huge.
|
||||
accuracy = 45
|
||||
charge_cost = 2400 //yes, this bad boy empties an entire weapon cell in one shot. What of it?
|
||||
var/spinning_up = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/bfgtaser/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0)
|
||||
if(spinning_up)
|
||||
return
|
||||
if(!power_supply || !power_supply.check_charge(charge_cost))
|
||||
handle_click_empty(user)
|
||||
return
|
||||
|
||||
playsound(src, 'sound/weapons/chargeup.ogg', 100, 1)
|
||||
spinning_up = TRUE
|
||||
update_icon()
|
||||
user.visible_message("<span class='notice'>[user] starts charging the [src]!</span>", \
|
||||
"<span class='notice'>You start charging the [src]!</span>")
|
||||
if(do_after(user, 8, src))
|
||||
spinning_up = FALSE
|
||||
..()
|
||||
else
|
||||
spinning_up = FALSE
|
||||
|
||||
/obj/item/projectile/beam/stun/weak/BFG
|
||||
fire_sound = 'sound/effects/sparks6.ogg'
|
||||
hitsound = 'sound/effects/sparks4.ogg'
|
||||
hitsound_wall = 'sound/effects/sparks7.ogg'
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser
|
||||
name = "lightning ball"
|
||||
icon = 'icons/obj/projectiles_vr.dmi'
|
||||
icon_state = "minitesla"
|
||||
speed=5
|
||||
damage = 100
|
||||
damage_type = AGONY
|
||||
check_armour = "energy"
|
||||
embed_chance = 0
|
||||
hitsound = 'sound/weapons/zapbang.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
var/zaptype = /obj/item/projectile/beam/stun/weak/BFG
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser/process()
|
||||
var/list/victims = list()
|
||||
for(var/mob/living/M in living_mobs(world.view))
|
||||
if(M != firer)
|
||||
victims += M
|
||||
if(LAZYLEN(victims))
|
||||
var/target = pick(victims)
|
||||
var/obj/item/projectile/P = new zaptype(src.loc)
|
||||
P.launch_projectile_from_turf(target = target, target_zone = null, user = firer, params = null, angle_override = null, forced_spread = 0)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser/on_hit()
|
||||
var/list/victims = list()
|
||||
for(var/mob/living/M in living_mobs(world.view))
|
||||
if(M != firer)
|
||||
victims += M
|
||||
if(LAZYLEN(victims))
|
||||
for(var/target in victims)
|
||||
var/obj/item/projectile/P = new zaptype(src.loc)
|
||||
P.launch_projectile_from_turf(target = target, target_zone = null, user = firer, params = null, angle_override = null, forced_spread = 0)
|
||||
/obj/item/weapon/gun/energy/ionrifle/pistol
|
||||
projectile_type = /obj/item/projectile/ion/pistol // still packs a punch but no AoE
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/weak
|
||||
projectile_type = /obj/item/projectile/ion/small
|
||||
|
||||
/obj/item/weapon/gun/energy/medigun //Adminspawn/ERT etc
|
||||
name = "directed restoration system"
|
||||
desc = "The BL-3 'Phoenix' is an adaptation on the ML-3 'Medbeam' design that channels the power of the beam into a single healing laser. It is highly energy-inefficient, but its medical power cannot be denied."
|
||||
force = 5
|
||||
icon_state = "medbeam"
|
||||
item_state = "medbeam"
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi',
|
||||
)
|
||||
slot_flags = SLOT_BELT
|
||||
accuracy = 100
|
||||
fire_delay = 12
|
||||
fire_sound = 'sound/weapons/eluger.ogg'
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/medigun
|
||||
|
||||
accept_cell_type = /obj/item/weapon/cell
|
||||
cell_type = /obj/item/weapon/cell/high
|
||||
charge_cost = 2500
|
||||
|
||||
/obj/item/weapon/gun/energy/bfgtaser
|
||||
name = "9000-series Ball Lightning Taser"
|
||||
desc = "The brainchild of Hephaestus Industries Civil Pacification Division, the BLT-9000 was intended for riot control but despite enthusiastic interest from law-enforcement agencies across the Commonwealth and beyond, its indiscriminate nature led to it being banned from civilian use in virtually all jurisdictions. As a result, most pieces are found in the hands of collectors."
|
||||
icon = 'icons/obj/gun_vr.dmi'
|
||||
icon_state = "BFG"
|
||||
fire_sound = 'sound/effects/phasein.ogg'
|
||||
item_state = "mhdhowitzer"
|
||||
wielded_item_state = "mhdhowitzer-wielded" //Placeholder
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/bullet/BFGtaser
|
||||
fire_delay = 20
|
||||
w_class = ITEMSIZE_LARGE
|
||||
one_handed_penalty = 90 // The thing's heavy and huge.
|
||||
accuracy = 45
|
||||
charge_cost = 2400 //yes, this bad boy empties an entire weapon cell in one shot. What of it?
|
||||
var/spinning_up = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/bfgtaser/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0)
|
||||
if(spinning_up)
|
||||
return
|
||||
if(!power_supply || !power_supply.check_charge(charge_cost))
|
||||
handle_click_empty(user)
|
||||
return
|
||||
|
||||
playsound(src, 'sound/weapons/chargeup.ogg', 100, 1)
|
||||
spinning_up = TRUE
|
||||
update_icon()
|
||||
user.visible_message("<span class='notice'>[user] starts charging the [src]!</span>", \
|
||||
"<span class='notice'>You start charging the [src]!</span>")
|
||||
if(do_after(user, 8, src))
|
||||
spinning_up = FALSE
|
||||
..()
|
||||
else
|
||||
spinning_up = FALSE
|
||||
|
||||
/obj/item/projectile/beam/stun/weak/BFG
|
||||
fire_sound = 'sound/effects/sparks6.ogg'
|
||||
hitsound = 'sound/effects/sparks4.ogg'
|
||||
hitsound_wall = 'sound/effects/sparks7.ogg'
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser
|
||||
name = "lightning ball"
|
||||
icon = 'icons/obj/projectiles_vr.dmi'
|
||||
icon_state = "minitesla"
|
||||
speed=5
|
||||
damage = 100
|
||||
damage_type = AGONY
|
||||
check_armour = "energy"
|
||||
embed_chance = 0
|
||||
hitsound = 'sound/weapons/zapbang.ogg'
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
var/zaptype = /obj/item/projectile/beam/stun/weak/BFG
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser/process()
|
||||
var/list/victims = list()
|
||||
for(var/mob/living/M in living_mobs(world.view))
|
||||
if(M != firer)
|
||||
victims += M
|
||||
if(LAZYLEN(victims))
|
||||
var/target = pick(victims)
|
||||
var/obj/item/projectile/P = new zaptype(src.loc)
|
||||
P.launch_projectile_from_turf(target = target, target_zone = null, user = firer, params = null, angle_override = null, forced_spread = 0)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser/on_hit()
|
||||
var/list/victims = list()
|
||||
for(var/mob/living/M in living_mobs(world.view))
|
||||
if(M != firer)
|
||||
victims += M
|
||||
if(LAZYLEN(victims))
|
||||
for(var/target in victims)
|
||||
var/obj/item/projectile/P = new zaptype(src.loc)
|
||||
P.launch_projectile_from_turf(target = target, target_zone = null, user = firer, params = null, angle_override = null, forced_spread = 0)
|
||||
..()
|
||||
@@ -1,212 +1,212 @@
|
||||
/*
|
||||
* Taser
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/taser
|
||||
name = "taser gun"
|
||||
desc = "The NT Mk30 NL is a small gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T RayZar design."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist \
|
||||
energy weapons of various types and quality primarily for the civilian market."
|
||||
icon_state = "taser"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
charge_cost = 480
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted
|
||||
name = "mounted taser gun"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted/augment
|
||||
self_recharge = 1
|
||||
use_external_power = 0
|
||||
use_organic_power = TRUE
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted/cyborg
|
||||
name = "taser gun"
|
||||
charge_cost = 400
|
||||
recharge_time = 7 //Time it takes for shots to recharge (in ticks)
|
||||
|
||||
/*
|
||||
* Disabler
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/taser/disabler
|
||||
name = "disabler"
|
||||
desc = "The NT Mk4 T-DL is a small gun used for non-lethal takedowns. Produced by NT, it's an archaic device which attacks the target's \
|
||||
nervous-system and is actually a heavily modified version of the NT Mk30 NL. It's use is heavily regulated due to its effects on the body."
|
||||
icon_state = "disabler"
|
||||
projectile_type = /obj/item/projectile/beam/stun/disabler
|
||||
charge_cost = 480
|
||||
|
||||
/*
|
||||
* Crossbow
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/crossbow
|
||||
name = "mini energy-crossbow"
|
||||
desc = "A weapon favored by many mercenary stealth specialists."
|
||||
icon_state = "crossbow"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
item_state = "crossbow"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 2, TECH_ILLEGAL = 5)
|
||||
matter = list(MAT_STEEL = 2000)
|
||||
slot_flags = SLOT_BELT | SLOT_HOLSTER
|
||||
silenced = 1
|
||||
projectile_type = /obj/item/projectile/energy/bolt
|
||||
charge_cost = 480
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
charge_meter = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/ninja
|
||||
name = "energy dart thrower"
|
||||
projectile_type = /obj/item/projectile/energy/dart
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/largecrossbow
|
||||
name = "energy crossbow"
|
||||
desc = "A weapon favored by mercenary infiltration teams."
|
||||
icon_state = "crossbowlarge"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
matter = list(MAT_STEEL = 200000)
|
||||
slot_flags = SLOT_BELT
|
||||
projectile_type = /obj/item/projectile/energy/bolt/large
|
||||
|
||||
/*
|
||||
* Plasma Stun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/plasmastun
|
||||
name = "plasma pulse projector"
|
||||
desc = "The RayZar MA21 Selkie is a weapon that uses a laser pulse to ionise the local atmosphere, creating a disorienting pulse of plasma and deafening shockwave as the wave expands."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market. \
|
||||
Less well known are RayZar's limited-production experimental projects, often in the form of less-lethal weapon solutions."
|
||||
icon_state = "plasma_stun"
|
||||
item_state = "plasma_stun"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_POWER = 3)
|
||||
fire_delay = 20
|
||||
charge_cost = 600
|
||||
projectile_type = /obj/item/projectile/energy/plasmastun
|
||||
|
||||
/*
|
||||
* Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver
|
||||
name = "stun revolver"
|
||||
desc = "A LAEP20 \"Aktzin\". Designed and produced by Lawson Arms under the wing of Hephaestus, \
|
||||
several TSCs have been trying to get a hold of the blueprints for half a decade."
|
||||
description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, \
|
||||
often sold alongside MarsTech projectile weapons to security and law enforcement agencies. \
|
||||
The Aktzin's capsule-based stun ammunition is a closely guarded Hephaestus Industries patent, \
|
||||
and the company has been particularly litigious towards any attempted imitators."
|
||||
icon_state = "stunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
|
||||
projectile_type = /obj/item/projectile/energy/electrode/strong
|
||||
charge_cost = 400
|
||||
|
||||
/*
|
||||
* Detective Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective
|
||||
desc = "A LAEP20 \"Aktzin\". Designed and produced by Lawson Arms under the wing of Hephaestus, \
|
||||
several TSCs have been trying to get a hold of the blueprints for half a decade."
|
||||
var/unique_reskin
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective/update_icon(var/ignore_inhands)
|
||||
if(power_supply == null)
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin]_open"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_open"
|
||||
return
|
||||
else if(charge_meter)
|
||||
var/ratio = power_supply.charge / power_supply.maxcharge
|
||||
|
||||
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
|
||||
if(power_supply.charge < charge_cost)
|
||||
ratio = 0
|
||||
else
|
||||
ratio = max(round(ratio, 0.25) * 100, 25)
|
||||
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin][ratio]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][ratio]"
|
||||
|
||||
else if(power_supply)
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
if(!ignore_inhands) update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Rename your gun. If you're Security."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
var/job = M.mind.assigned_role
|
||||
if(job != "Detective" && job != "Security Officer" && job != "Warden" && job != "Head of Security")
|
||||
to_chat(M, "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>")
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective/verb/reskin_gun()
|
||||
set name = "Resprite gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to choose a sprite for your gun."
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["Lawson Arms LAEP20"] = "stunrevolver"
|
||||
options["Lawson Arms LTX1020"] = "vinstunrevolver"
|
||||
options["Lawson Arms LTX1010"] = "snubstun2revolver"
|
||||
options["Lawson Arms LTX1020 (Blued)"] = "bluedstunrevolver"
|
||||
options["Lawson Arms LTX1020 (Stainless)"] = "stainstunrevolver"
|
||||
options["Lawson Arms LTX1020 (Ace)"] = "snubstunrevolver"
|
||||
options["Lawson Arms LTX1020 (Gold)"] = "goldstunrevolver"
|
||||
var/choice = input(M,"Choose your sprite!","Resprite Gun") in options
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
unique_reskin = options[choice]
|
||||
to_chat(M, "Your gun is now sprited as [choice]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/*
|
||||
* Vintage Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver/vintage
|
||||
name = "vintage stun revolver"
|
||||
desc = "An older model stun revolver that is still in service across the frontier."
|
||||
description_fluff = "The LTX1020 \"Bolter\", a Firefly Co. staple from when the company was in its hayday. \
|
||||
While Firefly Co. has sadly been dissmantled due to bankruptcy, their iconic weapons can still be found \
|
||||
across the frontier as anything from collectors items to surplus equipment. The LTX1020 falls under \
|
||||
the latter category. Several companies have been known to use the base tech within the Bolter to create \
|
||||
their own variants of the Stun Revolver."
|
||||
icon_state = "vinstunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
|
||||
|
||||
/*
|
||||
* Snubnose Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver/snubnose
|
||||
name = "snub stun revolver"
|
||||
desc = "A snub nose stun revolver sporting a rather elegant look."
|
||||
description_fluff = "The LTX1010 \"Stubby\", a Firefly Co. staple from when the company was in its hayday. \
|
||||
While Firefly Co. has sadly been dissmantled due to bankruptcy, their iconic weapons can still be found \
|
||||
across the frontier as anything from collectors items to surplus equipment. The LTX1010 falls under \
|
||||
the latter category. Gangsters and other gentlemanly criminals alike use the Stubby as a means of policing \
|
||||
within their ranks. Hard to argue with the boss with 12000 volts shooting through you."
|
||||
icon_state = "snubstunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
w_class = ITEMSIZE_SMALL //small pistol is small
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
|
||||
/*
|
||||
* Taser
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/taser
|
||||
name = "taser gun"
|
||||
desc = "The NT Mk30 NL is a small gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T RayZar design."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist \
|
||||
energy weapons of various types and quality primarily for the civilian market."
|
||||
icon_state = "taser"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
charge_cost = 480
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted
|
||||
name = "mounted taser gun"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted/augment
|
||||
self_recharge = 1
|
||||
use_external_power = 0
|
||||
use_organic_power = TRUE
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted/cyborg
|
||||
name = "taser gun"
|
||||
charge_cost = 400
|
||||
recharge_time = 7 //Time it takes for shots to recharge (in ticks)
|
||||
|
||||
/*
|
||||
* Disabler
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/taser/disabler
|
||||
name = "disabler"
|
||||
desc = "The NT Mk4 T-DL is a small gun used for non-lethal takedowns. Produced by NT, it's an archaic device which attacks the target's \
|
||||
nervous-system and is actually a heavily modified version of the NT Mk30 NL. It's use is heavily regulated due to its effects on the body."
|
||||
icon_state = "disabler"
|
||||
projectile_type = /obj/item/projectile/beam/stun/disabler
|
||||
charge_cost = 480
|
||||
|
||||
/*
|
||||
* Crossbow
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/crossbow
|
||||
name = "mini energy-crossbow"
|
||||
desc = "A weapon favored by many mercenary stealth specialists."
|
||||
icon_state = "crossbow"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
item_state = "crossbow"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 2, TECH_ILLEGAL = 5)
|
||||
matter = list(MAT_STEEL = 2000)
|
||||
slot_flags = SLOT_BELT | SLOT_HOLSTER
|
||||
silenced = 1
|
||||
projectile_type = /obj/item/projectile/energy/bolt
|
||||
charge_cost = 480
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
charge_meter = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/ninja
|
||||
name = "energy dart thrower"
|
||||
projectile_type = /obj/item/projectile/energy/dart
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/largecrossbow
|
||||
name = "energy crossbow"
|
||||
desc = "A weapon favored by mercenary infiltration teams."
|
||||
icon_state = "crossbowlarge"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
matter = list(MAT_STEEL = 200000)
|
||||
slot_flags = SLOT_BELT
|
||||
projectile_type = /obj/item/projectile/energy/bolt/large
|
||||
|
||||
/*
|
||||
* Plasma Stun
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/plasmastun
|
||||
name = "plasma pulse projector"
|
||||
desc = "The RayZar MA21 Selkie is a weapon that uses a laser pulse to ionise the local atmosphere, creating a disorienting pulse of plasma and deafening shockwave as the wave expands."
|
||||
description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market. \
|
||||
Less well known are RayZar's limited-production experimental projects, often in the form of less-lethal weapon solutions."
|
||||
icon_state = "plasma_stun"
|
||||
item_state = "plasma_stun"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_POWER = 3)
|
||||
fire_delay = 20
|
||||
charge_cost = 600
|
||||
projectile_type = /obj/item/projectile/energy/plasmastun
|
||||
|
||||
/*
|
||||
* Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver
|
||||
name = "stun revolver"
|
||||
desc = "A LAEP20 \"Aktzin\". Designed and produced by Lawson Arms under the wing of Hephaestus, \
|
||||
several TSCs have been trying to get a hold of the blueprints for half a decade."
|
||||
description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, \
|
||||
often sold alongside MarsTech projectile weapons to security and law enforcement agencies. \
|
||||
The Aktzin's capsule-based stun ammunition is a closely guarded Hephaestus Industries patent, \
|
||||
and the company has been particularly litigious towards any attempted imitators."
|
||||
icon_state = "stunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
|
||||
projectile_type = /obj/item/projectile/energy/electrode/strong
|
||||
charge_cost = 400
|
||||
|
||||
/*
|
||||
* Detective Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective
|
||||
desc = "A LAEP20 \"Aktzin\". Designed and produced by Lawson Arms under the wing of Hephaestus, \
|
||||
several TSCs have been trying to get a hold of the blueprints for half a decade."
|
||||
var/unique_reskin
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective/update_icon(var/ignore_inhands)
|
||||
if(power_supply == null)
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin]_open"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_open"
|
||||
return
|
||||
else if(charge_meter)
|
||||
var/ratio = power_supply.charge / power_supply.maxcharge
|
||||
|
||||
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
|
||||
if(power_supply.charge < charge_cost)
|
||||
ratio = 0
|
||||
else
|
||||
ratio = max(round(ratio, 0.25) * 100, 25)
|
||||
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin][ratio]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][ratio]"
|
||||
|
||||
else if(power_supply)
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
if(!ignore_inhands) update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Rename your gun. If you're Security."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
var/job = M.mind.assigned_role
|
||||
if(job != "Detective" && job != "Security Officer" && job != "Warden" && job != "Head of Security")
|
||||
to_chat(M, "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>")
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/energy/stunrevolver/detective/verb/reskin_gun()
|
||||
set name = "Resprite gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to choose a sprite for your gun."
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["Lawson Arms LAEP20"] = "stunrevolver"
|
||||
options["Lawson Arms LTX1020"] = "vinstunrevolver"
|
||||
options["Lawson Arms LTX1010"] = "snubstun2revolver"
|
||||
options["Lawson Arms LTX1020 (Blued)"] = "bluedstunrevolver"
|
||||
options["Lawson Arms LTX1020 (Stainless)"] = "stainstunrevolver"
|
||||
options["Lawson Arms LTX1020 (Ace)"] = "snubstunrevolver"
|
||||
options["Lawson Arms LTX1020 (Gold)"] = "goldstunrevolver"
|
||||
var/choice = input(M,"Choose your sprite!","Resprite Gun") in options
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
unique_reskin = options[choice]
|
||||
to_chat(M, "Your gun is now sprited as [choice]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/*
|
||||
* Vintage Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver/vintage
|
||||
name = "vintage stun revolver"
|
||||
desc = "An older model stun revolver that is still in service across the frontier."
|
||||
description_fluff = "The LTX1020 \"Bolter\", a Firefly Co. staple from when the company was in its hayday. \
|
||||
While Firefly Co. has sadly been dissmantled due to bankruptcy, their iconic weapons can still be found \
|
||||
across the frontier as anything from collectors items to surplus equipment. The LTX1020 falls under \
|
||||
the latter category. Several companies have been known to use the base tech within the Bolter to create \
|
||||
their own variants of the Stun Revolver."
|
||||
icon_state = "vinstunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
|
||||
|
||||
/*
|
||||
* Snubnose Stun Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/stunrevolver/snubnose
|
||||
name = "snub stun revolver"
|
||||
desc = "A snub nose stun revolver sporting a rather elegant look."
|
||||
description_fluff = "The LTX1010 \"Stubby\", a Firefly Co. staple from when the company was in its hayday. \
|
||||
While Firefly Co. has sadly been dissmantled due to bankruptcy, their iconic weapons can still be found \
|
||||
across the frontier as anything from collectors items to surplus equipment. The LTX1010 falls under \
|
||||
the latter category. Gangsters and other gentlemanly criminals alike use the Stubby as a means of policing \
|
||||
within their ranks. Hard to argue with the boss with 12000 volts shooting through you."
|
||||
icon_state = "snubstunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
w_class = ITEMSIZE_SMALL //small pistol is small
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/obj/item/weapon/gun/energy/temperature
|
||||
name = "temperature gun"
|
||||
icon_state = "freezegun"
|
||||
desc = "A gun that can add or remove heat from entities it hits. In other words, it can fire 'cold', and 'hot' beams."
|
||||
charge_cost = 240
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 2)
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
|
||||
projectile_type = /obj/item/projectile/temp
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="endothermic beam", projectile_type = /obj/item/projectile/temp, charge_cost = 240),
|
||||
list(mode_name="exothermic beam", projectile_type = /obj/item/projectile/temp/hot, charge_cost = 240),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/temperature/mounted
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
/obj/item/weapon/gun/energy/temperature
|
||||
name = "temperature gun"
|
||||
icon_state = "freezegun"
|
||||
desc = "A gun that can add or remove heat from entities it hits. In other words, it can fire 'cold', and 'hot' beams."
|
||||
charge_cost = 240
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 2)
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
|
||||
projectile_type = /obj/item/projectile/temp
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="endothermic beam", projectile_type = /obj/item/projectile/temp, charge_cost = 240),
|
||||
list(mode_name="exothermic beam", projectile_type = /obj/item/projectile/temp/hot, charge_cost = 240),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/temperature/mounted
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
@@ -1,356 +1,356 @@
|
||||
#define HOLD_CASINGS 0 //do not do anything after firing. Manual action, like pump shotguns, or guns that want to define custom behaviour
|
||||
#define EJECT_CASINGS 1 //drop spent casings on the ground after firing
|
||||
#define CYCLE_CASINGS 2 //experimental: cycle casings, like a revolver. Also works for multibarrelled guns
|
||||
|
||||
/obj/item/weapon/gun/projectile
|
||||
name = "gun"
|
||||
desc = "A gun that fires bullets."
|
||||
icon_state = "revolver"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
matter = list(MAT_STEEL = 1000)
|
||||
recoil = 1
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/strong //Only used for chameleon guns
|
||||
|
||||
var/caliber = ".357" //determines which casings will fit
|
||||
var/handle_casings = EJECT_CASINGS //determines how spent casings should be handled
|
||||
var/load_method = SINGLE_CASING|SPEEDLOADER //1 = Single shells, 2 = box or quick loader, 3 = magazine
|
||||
var/obj/item/ammo_casing/chambered = null
|
||||
|
||||
reload_time = 1 //Ballistics reload fast, but not instantly
|
||||
|
||||
//For SINGLE_CASING or SPEEDLOADER guns
|
||||
var/max_shells = 0 //the number of casings that will fit inside
|
||||
var/ammo_type = null //the type of ammo that the gun comes preloaded with
|
||||
var/list/loaded = list() //stored ammo
|
||||
|
||||
//For MAGAZINE guns
|
||||
var/magazine_type = null //the type of magazine that the gun comes preloaded with
|
||||
var/obj/item/ammo_magazine/ammo_magazine = null //stored magazine
|
||||
var/allowed_magazines //determines list of which magazines will fit in the gun
|
||||
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
|
||||
var/auto_eject_sound = null
|
||||
//TODO generalize ammo icon states for guns
|
||||
//var/magazine_states = 0
|
||||
//var/list/icon_keys = list() //keys
|
||||
//var/list/ammo_states = list() //values
|
||||
|
||||
var/random_start_ammo = FALSE //randomize amount of starting ammo
|
||||
|
||||
/obj/item/weapon/gun/projectile/New(loc, var/starts_loaded = 1)
|
||||
..()
|
||||
if(starts_loaded)
|
||||
if(ispath(ammo_type) && (load_method & (SINGLE_CASING|SPEEDLOADER)))
|
||||
for(var/i in 1 to max_shells)
|
||||
loaded += new ammo_type(src)
|
||||
if(random_start_ammo)
|
||||
loaded.Cut(0,rand(0,max_shells))
|
||||
if(ispath(magazine_type) && (load_method & MAGAZINE))
|
||||
ammo_magazine = new magazine_type(src)
|
||||
allowed_magazines += /obj/item/ammo_magazine/smart
|
||||
if(random_start_ammo)
|
||||
var/ammo_cut = rand(0,ammo_magazine.max_ammo)
|
||||
ammo_magazine.contents.Cut(0,ammo_cut)
|
||||
ammo_magazine.stored_ammo.Cut(0,ammo_cut)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/consume_next_projectile()
|
||||
//get the next casing
|
||||
if(loaded.len)
|
||||
chambered = loaded[1] //load next casing.
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
loaded -= chambered
|
||||
else if(ammo_magazine && ammo_magazine.stored_ammo.len)
|
||||
chambered = ammo_magazine.stored_ammo[ammo_magazine.stored_ammo.len]
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
ammo_magazine.stored_ammo -= chambered
|
||||
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src)
|
||||
|
||||
if (chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/handle_post_fire()
|
||||
..()
|
||||
if(chambered)
|
||||
chambered.expend()
|
||||
process_chambered()
|
||||
|
||||
/obj/item/weapon/gun/projectile/handle_click_empty()
|
||||
..()
|
||||
process_chambered()
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/process_chambered()
|
||||
if (!chambered) return
|
||||
|
||||
// Aurora forensics port, gunpowder residue.
|
||||
if(chambered.leaves_residue)
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(istype(H))
|
||||
if(!H.gloves)
|
||||
H.gunshot_residue = chambered.caliber
|
||||
else
|
||||
var/obj/item/clothing/G = H.gloves
|
||||
G.gunshot_residue = chambered.caliber
|
||||
|
||||
switch(handle_casings)
|
||||
if(EJECT_CASINGS) //eject casing onto ground.
|
||||
if(chambered.caseless)
|
||||
qdel(chambered)
|
||||
return
|
||||
else
|
||||
chambered.loc = get_turf(src)
|
||||
playsound(src, "casing", 50, 1)
|
||||
if(CYCLE_CASINGS) //cycle the casing back to the end.
|
||||
if(ammo_magazine)
|
||||
ammo_magazine.stored_ammo += chambered
|
||||
else
|
||||
loaded += chambered
|
||||
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
chambered = null
|
||||
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src)
|
||||
|
||||
|
||||
//Attempts to load A into src, depending on the type of thing being loaded and the load_method
|
||||
//Maybe this should be broken up into separate procs for each load method?
|
||||
/obj/item/weapon/gun/projectile/proc/load_ammo(var/obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
var/obj/item/ammo_magazine/AM = A
|
||||
if(!(load_method & AM.mag_type) || caliber != AM.caliber || allowed_magazines && !is_type_in_list(A, allowed_magazines))
|
||||
to_chat(user, "<span class='warning'>[AM] won't load into [src]!</span>")
|
||||
return
|
||||
switch(AM.mag_type)
|
||||
if(MAGAZINE)
|
||||
if(ammo_magazine)
|
||||
to_chat(user, "<span class='warning'>[src] already has a magazine loaded.</span>") //already a magazine here
|
||||
return
|
||||
if(do_after(user, reload_time * AM.w_class))
|
||||
user.remove_from_mob(AM)
|
||||
AM.loc = src
|
||||
ammo_magazine = AM
|
||||
user.visible_message("[user] inserts [AM] into [src].", "<span class='notice'>You insert [AM] into [src].</span>")
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
playsound(src, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
if(SPEEDLOADER)
|
||||
if(loaded.len >= max_shells)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
var/count = 0
|
||||
for(var/obj/item/ammo_casing/C in AM.stored_ammo)
|
||||
if(loaded.len >= max_shells)
|
||||
break
|
||||
if(C.caliber == caliber)
|
||||
C.loc = src
|
||||
loaded += C
|
||||
AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way...
|
||||
count++
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
if(do_after(user, reload_time * AM.w_class))
|
||||
if(count)
|
||||
user.visible_message("[user] reloads [src].", "<span class='notice'>You load [count] round\s into [src].</span>")
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
AM.update_icon()
|
||||
else if(istype(A, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = A
|
||||
if(!(load_method & SINGLE_CASING) || caliber != C.caliber)
|
||||
return //incompatible
|
||||
if(loaded.len >= max_shells)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
|
||||
if(do_after(user, reload_time * C.w_class))
|
||||
user.remove_from_mob(C)
|
||||
C.loc = src
|
||||
loaded.Insert(1, C) //add to the head of the list
|
||||
user.visible_message("[user] inserts \a [C] into [src].", "<span class='notice'>You insert \a [C] into [src].</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
|
||||
else if(istype(A, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/storage = A
|
||||
if(!(load_method & SINGLE_CASING))
|
||||
return //incompatible
|
||||
|
||||
to_chat(user, "<span class='notice'>You start loading \the [src].</span>")
|
||||
sleep(1 SECOND)
|
||||
for(var/obj/item/ammo_casing/ammo in storage.contents)
|
||||
if(caliber != ammo.caliber)
|
||||
continue
|
||||
|
||||
load_ammo(ammo, user)
|
||||
|
||||
if(loaded.len >= max_shells)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
break
|
||||
sleep(1 SECOND)
|
||||
|
||||
update_icon()
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
|
||||
//attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled
|
||||
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1)
|
||||
if(ammo_magazine)
|
||||
user.put_in_hands(ammo_magazine)
|
||||
user.visible_message("[user] removes [ammo_magazine] from [src].", "<span class='notice'>You remove [ammo_magazine] from [src].</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
else if(loaded.len)
|
||||
//presumably, if it can be speed-loaded, it can be speed-unloaded.
|
||||
if(allow_dump && (load_method & SPEEDLOADER))
|
||||
var/count = 0
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
for(var/obj/item/ammo_casing/C in loaded)
|
||||
C.loc = T
|
||||
count++
|
||||
loaded.Cut()
|
||||
if(count)
|
||||
user.visible_message("[user] unloads [src].", "<span class='notice'>You unload [count] round\s from [src].</span>")
|
||||
else if(load_method & SINGLE_CASING)
|
||||
var/obj/item/ammo_casing/C = loaded[loaded.len]
|
||||
loaded.len--
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is empty.</span>")
|
||||
update_icon()
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
..()
|
||||
load_ammo(A, user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
|
||||
if(firemodes.len > 1)
|
||||
switch_firemodes(user)
|
||||
else
|
||||
unload_ammo(user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob)
|
||||
if(user.get_inactive_hand() == src)
|
||||
unload_ammo(user, allow_dump=0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user)
|
||||
..()
|
||||
if(auto_eject && ammo_magazine && ammo_magazine.stored_ammo && !ammo_magazine.stored_ammo.len)
|
||||
ammo_magazine.loc = get_turf(src.loc)
|
||||
user.visible_message(
|
||||
"[ammo_magazine] falls out and clatters on the floor!",
|
||||
"<span class='notice'>[ammo_magazine] falls out and clatters on the floor!</span>"
|
||||
)
|
||||
if(auto_eject_sound)
|
||||
playsound(src, auto_eject_sound, 40, 1)
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
update_icon() //make sure to do this after unsetting ammo_magazine
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
|
||||
/obj/item/weapon/gun/projectile/examine(mob/user)
|
||||
. = ..()
|
||||
if(ammo_magazine)
|
||||
. += "It has \a [ammo_magazine] loaded."
|
||||
. += "It has [getAmmo()] round\s remaining."
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/getAmmo()
|
||||
var/bullets = 0
|
||||
if(loaded)
|
||||
bullets += loaded.len
|
||||
if(ammo_magazine && ammo_magazine.stored_ammo)
|
||||
bullets += ammo_magazine.stored_ammo.len
|
||||
if(chambered)
|
||||
bullets += 1
|
||||
return bullets
|
||||
|
||||
/* Unneeded -- so far.
|
||||
//in case the weapon has firemodes and can't unload using attack_hand()
|
||||
/obj/item/weapon/gun/projectile/verb/unload_gun()
|
||||
set name = "Unload Ammo"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.stat || usr.restrained()) return
|
||||
|
||||
unload_ammo(usr)
|
||||
*/
|
||||
|
||||
// TGMC Ammo HUD Insertion
|
||||
/obj/item/weapon/gun/projectile/has_ammo_counter()
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/gun/projectile/get_ammo_type()
|
||||
if(load_method & MAGAZINE)
|
||||
if(chambered) // Do we have an ammo casing chambered
|
||||
var/obj/item/ammo_casing/A = chambered
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else if(ammo_magazine && ammo_magazine.stored_ammo.len) // Do we have a mag, and have ammo in the mag, but nothing chambered?
|
||||
var/obj/item/ammo_casing/A = ammo_magazine.stored_ammo[1]
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else if(src.projectile_type) // Else, we're entirely empty, and irregardless of the mag we have loaded (as it's empty, or it would've passed the length check above), return the DEFAULT projectile_type on the gun, if set.
|
||||
var/obj/item/projectile/P = src.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else
|
||||
return list("unknown", "unknown") // Safety, this shouldn't happen, but just in case
|
||||
else if(load_method & (SINGLE_CASING|SPEEDLOADER)) // Do we load with single casings OR speedloaders?
|
||||
if(chambered) // Do we have an ammo casing loaded in the chamber? All casings still have a projectile_type var.
|
||||
var/obj/item/ammo_casing/A = chambered
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty)) // Return the casing's projectile_type ammo hud state
|
||||
else if(loaded.len) // Else, is the gun loaded, but no ammo casings in chamber currently?
|
||||
var/obj/item/ammo_casing/A = loaded[1]
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty)) // Return the ammunition loaded in the gun's hud_state
|
||||
else if(src.projectile_type) // Else, we're entirely empty, and have nothing loaded in the gun, and nothing in the chamber. Return the DEFAULT projectile_type on the gun, if set.
|
||||
var/obj/item/projectile/P = src.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else
|
||||
return list("unknown", "unknown") // Safety, this shouldn't happen, but just in case
|
||||
else if(src.projectile_type) // Failsafe if we somehow don't pass the above. Return the DEFAULT projectile_type on the gun, if set.
|
||||
var/obj/item/projectile/P = src.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else // Failsafe if we somehow fail all three methods
|
||||
return list("unknown", "unknown")
|
||||
|
||||
/obj/item/weapon/gun/projectile/get_ammo_count()
|
||||
if(ammo_magazine) // Do we have a magazine loaded?
|
||||
var/shots_left
|
||||
if(chambered && chambered.BB) // Do we have a bullet in the currently-chambered casing, if any?
|
||||
shots_left++
|
||||
for(var/obj/item/ammo_casing/bullet in ammo_magazine.stored_ammo)
|
||||
if(bullet.BB)
|
||||
shots_left++
|
||||
|
||||
if(shots_left > 0)
|
||||
return shots_left
|
||||
else
|
||||
return 0 // No ammo left or failsafe.
|
||||
else if(loaded) // Do we use internal ammunition
|
||||
var/shots_left
|
||||
if(chambered && chambered.BB) // Do we have a bullet in the currently-chambered casing, if any?
|
||||
shots_left++
|
||||
for(var/obj/item/ammo_casing/bullet in loaded)
|
||||
if(bullet.BB) // Only increment how many shots we have left if we're loaded.
|
||||
shots_left++
|
||||
|
||||
if(shots_left > 0)
|
||||
return shots_left
|
||||
else
|
||||
return 0 // No ammo left or failsafe.
|
||||
else if(chambered) // If we don't have a magazine or internal ammunition loaded, but we have a casing in chamber, return the amount.
|
||||
return chambered.BB ? 1 : 0
|
||||
else // Failsafe, or completely unloaded
|
||||
return 0
|
||||
#define HOLD_CASINGS 0 //do not do anything after firing. Manual action, like pump shotguns, or guns that want to define custom behaviour
|
||||
#define EJECT_CASINGS 1 //drop spent casings on the ground after firing
|
||||
#define CYCLE_CASINGS 2 //experimental: cycle casings, like a revolver. Also works for multibarrelled guns
|
||||
|
||||
/obj/item/weapon/gun/projectile
|
||||
name = "gun"
|
||||
desc = "A gun that fires bullets."
|
||||
icon_state = "revolver"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
matter = list(MAT_STEEL = 1000)
|
||||
recoil = 1
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/strong //Only used for chameleon guns
|
||||
|
||||
var/caliber = ".357" //determines which casings will fit
|
||||
var/handle_casings = EJECT_CASINGS //determines how spent casings should be handled
|
||||
var/load_method = SINGLE_CASING|SPEEDLOADER //1 = Single shells, 2 = box or quick loader, 3 = magazine
|
||||
var/obj/item/ammo_casing/chambered = null
|
||||
|
||||
reload_time = 1 //Ballistics reload fast, but not instantly
|
||||
|
||||
//For SINGLE_CASING or SPEEDLOADER guns
|
||||
var/max_shells = 0 //the number of casings that will fit inside
|
||||
var/ammo_type = null //the type of ammo that the gun comes preloaded with
|
||||
var/list/loaded = list() //stored ammo
|
||||
|
||||
//For MAGAZINE guns
|
||||
var/magazine_type = null //the type of magazine that the gun comes preloaded with
|
||||
var/obj/item/ammo_magazine/ammo_magazine = null //stored magazine
|
||||
var/allowed_magazines //determines list of which magazines will fit in the gun
|
||||
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
|
||||
var/auto_eject_sound = null
|
||||
//TODO generalize ammo icon states for guns
|
||||
//var/magazine_states = 0
|
||||
//var/list/icon_keys = list() //keys
|
||||
//var/list/ammo_states = list() //values
|
||||
|
||||
var/random_start_ammo = FALSE //randomize amount of starting ammo
|
||||
|
||||
/obj/item/weapon/gun/projectile/New(loc, var/starts_loaded = 1)
|
||||
..()
|
||||
if(starts_loaded)
|
||||
if(ispath(ammo_type) && (load_method & (SINGLE_CASING|SPEEDLOADER)))
|
||||
for(var/i in 1 to max_shells)
|
||||
loaded += new ammo_type(src)
|
||||
if(random_start_ammo)
|
||||
loaded.Cut(0,rand(0,max_shells))
|
||||
if(ispath(magazine_type) && (load_method & MAGAZINE))
|
||||
ammo_magazine = new magazine_type(src)
|
||||
allowed_magazines += /obj/item/ammo_magazine/smart
|
||||
if(random_start_ammo)
|
||||
var/ammo_cut = rand(0,ammo_magazine.max_ammo)
|
||||
ammo_magazine.contents.Cut(0,ammo_cut)
|
||||
ammo_magazine.stored_ammo.Cut(0,ammo_cut)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/consume_next_projectile()
|
||||
//get the next casing
|
||||
if(loaded.len)
|
||||
chambered = loaded[1] //load next casing.
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
loaded -= chambered
|
||||
else if(ammo_magazine && ammo_magazine.stored_ammo.len)
|
||||
chambered = ammo_magazine.stored_ammo[ammo_magazine.stored_ammo.len]
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
ammo_magazine.stored_ammo -= chambered
|
||||
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src)
|
||||
|
||||
if (chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/handle_post_fire()
|
||||
..()
|
||||
if(chambered)
|
||||
chambered.expend()
|
||||
process_chambered()
|
||||
|
||||
/obj/item/weapon/gun/projectile/handle_click_empty()
|
||||
..()
|
||||
process_chambered()
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/process_chambered()
|
||||
if (!chambered) return
|
||||
|
||||
// Aurora forensics port, gunpowder residue.
|
||||
if(chambered.leaves_residue)
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(istype(H))
|
||||
if(!H.gloves)
|
||||
H.gunshot_residue = chambered.caliber
|
||||
else
|
||||
var/obj/item/clothing/G = H.gloves
|
||||
G.gunshot_residue = chambered.caliber
|
||||
|
||||
switch(handle_casings)
|
||||
if(EJECT_CASINGS) //eject casing onto ground.
|
||||
if(chambered.caseless)
|
||||
qdel(chambered)
|
||||
return
|
||||
else
|
||||
chambered.loc = get_turf(src)
|
||||
playsound(src, "casing", 50, 1)
|
||||
if(CYCLE_CASINGS) //cycle the casing back to the end.
|
||||
if(ammo_magazine)
|
||||
ammo_magazine.stored_ammo += chambered
|
||||
else
|
||||
loaded += chambered
|
||||
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
chambered = null
|
||||
|
||||
var/mob/living/M = loc // TGMC Ammo HUD
|
||||
if(istype(M)) // TGMC Ammo HUD
|
||||
M?.hud_used.update_ammo_hud(M, src)
|
||||
|
||||
|
||||
//Attempts to load A into src, depending on the type of thing being loaded and the load_method
|
||||
//Maybe this should be broken up into separate procs for each load method?
|
||||
/obj/item/weapon/gun/projectile/proc/load_ammo(var/obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
var/obj/item/ammo_magazine/AM = A
|
||||
if(!(load_method & AM.mag_type) || caliber != AM.caliber || allowed_magazines && !is_type_in_list(A, allowed_magazines))
|
||||
to_chat(user, "<span class='warning'>[AM] won't load into [src]!</span>")
|
||||
return
|
||||
switch(AM.mag_type)
|
||||
if(MAGAZINE)
|
||||
if(ammo_magazine)
|
||||
to_chat(user, "<span class='warning'>[src] already has a magazine loaded.</span>") //already a magazine here
|
||||
return
|
||||
if(do_after(user, reload_time * AM.w_class))
|
||||
user.remove_from_mob(AM)
|
||||
AM.loc = src
|
||||
ammo_magazine = AM
|
||||
user.visible_message("[user] inserts [AM] into [src].", "<span class='notice'>You insert [AM] into [src].</span>")
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
playsound(src, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
if(SPEEDLOADER)
|
||||
if(loaded.len >= max_shells)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
var/count = 0
|
||||
for(var/obj/item/ammo_casing/C in AM.stored_ammo)
|
||||
if(loaded.len >= max_shells)
|
||||
break
|
||||
if(C.caliber == caliber)
|
||||
C.loc = src
|
||||
loaded += C
|
||||
AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way...
|
||||
count++
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
if(do_after(user, reload_time * AM.w_class))
|
||||
if(count)
|
||||
user.visible_message("[user] reloads [src].", "<span class='notice'>You load [count] round\s into [src].</span>")
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
AM.update_icon()
|
||||
else if(istype(A, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = A
|
||||
if(!(load_method & SINGLE_CASING) || caliber != C.caliber)
|
||||
return //incompatible
|
||||
if(loaded.len >= max_shells)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
|
||||
if(do_after(user, reload_time * C.w_class))
|
||||
user.remove_from_mob(C)
|
||||
C.loc = src
|
||||
loaded.Insert(1, C) //add to the head of the list
|
||||
user.visible_message("[user] inserts \a [C] into [src].", "<span class='notice'>You insert \a [C] into [src].</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
|
||||
else if(istype(A, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/storage = A
|
||||
if(!(load_method & SINGLE_CASING))
|
||||
return //incompatible
|
||||
|
||||
to_chat(user, "<span class='notice'>You start loading \the [src].</span>")
|
||||
sleep(1 SECOND)
|
||||
for(var/obj/item/ammo_casing/ammo in storage.contents)
|
||||
if(caliber != ammo.caliber)
|
||||
continue
|
||||
|
||||
load_ammo(ammo, user)
|
||||
|
||||
if(loaded.len >= max_shells)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
break
|
||||
sleep(1 SECOND)
|
||||
|
||||
update_icon()
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
|
||||
//attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled
|
||||
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1)
|
||||
if(ammo_magazine)
|
||||
user.put_in_hands(ammo_magazine)
|
||||
user.visible_message("[user] removes [ammo_magazine] from [src].", "<span class='notice'>You remove [ammo_magazine] from [src].</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
else if(loaded.len)
|
||||
//presumably, if it can be speed-loaded, it can be speed-unloaded.
|
||||
if(allow_dump && (load_method & SPEEDLOADER))
|
||||
var/count = 0
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
for(var/obj/item/ammo_casing/C in loaded)
|
||||
C.loc = T
|
||||
count++
|
||||
loaded.Cut()
|
||||
if(count)
|
||||
user.visible_message("[user] unloads [src].", "<span class='notice'>You unload [count] round\s from [src].</span>")
|
||||
else if(load_method & SINGLE_CASING)
|
||||
var/obj/item/ammo_casing/C = loaded[loaded.len]
|
||||
loaded.len--
|
||||
user.put_in_hands(C)
|
||||
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is empty.</span>")
|
||||
update_icon()
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
..()
|
||||
load_ammo(A, user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
|
||||
if(firemodes.len > 1)
|
||||
switch_firemodes(user)
|
||||
else
|
||||
unload_ammo(user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob)
|
||||
if(user.get_inactive_hand() == src)
|
||||
unload_ammo(user, allow_dump=0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user)
|
||||
..()
|
||||
if(auto_eject && ammo_magazine && ammo_magazine.stored_ammo && !ammo_magazine.stored_ammo.len)
|
||||
ammo_magazine.loc = get_turf(src.loc)
|
||||
user.visible_message(
|
||||
"[ammo_magazine] falls out and clatters on the floor!",
|
||||
"<span class='notice'>[ammo_magazine] falls out and clatters on the floor!</span>"
|
||||
)
|
||||
if(auto_eject_sound)
|
||||
playsound(src, auto_eject_sound, 40, 1)
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
update_icon() //make sure to do this after unsetting ammo_magazine
|
||||
user.hud_used.update_ammo_hud(user, src)
|
||||
|
||||
/obj/item/weapon/gun/projectile/examine(mob/user)
|
||||
. = ..()
|
||||
if(ammo_magazine)
|
||||
. += "It has \a [ammo_magazine] loaded."
|
||||
. += "It has [getAmmo()] round\s remaining."
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/getAmmo()
|
||||
var/bullets = 0
|
||||
if(loaded)
|
||||
bullets += loaded.len
|
||||
if(ammo_magazine && ammo_magazine.stored_ammo)
|
||||
bullets += ammo_magazine.stored_ammo.len
|
||||
if(chambered)
|
||||
bullets += 1
|
||||
return bullets
|
||||
|
||||
/* Unneeded -- so far.
|
||||
//in case the weapon has firemodes and can't unload using attack_hand()
|
||||
/obj/item/weapon/gun/projectile/verb/unload_gun()
|
||||
set name = "Unload Ammo"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.stat || usr.restrained()) return
|
||||
|
||||
unload_ammo(usr)
|
||||
*/
|
||||
|
||||
// TGMC Ammo HUD Insertion
|
||||
/obj/item/weapon/gun/projectile/has_ammo_counter()
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/gun/projectile/get_ammo_type()
|
||||
if(load_method & MAGAZINE)
|
||||
if(chambered) // Do we have an ammo casing chambered
|
||||
var/obj/item/ammo_casing/A = chambered
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else if(ammo_magazine && ammo_magazine.stored_ammo.len) // Do we have a mag, and have ammo in the mag, but nothing chambered?
|
||||
var/obj/item/ammo_casing/A = ammo_magazine.stored_ammo[1]
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else if(src.projectile_type) // Else, we're entirely empty, and irregardless of the mag we have loaded (as it's empty, or it would've passed the length check above), return the DEFAULT projectile_type on the gun, if set.
|
||||
var/obj/item/projectile/P = src.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else
|
||||
return list("unknown", "unknown") // Safety, this shouldn't happen, but just in case
|
||||
else if(load_method & (SINGLE_CASING|SPEEDLOADER)) // Do we load with single casings OR speedloaders?
|
||||
if(chambered) // Do we have an ammo casing loaded in the chamber? All casings still have a projectile_type var.
|
||||
var/obj/item/ammo_casing/A = chambered
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty)) // Return the casing's projectile_type ammo hud state
|
||||
else if(loaded.len) // Else, is the gun loaded, but no ammo casings in chamber currently?
|
||||
var/obj/item/ammo_casing/A = loaded[1]
|
||||
var/obj/item/projectile/P = A.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty)) // Return the ammunition loaded in the gun's hud_state
|
||||
else if(src.projectile_type) // Else, we're entirely empty, and have nothing loaded in the gun, and nothing in the chamber. Return the DEFAULT projectile_type on the gun, if set.
|
||||
var/obj/item/projectile/P = src.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else
|
||||
return list("unknown", "unknown") // Safety, this shouldn't happen, but just in case
|
||||
else if(src.projectile_type) // Failsafe if we somehow don't pass the above. Return the DEFAULT projectile_type on the gun, if set.
|
||||
var/obj/item/projectile/P = src.projectile_type
|
||||
return list(initial(P.hud_state), initial(P.hud_state_empty))
|
||||
else // Failsafe if we somehow fail all three methods
|
||||
return list("unknown", "unknown")
|
||||
|
||||
/obj/item/weapon/gun/projectile/get_ammo_count()
|
||||
if(ammo_magazine) // Do we have a magazine loaded?
|
||||
var/shots_left
|
||||
if(chambered && chambered.BB) // Do we have a bullet in the currently-chambered casing, if any?
|
||||
shots_left++
|
||||
for(var/obj/item/ammo_casing/bullet in ammo_magazine.stored_ammo)
|
||||
if(bullet.BB)
|
||||
shots_left++
|
||||
|
||||
if(shots_left > 0)
|
||||
return shots_left
|
||||
else
|
||||
return 0 // No ammo left or failsafe.
|
||||
else if(loaded) // Do we use internal ammunition
|
||||
var/shots_left
|
||||
if(chambered && chambered.BB) // Do we have a bullet in the currently-chambered casing, if any?
|
||||
shots_left++
|
||||
for(var/obj/item/ammo_casing/bullet in loaded)
|
||||
if(bullet.BB) // Only increment how many shots we have left if we're loaded.
|
||||
shots_left++
|
||||
|
||||
if(shots_left > 0)
|
||||
return shots_left
|
||||
else
|
||||
return 0 // No ammo left or failsafe.
|
||||
else if(chambered) // If we don't have a magazine or internal ammunition loaded, but we have a casing in chamber, return the amount.
|
||||
return chambered.BB ? 1 : 0
|
||||
else // Failsafe, or completely unloaded
|
||||
return 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,351 +1,351 @@
|
||||
/*
|
||||
* Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver
|
||||
name = "revolver"
|
||||
desc = "The MarsTech HE Colt is a choice revolver for when you absolutely, positively need to put a hole in the other guy. Uses .357 rounds."
|
||||
description_fluff = "MarsTech first made their name in the Second Cold War as the 'Lunar Arms Company' providing home-grown arms to the Selene Federation, \
|
||||
but after the formation of the SCG rebranded and relocated to Mars where they remain based to this day. \
|
||||
The company was acquired by Hephaestus in the mid 23rd century, and its branding used to present an image of historical prestige and Solar unity for their latest product line. \
|
||||
MarsTech operates production facilities out of many of the SCG’s larger colonies."
|
||||
icon_state = "revolver"
|
||||
item_state = "revolver"
|
||||
caliber = ".357"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
max_shells = 6
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/strong
|
||||
var/chamber_offset = 0 //how many empty chambers in the cylinder until you hit a round
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/verb/spin_cylinder()
|
||||
set name = "Spin cylinder"
|
||||
set desc = "Fun when you're bored out of your skull."
|
||||
set category = "Object"
|
||||
|
||||
chamber_offset = 0
|
||||
visible_message("<span class='warning'>\The [usr] spins the cylinder of \the [src]!</span>", \
|
||||
"<span class='notice'>You hear something metallic spin and click.</span>")
|
||||
playsound(src, 'sound/weapons/revolver_spin.ogg', 100, 1)
|
||||
loaded = shuffle(loaded)
|
||||
if(rand(1,max_shells) > loaded.len)
|
||||
chamber_offset = rand(0,max_shells - loaded.len)
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/consume_next_projectile()
|
||||
if(chamber_offset)
|
||||
chamber_offset--
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/load_ammo(var/obj/item/A, mob/user)
|
||||
chamber_offset = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/stainless
|
||||
icon_state = "revolver_stainless"
|
||||
|
||||
/*
|
||||
* Detective Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/detective
|
||||
name = "revolver"
|
||||
desc = "A standard MarsTech R1 snubnose revolver, popular among some law enforcement agencies for its simple, long-lasting construction. Uses .38-Special rounds."
|
||||
description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, MarsTech has been the provider of choice for law enforcement and security forces for over 300 years."
|
||||
icon_state = "detective"
|
||||
caliber = ".38"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a38
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to rename your gun. If you're the detective."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
if(!M.mind.assigned_role == "Detective")
|
||||
to_chat(M, "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>")
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input(usr, "What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective45
|
||||
name = ".45 revolver"
|
||||
desc = "A basic revolver, popular among some law enforcement agencies for its simple, long-lasting construction, modified for .45 rounds and a seven-shot cylinder."
|
||||
icon_state = "detective"
|
||||
caliber = ".45"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a45/rubber
|
||||
max_shells = 6
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Rename your gun. If you're the Detective."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
var/job = M.mind.assigned_role
|
||||
if(job != "Detective")
|
||||
to_chat(M, "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>")
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input(usr, "What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective45/verb/reskin_gun()
|
||||
set name = "Resprite gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to choose a sprite for your gun."
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["MarsTech R1 Snubnose"] = "detective"
|
||||
options["MarsTech R1 Snubnose (Blued)"] = "detective_blued"
|
||||
options["MarsTech R1 Snubnose (Stainless)"] = "detective_stainless"
|
||||
options["MarsTech R1 Snubnose (Gold)"] = "detective_stainless"
|
||||
options["MarsTech R1 Snubnose (Leopard)"] = "detective_leopard"
|
||||
options["MarsTech Frontiersman Classic"] = "detective_peacemaker"
|
||||
options["MarsTech Frontiersman Shadow"] = "detective_peacemaker_dark"
|
||||
options["Jindal Duke"] = "detective_fitz"
|
||||
options["H-H M1895"] = "nagant"
|
||||
var/choice = tgui_input_list(M,"Choose your sprite!","Resprite Gun", options)
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
to_chat(M, "Your gun is now sprited as [choice]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/*
|
||||
* Lombardi Revolvers
|
||||
* Use to be detective revolvers until seperated
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/lombardi
|
||||
name = "Lombardi Buzzard"
|
||||
desc = "A rugged revolver that is mostly used by small law enforcement agencies across the frontier as a cheap, reliable sidearm. Uses .357 rounds."
|
||||
icon_state = "lombardi_police"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lombardi/panther
|
||||
name = "Lombardi Panther"
|
||||
icon_state = "lombardi_panther"
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lombardi/gold
|
||||
name = "Lombardi Deluxe 2502"
|
||||
desc = "A sweet looking revolver that is decorated with false gold and silver plating. Favored among by gamblers and criminals alike. Uses .357 rounds."
|
||||
icon_state = "lombardi_gold"
|
||||
|
||||
/*
|
||||
* Captain's Peacekeeper
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/cappeacekeeper
|
||||
name = "decorated peacekeeper"
|
||||
desc = "A MarsTech Frontiersman revolver that has been heavily modified. It has been decorated for personal use by command officers. Uses .44 rounds."
|
||||
description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, \
|
||||
MarsTech has been the provider of choice for law enforcement and security forces for over 300 years."
|
||||
icon_state = "captains_peacemaker"
|
||||
caliber = ".44"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a44
|
||||
|
||||
/*
|
||||
* Mateba
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/mateba
|
||||
name = "mateba"
|
||||
desc = "This unique looking handgun is named after an Italian company famous for the original manufacture of \
|
||||
these revolvers, and pasta kneading machines. Uses .357 rounds." // Yes I'm serious. -Spades
|
||||
icon_state = "mateba"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
|
||||
/*
|
||||
* Deckard (Blade Runner)
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard
|
||||
name = "\improper \"Deckard\" .38"
|
||||
desc = "A custom-built revolver, based off the semi-popular Detective Special model. Uses .38-Special rounds."
|
||||
icon_state = "deckard-empty"
|
||||
caliber = ".38"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a38
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard/emp
|
||||
ammo_type = /obj/item/ammo_casing/a38/emp
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard/update_icon()
|
||||
..()
|
||||
if(loaded.len)
|
||||
icon_state = "deckard-loaded"
|
||||
else
|
||||
icon_state = "deckard-empty"
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard/load_ammo(var/obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
flick("deckard-reload",src)
|
||||
..()
|
||||
|
||||
/*
|
||||
* Judge
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/judge
|
||||
name = "\"The Judge\""
|
||||
desc = "A revolving hand-shotgun by Jindal Arms that packs the power of a 12 guage in the palm of your hand (if you don't break your wrist). Uses 12g rounds."
|
||||
description_fluff = "While wholly owned by Hephaestus Industries, the Jindal Arms brand does not appear \
|
||||
prominently in most company catalogues (Perhaps owing to its less than prestigious image), \
|
||||
instead being sold almost exclusively through retailers and advertising platforms targeting the \
|
||||
'independent roughneck' demographic."
|
||||
icon_state = "judge"
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 4)
|
||||
max_shells = 5
|
||||
recoil = 2 // ow my fucking hand
|
||||
accuracy = -15 // smooth bore + short barrel = shit accuracy
|
||||
ammo_type = /obj/item/ammo_casing/a12g
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun
|
||||
// ToDo: Remove accuracy debuf in exchange for slightly injuring your hand every time you fire it.
|
||||
|
||||
/*
|
||||
* Mako
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat
|
||||
name = "Mako revolver"
|
||||
desc = "The Bishamonten P100 Mako is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead. A rare yet deadly collector's item. Uses .38-Special and 12g rounds depending on the barrel."
|
||||
description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \
|
||||
Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \
|
||||
Bishamonten weapons tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons, and used very standard firing mechanisms - \
|
||||
the Mako was a notable exception, so original examples are much sought after."
|
||||
icon_state = "combatrevolver"
|
||||
item_state = "revolver"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
max_shells = 9
|
||||
caliber = ".38"
|
||||
ammo_type = /obj/item/ammo_casing/a38
|
||||
projectile_type = /obj/item/projectile/bullet/pistol
|
||||
var/secondary_max_shells = 1
|
||||
var/secondary_caliber = "12g"
|
||||
var/secondary_ammo_type = /obj/item/ammo_casing/a12g
|
||||
var/flipped_firing = 0
|
||||
var/list/secondary_loaded = list()
|
||||
var/list/tertiary_loaded = list()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/New()
|
||||
for(var/i in 1 to secondary_max_shells)
|
||||
secondary_loaded += new secondary_ammo_type(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/verb/swap_firingmode()
|
||||
set name = "Swap Firing Mode"
|
||||
set category = "Object"
|
||||
set desc = "Click to swap from one method of firing to another."
|
||||
|
||||
var/mob/living/carbon/human/M = usr
|
||||
if(!M.mind)
|
||||
return 0
|
||||
|
||||
to_chat(M, "<span class='notice'>You change the firing mode on \the [src].</span>")
|
||||
if(!flipped_firing)
|
||||
if(max_shells && secondary_max_shells)
|
||||
max_shells = secondary_max_shells
|
||||
|
||||
if(caliber && secondary_caliber)
|
||||
caliber = secondary_caliber
|
||||
|
||||
if(ammo_type && secondary_ammo_type)
|
||||
ammo_type = secondary_ammo_type
|
||||
|
||||
if(secondary_loaded)
|
||||
tertiary_loaded = loaded.Copy()
|
||||
loaded = secondary_loaded
|
||||
|
||||
flipped_firing = 1
|
||||
|
||||
else
|
||||
if(max_shells)
|
||||
max_shells = initial(max_shells)
|
||||
|
||||
if(caliber && secondary_caliber)
|
||||
caliber = initial(caliber)
|
||||
|
||||
if(ammo_type && secondary_ammo_type)
|
||||
ammo_type = initial(ammo_type)
|
||||
|
||||
if(tertiary_loaded)
|
||||
secondary_loaded = loaded.Copy()
|
||||
loaded = tertiary_loaded
|
||||
|
||||
flipped_firing = 0
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/spin_cylinder()
|
||||
set name = "Spin cylinder"
|
||||
set desc = "Fun when you're bored out of your skull."
|
||||
set category = "Object"
|
||||
|
||||
chamber_offset = 0
|
||||
visible_message("<span class='warning'>\The [usr] spins the cylinder of \the [src]!</span>", \
|
||||
"<span class='notice'>You hear something metallic spin and click.</span>")
|
||||
playsound(src, 'sound/weapons/revolver_spin.ogg', 100, 1)
|
||||
if(!flipped_firing)
|
||||
loaded = shuffle(loaded)
|
||||
if(rand(1,max_shells) > loaded.len)
|
||||
chamber_offset = rand(0,max_shells - loaded.len)
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/examine(mob/user)
|
||||
. = ..()
|
||||
if(secondary_loaded)
|
||||
var/to_print
|
||||
for(var/round in secondary_loaded)
|
||||
to_print += round
|
||||
. += "It has a secondary barrel loaded with \a [to_print]"
|
||||
else
|
||||
. += "It has a secondary barrel that is empty."
|
||||
|
||||
|
||||
/*
|
||||
* Webley (Bay Port)
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/webley
|
||||
name = "patrol revolver"
|
||||
desc = "A rugged top break revolver commonly issued to planetary law enforcement offices. Uses .44 magnum rounds."
|
||||
description_fluff = "The Heberg-Hammarstrom Althing is a simple, head-wearing revolver made with an anti-corrosive alloy. \
|
||||
The Althing is advertised as being 'able to survive six months on the bottom of a frozen river and emerge full ready to \
|
||||
save a life'. Issued as standard sidearms to SifGuard frontier patrol."
|
||||
icon_state = "webley2"
|
||||
item_state = "webley2"
|
||||
caliber = ".44"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
ammo_type = /obj/item/ammo_casing/a44
|
||||
|
||||
/*
|
||||
* Webley (Eris Port)
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/consul
|
||||
name = "\improper \"Consul\" Revolver"
|
||||
desc = "Are you feeling lucky, punk? Uses .44 rounds."
|
||||
icon_state = "inspector"
|
||||
item_state = "revolver"
|
||||
caliber = ".44"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
ammo_type = /obj/item/ammo_casing/a44/rubber
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/consul/proc/update_charge()
|
||||
cut_overlays()
|
||||
if(loaded.len==0)
|
||||
add_overlay("inspector_off")
|
||||
else
|
||||
add_overlay("inspector_on")
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/consul/update_icon()
|
||||
update_charge()
|
||||
/*
|
||||
* Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver
|
||||
name = "revolver"
|
||||
desc = "The MarsTech HE Colt is a choice revolver for when you absolutely, positively need to put a hole in the other guy. Uses .357 rounds."
|
||||
description_fluff = "MarsTech first made their name in the Second Cold War as the 'Lunar Arms Company' providing home-grown arms to the Selene Federation, \
|
||||
but after the formation of the SCG rebranded and relocated to Mars where they remain based to this day. \
|
||||
The company was acquired by Hephaestus in the mid 23rd century, and its branding used to present an image of historical prestige and Solar unity for their latest product line. \
|
||||
MarsTech operates production facilities out of many of the SCG’s larger colonies."
|
||||
icon_state = "revolver"
|
||||
item_state = "revolver"
|
||||
caliber = ".357"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
max_shells = 6
|
||||
ammo_type = /obj/item/ammo_casing/a357
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/strong
|
||||
var/chamber_offset = 0 //how many empty chambers in the cylinder until you hit a round
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/verb/spin_cylinder()
|
||||
set name = "Spin cylinder"
|
||||
set desc = "Fun when you're bored out of your skull."
|
||||
set category = "Object"
|
||||
|
||||
chamber_offset = 0
|
||||
visible_message("<span class='warning'>\The [usr] spins the cylinder of \the [src]!</span>", \
|
||||
"<span class='notice'>You hear something metallic spin and click.</span>")
|
||||
playsound(src, 'sound/weapons/revolver_spin.ogg', 100, 1)
|
||||
loaded = shuffle(loaded)
|
||||
if(rand(1,max_shells) > loaded.len)
|
||||
chamber_offset = rand(0,max_shells - loaded.len)
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/consume_next_projectile()
|
||||
if(chamber_offset)
|
||||
chamber_offset--
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/load_ammo(var/obj/item/A, mob/user)
|
||||
chamber_offset = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/stainless
|
||||
icon_state = "revolver_stainless"
|
||||
|
||||
/*
|
||||
* Detective Revolver
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/detective
|
||||
name = "revolver"
|
||||
desc = "A standard MarsTech R1 snubnose revolver, popular among some law enforcement agencies for its simple, long-lasting construction. Uses .38-Special rounds."
|
||||
description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, MarsTech has been the provider of choice for law enforcement and security forces for over 300 years."
|
||||
icon_state = "detective"
|
||||
caliber = ".38"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a38
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to rename your gun. If you're the detective."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
if(!M.mind.assigned_role == "Detective")
|
||||
to_chat(M, "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>")
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input(usr, "What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective45
|
||||
name = ".45 revolver"
|
||||
desc = "A basic revolver, popular among some law enforcement agencies for its simple, long-lasting construction, modified for .45 rounds and a seven-shot cylinder."
|
||||
icon_state = "detective"
|
||||
caliber = ".45"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a45/rubber
|
||||
max_shells = 6
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Rename your gun. If you're the Detective."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
var/job = M.mind.assigned_role
|
||||
if(job != "Detective")
|
||||
to_chat(M, "<span class='notice'>You don't feel cool enough to name this gun, chump.</span>")
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input(usr, "What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/detective45/verb/reskin_gun()
|
||||
set name = "Resprite gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to choose a sprite for your gun."
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["MarsTech R1 Snubnose"] = "detective"
|
||||
options["MarsTech R1 Snubnose (Blued)"] = "detective_blued"
|
||||
options["MarsTech R1 Snubnose (Stainless)"] = "detective_stainless"
|
||||
options["MarsTech R1 Snubnose (Gold)"] = "detective_stainless"
|
||||
options["MarsTech R1 Snubnose (Leopard)"] = "detective_leopard"
|
||||
options["MarsTech Frontiersman Classic"] = "detective_peacemaker"
|
||||
options["MarsTech Frontiersman Shadow"] = "detective_peacemaker_dark"
|
||||
options["Jindal Duke"] = "detective_fitz"
|
||||
options["H-H M1895"] = "nagant"
|
||||
var/choice = tgui_input_list(M,"Choose your sprite!","Resprite Gun", options)
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
to_chat(M, "Your gun is now sprited as [choice]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/*
|
||||
* Lombardi Revolvers
|
||||
* Use to be detective revolvers until seperated
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/lombardi
|
||||
name = "Lombardi Buzzard"
|
||||
desc = "A rugged revolver that is mostly used by small law enforcement agencies across the frontier as a cheap, reliable sidearm. Uses .357 rounds."
|
||||
icon_state = "lombardi_police"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lombardi/panther
|
||||
name = "Lombardi Panther"
|
||||
icon_state = "lombardi_panther"
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lombardi/gold
|
||||
name = "Lombardi Deluxe 2502"
|
||||
desc = "A sweet looking revolver that is decorated with false gold and silver plating. Favored among by gamblers and criminals alike. Uses .357 rounds."
|
||||
icon_state = "lombardi_gold"
|
||||
|
||||
/*
|
||||
* Captain's Peacekeeper
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/cappeacekeeper
|
||||
name = "decorated peacekeeper"
|
||||
desc = "A MarsTech Frontiersman revolver that has been heavily modified. It has been decorated for personal use by command officers. Uses .44 rounds."
|
||||
description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, \
|
||||
MarsTech has been the provider of choice for law enforcement and security forces for over 300 years."
|
||||
icon_state = "captains_peacemaker"
|
||||
caliber = ".44"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a44
|
||||
|
||||
/*
|
||||
* Mateba
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/mateba
|
||||
name = "mateba"
|
||||
desc = "This unique looking handgun is named after an Italian company famous for the original manufacture of \
|
||||
these revolvers, and pasta kneading machines. Uses .357 rounds." // Yes I'm serious. -Spades
|
||||
icon_state = "mateba"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
|
||||
/*
|
||||
* Deckard (Blade Runner)
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard
|
||||
name = "\improper \"Deckard\" .38"
|
||||
desc = "A custom-built revolver, based off the semi-popular Detective Special model. Uses .38-Special rounds."
|
||||
icon_state = "deckard-empty"
|
||||
caliber = ".38"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
ammo_type = /obj/item/ammo_casing/a38
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard/emp
|
||||
ammo_type = /obj/item/ammo_casing/a38/emp
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard/update_icon()
|
||||
..()
|
||||
if(loaded.len)
|
||||
icon_state = "deckard-loaded"
|
||||
else
|
||||
icon_state = "deckard-empty"
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/deckard/load_ammo(var/obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/ammo_magazine))
|
||||
flick("deckard-reload",src)
|
||||
..()
|
||||
|
||||
/*
|
||||
* Judge
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/judge
|
||||
name = "\"The Judge\""
|
||||
desc = "A revolving hand-shotgun by Jindal Arms that packs the power of a 12 guage in the palm of your hand (if you don't break your wrist). Uses 12g rounds."
|
||||
description_fluff = "While wholly owned by Hephaestus Industries, the Jindal Arms brand does not appear \
|
||||
prominently in most company catalogues (Perhaps owing to its less than prestigious image), \
|
||||
instead being sold almost exclusively through retailers and advertising platforms targeting the \
|
||||
'independent roughneck' demographic."
|
||||
icon_state = "judge"
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 4)
|
||||
max_shells = 5
|
||||
recoil = 2 // ow my fucking hand
|
||||
accuracy = -15 // smooth bore + short barrel = shit accuracy
|
||||
ammo_type = /obj/item/ammo_casing/a12g
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun
|
||||
// ToDo: Remove accuracy debuf in exchange for slightly injuring your hand every time you fire it.
|
||||
|
||||
/*
|
||||
* Mako
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat
|
||||
name = "Mako revolver"
|
||||
desc = "The Bishamonten P100 Mako is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead. A rare yet deadly collector's item. Uses .38-Special and 12g rounds depending on the barrel."
|
||||
description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \
|
||||
Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \
|
||||
Bishamonten weapons tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons, and used very standard firing mechanisms - \
|
||||
the Mako was a notable exception, so original examples are much sought after."
|
||||
icon_state = "combatrevolver"
|
||||
item_state = "revolver"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
max_shells = 9
|
||||
caliber = ".38"
|
||||
ammo_type = /obj/item/ammo_casing/a38
|
||||
projectile_type = /obj/item/projectile/bullet/pistol
|
||||
var/secondary_max_shells = 1
|
||||
var/secondary_caliber = "12g"
|
||||
var/secondary_ammo_type = /obj/item/ammo_casing/a12g
|
||||
var/flipped_firing = 0
|
||||
var/list/secondary_loaded = list()
|
||||
var/list/tertiary_loaded = list()
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/New()
|
||||
for(var/i in 1 to secondary_max_shells)
|
||||
secondary_loaded += new secondary_ammo_type(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/verb/swap_firingmode()
|
||||
set name = "Swap Firing Mode"
|
||||
set category = "Object"
|
||||
set desc = "Click to swap from one method of firing to another."
|
||||
|
||||
var/mob/living/carbon/human/M = usr
|
||||
if(!M.mind)
|
||||
return 0
|
||||
|
||||
to_chat(M, "<span class='notice'>You change the firing mode on \the [src].</span>")
|
||||
if(!flipped_firing)
|
||||
if(max_shells && secondary_max_shells)
|
||||
max_shells = secondary_max_shells
|
||||
|
||||
if(caliber && secondary_caliber)
|
||||
caliber = secondary_caliber
|
||||
|
||||
if(ammo_type && secondary_ammo_type)
|
||||
ammo_type = secondary_ammo_type
|
||||
|
||||
if(secondary_loaded)
|
||||
tertiary_loaded = loaded.Copy()
|
||||
loaded = secondary_loaded
|
||||
|
||||
flipped_firing = 1
|
||||
|
||||
else
|
||||
if(max_shells)
|
||||
max_shells = initial(max_shells)
|
||||
|
||||
if(caliber && secondary_caliber)
|
||||
caliber = initial(caliber)
|
||||
|
||||
if(ammo_type && secondary_ammo_type)
|
||||
ammo_type = initial(ammo_type)
|
||||
|
||||
if(tertiary_loaded)
|
||||
secondary_loaded = loaded.Copy()
|
||||
loaded = tertiary_loaded
|
||||
|
||||
flipped_firing = 0
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/spin_cylinder()
|
||||
set name = "Spin cylinder"
|
||||
set desc = "Fun when you're bored out of your skull."
|
||||
set category = "Object"
|
||||
|
||||
chamber_offset = 0
|
||||
visible_message("<span class='warning'>\The [usr] spins the cylinder of \the [src]!</span>", \
|
||||
"<span class='notice'>You hear something metallic spin and click.</span>")
|
||||
playsound(src, 'sound/weapons/revolver_spin.ogg', 100, 1)
|
||||
if(!flipped_firing)
|
||||
loaded = shuffle(loaded)
|
||||
if(rand(1,max_shells) > loaded.len)
|
||||
chamber_offset = rand(0,max_shells - loaded.len)
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/lemat/examine(mob/user)
|
||||
. = ..()
|
||||
if(secondary_loaded)
|
||||
var/to_print
|
||||
for(var/round in secondary_loaded)
|
||||
to_print += round
|
||||
. += "It has a secondary barrel loaded with \a [to_print]"
|
||||
else
|
||||
. += "It has a secondary barrel that is empty."
|
||||
|
||||
|
||||
/*
|
||||
* Webley (Bay Port)
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/webley
|
||||
name = "patrol revolver"
|
||||
desc = "A rugged top break revolver commonly issued to planetary law enforcement offices. Uses .44 magnum rounds."
|
||||
description_fluff = "The Heberg-Hammarstrom Althing is a simple, head-wearing revolver made with an anti-corrosive alloy. \
|
||||
The Althing is advertised as being 'able to survive six months on the bottom of a frozen river and emerge full ready to \
|
||||
save a life'. Issued as standard sidearms to SifGuard frontier patrol."
|
||||
icon_state = "webley2"
|
||||
item_state = "webley2"
|
||||
caliber = ".44"
|
||||
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
ammo_type = /obj/item/ammo_casing/a44
|
||||
|
||||
/*
|
||||
* Webley (Eris Port)
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/revolver/consul
|
||||
name = "\improper \"Consul\" Revolver"
|
||||
desc = "Are you feeling lucky, punk? Uses .44 rounds."
|
||||
icon_state = "inspector"
|
||||
item_state = "revolver"
|
||||
caliber = ".44"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3)
|
||||
handle_casings = CYCLE_CASINGS
|
||||
ammo_type = /obj/item/ammo_casing/a44/rubber
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/consul/proc/update_charge()
|
||||
cut_overlays()
|
||||
if(loaded.len==0)
|
||||
add_overlay("inspector_off")
|
||||
else
|
||||
add_overlay("inspector_on")
|
||||
|
||||
/obj/item/weapon/gun/projectile/revolver/consul/update_icon()
|
||||
update_charge()
|
||||
|
||||
@@ -1,236 +1,236 @@
|
||||
/*
|
||||
* Shotgun
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump
|
||||
name = "shotgun"
|
||||
desc = "The mass-produced MarsTech Meteor 29 shotgun is a favourite of police and security forces on many worlds. Uses 12g rounds."
|
||||
description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, \
|
||||
MarsTech has been the provider of choice for law enforcement and security forces for over 300 years."
|
||||
icon_state = "shotgun"
|
||||
item_state = "shotgun"
|
||||
max_shells = 4
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
ammo_type = /obj/item/ammo_casing/a12g/beanbag
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun
|
||||
handle_casings = HOLD_CASINGS
|
||||
var/recentpump = 0 //To prevent spammage
|
||||
var/action_sound = 'sound/weapons/shotgunpump.ogg'
|
||||
var/empty_sprite = 0 //This is just a dirty var so it doesn't fudge up.
|
||||
var/pump_animation = "shotgun-pump" //You put the reference to the animation in question here. Frees up namming. Ex: "shotgun_old_pump" or "sniper_cycle"
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/consume_next_projectile()
|
||||
if(chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob)
|
||||
if(world.time >= recentpump + 10)
|
||||
pump(user)
|
||||
recentpump = world.time
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob)
|
||||
playsound(src, action_sound, 60, 1)
|
||||
|
||||
// We have a shell in the chamber
|
||||
if(chambered)
|
||||
if(chambered.caseless)
|
||||
qdel(chambered) // Delete casing
|
||||
else
|
||||
chambered.loc = get_turf(src) // Eject casing
|
||||
chambered = null
|
||||
M.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD Port
|
||||
|
||||
// Load next shell
|
||||
if(loaded.len)
|
||||
var/obj/item/ammo_casing/AC = loaded[1] // Load next casing.
|
||||
loaded -= AC // Remove casing from loaded list.
|
||||
chambered = AC
|
||||
M.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD Port
|
||||
|
||||
if(pump_animation) // This affects all bolt action and shotguns.
|
||||
flick("[pump_animation]", src) // This plays any pumping
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/update_icon()//This adds empty sprite capability for shotguns.
|
||||
..()
|
||||
if(!empty_sprite)//Just a dirty check
|
||||
return
|
||||
if((loaded.len) || (chambered))
|
||||
icon_state = "[icon_state]"
|
||||
else
|
||||
icon_state = "[icon_state]-empty"
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/empty
|
||||
ammo_type = null
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/slug
|
||||
ammo_type = /obj/item/ammo_casing/a12g
|
||||
pump_animation = null
|
||||
|
||||
/*
|
||||
* Combat Shotgun
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat
|
||||
name = "combat shotgun"
|
||||
desc = "Built for close quarters combat, the Hephaestus Industries KS-40 is widely regarded as a weapon of choice for repelling boarders. Uses 12g rounds."
|
||||
description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' \
|
||||
branding for its military-grade equipment used by armed forces across human space."
|
||||
icon_state = "cshotgun"
|
||||
item_state = "cshotgun"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2)
|
||||
max_shells = 7 //match the ammo box capacity, also it can hold a round in the chamber anyways, for a total of 8.
|
||||
ammo_type = /obj/item/ammo_casing/a12g
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
pump_animation = "cshotgun-pump"
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat/empty
|
||||
ammo_type = null
|
||||
|
||||
/*
|
||||
* Double-Barreled Shotgun
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel
|
||||
name = "double-barreled shotgun"
|
||||
desc = "A truely classic weapon. No need to change what works. Uses 12g rounds."
|
||||
icon_state = "dshotgun"
|
||||
item_state = "dshotgun"
|
||||
//SPEEDLOADER because rapid unloading.
|
||||
//In principle someone could make a speedloader for it, so it makes sense.
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
handle_casings = CYCLE_CASINGS
|
||||
max_shells = 2
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 1)
|
||||
ammo_type = /obj/item/ammo_casing/a12g/beanbag
|
||||
|
||||
var/unique_reskin
|
||||
var/sawn_off = FALSE
|
||||
|
||||
burst_delay = 0
|
||||
firemodes = list(
|
||||
list(mode_name="fire one barrel at a time", burst=1),
|
||||
list(mode_name="fire both barrels at once", burst=2),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet
|
||||
ammo_type = /obj/item/ammo_casing/a12g/pellet
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/flare
|
||||
name = "signal shotgun"
|
||||
desc = "A double-barreled shotgun meant to fire signal flash shells. Uses 12g rounds."
|
||||
ammo_type = /obj/item/ammo_casing/a12g/flash
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/unload_ammo(user, allow_dump)
|
||||
..(user, allow_dump=1)
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Rename your gun."
|
||||
|
||||
var/input = sanitizeSafe(input(usr, "What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
var/mob/M = usr
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/verb/reskin_gun()
|
||||
set name = "Resprite gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to choose a sprite for your gun."
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["Default"] = "dshotgun"
|
||||
options["Cherry Red"] = "dshotgun_d"
|
||||
options["Ash"] = "dshotgun_f"
|
||||
options["Faded Grey"] = "dshotgun_g"
|
||||
options["Maple"] = "dshotgun_l"
|
||||
options["Rosewood"] = "dshotgun_p"
|
||||
options["Olive Green"] = "dshotgun_o"
|
||||
options["Blued"] = "dshotgun_b"
|
||||
var/choice = tgui_input_list(M,"Choose your sprite!","Resprite Gun", options)
|
||||
if(sawn_off)
|
||||
to_chat(M, "<span class='warning'>The [src] is already shortened and cannot be resprited!</span>")
|
||||
return
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
unique_reskin = options[choice]
|
||||
to_chat(M, "Your gun is now sprited as [choice]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
//this is largely hacky and bad :( -Pete //less hacky and bad now :) -Ghost
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
if(sawn_off)
|
||||
to_chat(user, "<span class='warning'>The [src] is already shortened!</span>")
|
||||
return
|
||||
if(istype(A, /obj/item/weapon/surgical/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
|
||||
to_chat(user, "<span class='notice'>You begin to shorten the barrel of \the [src].</span>")
|
||||
if(loaded.len)
|
||||
var/burstsetting = burst
|
||||
burst = 2
|
||||
user.visible_message("<span class='danger'>The shotgun goes off!</span>", "<span class='danger'>The shotgun goes off in your face!</span>")
|
||||
Fire_userless(user)
|
||||
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD Port
|
||||
burst = burstsetting
|
||||
return
|
||||
if(do_after(user, 30)) // SHIT IS STEALTHY EYYYYY
|
||||
if(sawn_off)
|
||||
return
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin]_sawn"
|
||||
else
|
||||
icon_state = "dshotgun_sawn"
|
||||
item_state = "sawnshotgun"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
force = 5
|
||||
slot_flags &= ~SLOT_BACK // you can't sling it on your back
|
||||
slot_flags |= (SLOT_BELT|SLOT_HOLSTER) // but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not.
|
||||
name = "sawn-off shotgun"
|
||||
desc = "Omar's coming!"
|
||||
to_chat(user, "<span class='warning'>You shorten the barrel of \the [src]!</span>")
|
||||
sawn_off = TRUE
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
* Sawn-Off Shotgun
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn
|
||||
name = "sawn-off shotgun"
|
||||
desc = "Omar's coming!" // I'm not gonna add "Uses 12g rounds." to this one. I'll just let this reference go undisturbed.
|
||||
icon_state = "dshotgun_sawn"
|
||||
item_state = "sawnshotgun"
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
ammo_type = /obj/item/ammo_casing/a12g/pellet
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
force = 5
|
||||
sawn_off = TRUE
|
||||
|
||||
//Sjorgen Inertial Shotgun
|
||||
/obj/item/weapon/gun/projectile/shotgun/semi
|
||||
name = "semi-automatic shotgun"
|
||||
desc = "A shotgun with a simple, yet effective recoil inertia loading mechanism for semi-automatic fire. This gun uses 12 gauge ammunition."
|
||||
description_fluff = "Looking back on yet another venerable design, Hedberg-Hammarstrom settled on a pattern of shotgun that both had the reliability of a well proven semi-automatic loading system in addition to a striking visual aesthetic that would be appealing to even the most discerning of firearm collectors."
|
||||
icon_state = "sjorgen"
|
||||
item_state = "shotgun"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
|
||||
slot_flags = SLOT_BACK
|
||||
load_method = SINGLE_CASING
|
||||
max_shells = 5
|
||||
ammo_type = /obj/item/ammo_casing/a12g/beanbag
|
||||
|
||||
/*
|
||||
* Shotgun
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump
|
||||
name = "shotgun"
|
||||
desc = "The mass-produced MarsTech Meteor 29 shotgun is a favourite of police and security forces on many worlds. Uses 12g rounds."
|
||||
description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, \
|
||||
MarsTech has been the provider of choice for law enforcement and security forces for over 300 years."
|
||||
icon_state = "shotgun"
|
||||
item_state = "shotgun"
|
||||
max_shells = 4
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2)
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
ammo_type = /obj/item/ammo_casing/a12g/beanbag
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun
|
||||
handle_casings = HOLD_CASINGS
|
||||
var/recentpump = 0 //To prevent spammage
|
||||
var/action_sound = 'sound/weapons/shotgunpump.ogg'
|
||||
var/empty_sprite = 0 //This is just a dirty var so it doesn't fudge up.
|
||||
var/pump_animation = "shotgun-pump" //You put the reference to the animation in question here. Frees up namming. Ex: "shotgun_old_pump" or "sniper_cycle"
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/consume_next_projectile()
|
||||
if(chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob)
|
||||
if(world.time >= recentpump + 10)
|
||||
pump(user)
|
||||
recentpump = world.time
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob)
|
||||
playsound(src, action_sound, 60, 1)
|
||||
|
||||
// We have a shell in the chamber
|
||||
if(chambered)
|
||||
if(chambered.caseless)
|
||||
qdel(chambered) // Delete casing
|
||||
else
|
||||
chambered.loc = get_turf(src) // Eject casing
|
||||
chambered = null
|
||||
M.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD Port
|
||||
|
||||
// Load next shell
|
||||
if(loaded.len)
|
||||
var/obj/item/ammo_casing/AC = loaded[1] // Load next casing.
|
||||
loaded -= AC // Remove casing from loaded list.
|
||||
chambered = AC
|
||||
M.hud_used.update_ammo_hud(M, src) // TGMC Ammo HUD Port
|
||||
|
||||
if(pump_animation) // This affects all bolt action and shotguns.
|
||||
flick("[pump_animation]", src) // This plays any pumping
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/update_icon()//This adds empty sprite capability for shotguns.
|
||||
..()
|
||||
if(!empty_sprite)//Just a dirty check
|
||||
return
|
||||
if((loaded.len) || (chambered))
|
||||
icon_state = "[icon_state]"
|
||||
else
|
||||
icon_state = "[icon_state]-empty"
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/empty
|
||||
ammo_type = null
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/slug
|
||||
ammo_type = /obj/item/ammo_casing/a12g
|
||||
pump_animation = null
|
||||
|
||||
/*
|
||||
* Combat Shotgun
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat
|
||||
name = "combat shotgun"
|
||||
desc = "Built for close quarters combat, the Hephaestus Industries KS-40 is widely regarded as a weapon of choice for repelling boarders. Uses 12g rounds."
|
||||
description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' \
|
||||
branding for its military-grade equipment used by armed forces across human space."
|
||||
icon_state = "cshotgun"
|
||||
item_state = "cshotgun"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2)
|
||||
max_shells = 7 //match the ammo box capacity, also it can hold a round in the chamber anyways, for a total of 8.
|
||||
ammo_type = /obj/item/ammo_casing/a12g
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
pump_animation = "cshotgun-pump"
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat/empty
|
||||
ammo_type = null
|
||||
|
||||
/*
|
||||
* Double-Barreled Shotgun
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel
|
||||
name = "double-barreled shotgun"
|
||||
desc = "A truely classic weapon. No need to change what works. Uses 12g rounds."
|
||||
icon_state = "dshotgun"
|
||||
item_state = "dshotgun"
|
||||
//SPEEDLOADER because rapid unloading.
|
||||
//In principle someone could make a speedloader for it, so it makes sense.
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
handle_casings = CYCLE_CASINGS
|
||||
max_shells = 2
|
||||
w_class = ITEMSIZE_LARGE
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 1)
|
||||
ammo_type = /obj/item/ammo_casing/a12g/beanbag
|
||||
|
||||
var/unique_reskin
|
||||
var/sawn_off = FALSE
|
||||
|
||||
burst_delay = 0
|
||||
firemodes = list(
|
||||
list(mode_name="fire one barrel at a time", burst=1),
|
||||
list(mode_name="fire both barrels at once", burst=2),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet
|
||||
ammo_type = /obj/item/ammo_casing/a12g/pellet
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/flare
|
||||
name = "signal shotgun"
|
||||
desc = "A double-barreled shotgun meant to fire signal flash shells. Uses 12g rounds."
|
||||
ammo_type = /obj/item/ammo_casing/a12g/flash
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/unload_ammo(user, allow_dump)
|
||||
..(user, allow_dump=1)
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/verb/rename_gun()
|
||||
set name = "Name Gun"
|
||||
set category = "Object"
|
||||
set desc = "Rename your gun."
|
||||
|
||||
var/input = sanitizeSafe(input(usr, "What do you want to name the gun?", ,""), MAX_NAME_LEN)
|
||||
|
||||
var/mob/M = usr
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/verb/reskin_gun()
|
||||
set name = "Resprite gun"
|
||||
set category = "Object"
|
||||
set desc = "Click to choose a sprite for your gun."
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["Default"] = "dshotgun"
|
||||
options["Cherry Red"] = "dshotgun_d"
|
||||
options["Ash"] = "dshotgun_f"
|
||||
options["Faded Grey"] = "dshotgun_g"
|
||||
options["Maple"] = "dshotgun_l"
|
||||
options["Rosewood"] = "dshotgun_p"
|
||||
options["Olive Green"] = "dshotgun_o"
|
||||
options["Blued"] = "dshotgun_b"
|
||||
var/choice = tgui_input_list(M,"Choose your sprite!","Resprite Gun", options)
|
||||
if(sawn_off)
|
||||
to_chat(M, "<span class='warning'>The [src] is already shortened and cannot be resprited!</span>")
|
||||
return
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
unique_reskin = options[choice]
|
||||
to_chat(M, "Your gun is now sprited as [choice]. Say hello to your new friend.")
|
||||
return 1
|
||||
|
||||
//this is largely hacky and bad :( -Pete //less hacky and bad now :) -Ghost
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
if(sawn_off)
|
||||
to_chat(user, "<span class='warning'>The [src] is already shortened!</span>")
|
||||
return
|
||||
if(istype(A, /obj/item/weapon/surgical/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter))
|
||||
to_chat(user, "<span class='notice'>You begin to shorten the barrel of \the [src].</span>")
|
||||
if(loaded.len)
|
||||
var/burstsetting = burst
|
||||
burst = 2
|
||||
user.visible_message("<span class='danger'>The shotgun goes off!</span>", "<span class='danger'>The shotgun goes off in your face!</span>")
|
||||
Fire_userless(user)
|
||||
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD Port
|
||||
burst = burstsetting
|
||||
return
|
||||
if(do_after(user, 30)) // SHIT IS STEALTHY EYYYYY
|
||||
if(sawn_off)
|
||||
return
|
||||
if(unique_reskin)
|
||||
icon_state = "[unique_reskin]_sawn"
|
||||
else
|
||||
icon_state = "dshotgun_sawn"
|
||||
item_state = "sawnshotgun"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
force = 5
|
||||
slot_flags &= ~SLOT_BACK // you can't sling it on your back
|
||||
slot_flags |= (SLOT_BELT|SLOT_HOLSTER) // but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not.
|
||||
name = "sawn-off shotgun"
|
||||
desc = "Omar's coming!"
|
||||
to_chat(user, "<span class='warning'>You shorten the barrel of \the [src]!</span>")
|
||||
sawn_off = TRUE
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
* Sawn-Off Shotgun
|
||||
*/
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn
|
||||
name = "sawn-off shotgun"
|
||||
desc = "Omar's coming!" // I'm not gonna add "Uses 12g rounds." to this one. I'll just let this reference go undisturbed.
|
||||
icon_state = "dshotgun_sawn"
|
||||
item_state = "sawnshotgun"
|
||||
slot_flags = SLOT_BELT|SLOT_HOLSTER
|
||||
ammo_type = /obj/item/ammo_casing/a12g/pellet
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
force = 5
|
||||
sawn_off = TRUE
|
||||
|
||||
//Sjorgen Inertial Shotgun
|
||||
/obj/item/weapon/gun/projectile/shotgun/semi
|
||||
name = "semi-automatic shotgun"
|
||||
desc = "A shotgun with a simple, yet effective recoil inertia loading mechanism for semi-automatic fire. This gun uses 12 gauge ammunition."
|
||||
description_fluff = "Looking back on yet another venerable design, Hedberg-Hammarstrom settled on a pattern of shotgun that both had the reliability of a well proven semi-automatic loading system in addition to a striking visual aesthetic that would be appealing to even the most discerning of firearm collectors."
|
||||
icon_state = "sjorgen"
|
||||
item_state = "shotgun"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
caliber = "12g"
|
||||
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
|
||||
slot_flags = SLOT_BACK
|
||||
load_method = SINGLE_CASING
|
||||
max_shells = 5
|
||||
ammo_type = /obj/item/ammo_casing/a12g/beanbag
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,17 @@
|
||||
/obj/item/projectile/animate
|
||||
name = "bolt of animation"
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#55AAFF"
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/animate/Bump(var/atom/change)
|
||||
if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects))
|
||||
var/obj/O = change
|
||||
new /mob/living/simple_mob/hostile/mimic/copy(O.loc, O, firer)
|
||||
..()
|
||||
/obj/item/projectile/animate
|
||||
name = "bolt of animation"
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#55AAFF"
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/animate/Bump(var/atom/change)
|
||||
if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects))
|
||||
var/obj/O = change
|
||||
new /mob/living/simple_mob/hostile/mimic/copy(O.loc, O, firer)
|
||||
..()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,471 +1,471 @@
|
||||
/obj/item/projectile/bullet
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
fire_sound = 'sound/weapons/Gunshot4.ogg'
|
||||
damage = 60
|
||||
damage_type = BRUTE
|
||||
nodamage = 0
|
||||
check_armour = "bullet"
|
||||
embed_chance = 20 //Modified in the actual embed process, but this should keep embed chance about the same
|
||||
sharp = TRUE
|
||||
hitsound_wall = "ricochet"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
excavation_amount = 20
|
||||
var/mob_passthrough_check = 0
|
||||
hud_state = "pistol_lightap"
|
||||
hud_state_empty = "pistol_empty" // Just in case we somehow have no hud_state_empty defined
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bullet
|
||||
|
||||
/obj/item/projectile/bullet/on_hit(var/atom/target, var/blocked = 0)
|
||||
if (..(target, blocked))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
|
||||
/obj/item/projectile/bullet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
if(penetrating > 0 && damage > 20 && prob(damage))
|
||||
mob_passthrough_check = 1
|
||||
else
|
||||
mob_passthrough_check = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/can_embed()
|
||||
//prevent embedding if the projectile is passing through the mob
|
||||
if(mob_passthrough_check)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/check_penetrate(var/atom/A)
|
||||
if(!A || !A.density) return 1 //if whatever it was got destroyed when we hit it, then I guess we can just keep going
|
||||
|
||||
if(istype(A, /obj/mecha))
|
||||
return 1 //mecha have their own penetration handling
|
||||
|
||||
if(ismob(A))
|
||||
if(!mob_passthrough_check)
|
||||
return 0
|
||||
if(iscarbon(A))
|
||||
damage *= 0.7 //squishy mobs absorb KE
|
||||
return 1
|
||||
|
||||
var/chance = damage
|
||||
if(istype(A, /turf/simulated/wall))
|
||||
var/turf/simulated/wall/W = A
|
||||
chance = round(damage/W.material.integrity*180)
|
||||
else if(istype(A, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = A
|
||||
chance = round(damage/D.maxhealth*180)
|
||||
if(D.glass) chance *= 2
|
||||
else if(istype(A, /obj/structure/girder))
|
||||
chance = 100
|
||||
|
||||
if(prob(chance))
|
||||
if(A.opacity)
|
||||
//display a message so that people on the other side aren't so confused
|
||||
A.visible_message("<span class='warning'>\The [src] pierces through \the [A]!</span>")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/* short-casing projectiles, like the kind used in pistols or SMGs */
|
||||
|
||||
/obj/item/projectile/bullet/pistol // 9mm pistols and most SMGs. Sacrifice power for capacity.
|
||||
fire_sound = 'sound/weapons/gunshot2.ogg'
|
||||
damage = 20
|
||||
hud_state = "pistol"
|
||||
hud_state_empty = "pistol_empty"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/ap
|
||||
damage = 15
|
||||
armor_penetration = 30
|
||||
hud_state = "pistol_light_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/hp
|
||||
damage = 25
|
||||
armor_penetration = -50
|
||||
hud_state = "pistol_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium // .45 (and maybe .40 if it ever gets added) caliber security pistols. Balance between capacity and power.
|
||||
fire_sound = 'sound/weapons/gunshot3.ogg' // Snappier sound.
|
||||
damage = 25
|
||||
hud_state = "pistol"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium/ap
|
||||
damage = 20
|
||||
armor_penetration = 15
|
||||
hud_state = "pistol_light_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium/hp
|
||||
damage = 30
|
||||
armor_penetration = -50
|
||||
hud_state = "pistol_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/strong // .357 and .44 caliber stuff. High power pistols like the Mateba or Desert Eagle. Sacrifice capacity for power.
|
||||
fire_sound = 'sound/weapons/gunshot4.ogg'
|
||||
damage = 60
|
||||
hud_state = "pistol_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/rubber/strong // "Rubber" bullets for high power pistols.
|
||||
fire_sound = 'sound/weapons/gunshot3.ogg' // Rubber shots have less powder, but these still have more punch than normal rubber shot.
|
||||
damage = 10
|
||||
agony = 60
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "pistol_special"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/rubber // "Rubber" bullets for all other pistols.
|
||||
name = "rubber bullet"
|
||||
damage = 5
|
||||
agony = 40
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "pistol_special"
|
||||
fire_sound ='sound/weapons/Gunshot_pathetic.ogg' // Rubber shots have less powder in the casing.
|
||||
|
||||
/* shotgun projectiles */
|
||||
|
||||
/obj/item/projectile/bullet/shotgun
|
||||
name = "slug"
|
||||
fire_sound = 'sound/weapons/Gunshot_shotgun.ogg'
|
||||
damage = 50
|
||||
armor_penetration = 20
|
||||
hud_state = "shotgun_slug"
|
||||
hud_state_empty = "shotgun_empty"
|
||||
|
||||
/obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets
|
||||
name = "beanbag"
|
||||
damage = 20
|
||||
agony = 60
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "shotgun_beanbag"
|
||||
|
||||
//Should do about 80 damage at 1 tile distance (adjacent), and 50 damage at 3 tiles distance.
|
||||
//Overall less damage than slugs in exchange for more damage at very close range and more embedding
|
||||
/obj/item/projectile/bullet/pellet/shotgun
|
||||
name = "shrapnel"
|
||||
fire_sound = 'sound/weapons/Gunshot_shotgun.ogg'
|
||||
damage = 13
|
||||
pellets = 6
|
||||
range_step = 1
|
||||
spread_step = 10
|
||||
hud_state = "shotgun_buckshot"
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun/flak
|
||||
damage = 2 //The main weapon using these fires four at a time, usually with different destinations. Usually.
|
||||
range_step = 2
|
||||
spread_step = 30
|
||||
armor_penetration = 10
|
||||
hud_state = "shotgun_flechette"
|
||||
|
||||
//EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used
|
||||
/obj/item/projectile/bullet/shotgun/ion
|
||||
name = "ion slug"
|
||||
fire_sound = 'sound/weapons/Laser.ogg' // Really? We got nothing better than this?
|
||||
damage = 15
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "shotgun_ion"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/shotgun/ion/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
empulse(target, 0, 0, 0, 0) //Only affects what it hits
|
||||
return 1
|
||||
|
||||
|
||||
/* "Rifle" rounds */
|
||||
|
||||
/obj/item/projectile/bullet/rifle
|
||||
fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg'
|
||||
armor_penetration = 15
|
||||
penetrating = 1
|
||||
hud_state = "rifle"
|
||||
hud_state_empty = "rifle_empty"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762
|
||||
fire_sound = 'sound/weapons/Gunshot_heavy.ogg'
|
||||
damage = 35
|
||||
hud_state = "rifle_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/sniper // Hitscan specifically for sniper ammo; to be implimented at a later date, probably for the SVD. -Ace
|
||||
fire_sound = 'sound/weapons/Gunshot_sniper.ogg'
|
||||
hitscan = 1 //so the ammo isn't useless as a sniper weapon
|
||||
hud_state = "hivelo"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/ap
|
||||
damage = 30
|
||||
armor_penetration = 50 // At 30 or more armor, this will do more damage than standard rounds.
|
||||
hud_state = "rifle_ap"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/hp
|
||||
damage = 40
|
||||
armor_penetration = -50
|
||||
penetrating = 0
|
||||
hud_state = "hivelo_iff"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/hunter // Optimized for killing simple animals and not people, because Balance(tm)
|
||||
damage = 20
|
||||
SA_bonus_damage = 50 // 70 total on animals.
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
hud_state = "rifle_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545
|
||||
fire_sound = 'sound/weapons/Gunshot_light.ogg'
|
||||
damage = 25
|
||||
hud_state = "rifle"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545/ap
|
||||
damage = 20
|
||||
armor_penetration = 50 // At 40 or more armor, this will do more damage than standard rounds.
|
||||
hud_state = "rifle_ap"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545/hp
|
||||
damage = 35
|
||||
armor_penetration = -50
|
||||
penetrating = 0
|
||||
hud_state = "hivelo_iff"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545/hunter
|
||||
damage = 15
|
||||
SA_bonus_damage = 35 // 50 total on animals.
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
hud_state = "rifle_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a145 // 14.5�114mm is bigger than a .50 BMG round.
|
||||
fire_sound = 'sound/weapons/Gunshot_cannon.ogg' // This is literally an anti-tank rifle caliber. It better sound like a fucking cannon.
|
||||
damage = 80
|
||||
stun = 3
|
||||
weaken = 3
|
||||
penetrating = 5
|
||||
armor_penetration = 80
|
||||
hitscan = 1 //so the PTR isn't useless as a sniper weapon
|
||||
hud_state = "sniper"
|
||||
|
||||
icon_state = "bullet_alt"
|
||||
tracer_type = /obj/effect/projectile/tracer/cannon
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a145/highvel
|
||||
damage = 50
|
||||
stun = 1
|
||||
weaken = 0
|
||||
penetrating = 15
|
||||
armor_penetration = 90
|
||||
hud_state = "sniper_flak"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a44rifle
|
||||
fire_sound = 'sound/weapons/gunshot4.ogg'
|
||||
damage = 50
|
||||
hud_state = "revolver"
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
/obj/item/projectile/bullet/suffocationbullet//How does this even work?
|
||||
name = "co bullet"
|
||||
damage = 20
|
||||
damage_type = OXY
|
||||
hud_state = "pistol_tranq"
|
||||
|
||||
/obj/item/projectile/bullet/cyanideround
|
||||
name = "poison bullet"
|
||||
damage = 40
|
||||
damage_type = TOX
|
||||
hud_state = "pistol_tranq"
|
||||
|
||||
/obj/item/projectile/bullet/burstbullet
|
||||
name = "exploding bullet"
|
||||
fire_sound = 'sound/effects/Explosion1.ogg'
|
||||
damage = 20
|
||||
embed_chance = 0
|
||||
edge = TRUE
|
||||
hud_state = "pistol_fire"
|
||||
|
||||
/obj/item/projectile/bullet/burstbullet/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isturf(target))
|
||||
explosion(target, -1, 0, 2)
|
||||
..()
|
||||
|
||||
/* Incendiary */
|
||||
|
||||
/obj/item/projectile/bullet/incendiary
|
||||
name = "incendiary bullet"
|
||||
icon_state = "bullet_alt"
|
||||
damage = 15
|
||||
damage_type = BURN
|
||||
incendiary = 0.5
|
||||
flammability = 2
|
||||
hud_state = "pistol_fire"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower
|
||||
name = "ball of fire"
|
||||
desc = "Don't stand in the fire."
|
||||
icon_state = "fireball"
|
||||
damage = 10
|
||||
embed_chance = 0
|
||||
incendiary = 2
|
||||
flammability = 4
|
||||
agony = 30
|
||||
range = 4
|
||||
vacuum_traversal = 0
|
||||
hud_state = "flame"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/after_move()
|
||||
..()
|
||||
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
for(var/obj/effect/plant/Victim in T)
|
||||
if(prob(max(20, 100 - (Victim.seed.get_trait(TRAIT_ENDURANCE))))) // Chance to immediately kill a vine or rampant growth, minimum of 20%.
|
||||
Victim.die_off()
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/large
|
||||
damage = 5
|
||||
incendiary = 3
|
||||
flammability = 2
|
||||
range = 6
|
||||
hud_state = "flame"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/tiny
|
||||
damage = 2
|
||||
incendiary = 0
|
||||
flammability = 2
|
||||
modifier_type_to_apply = /datum/modifier/fire/stack_managed/weak
|
||||
modifier_duration = 20 SECONDS
|
||||
range = 6
|
||||
agony = 0
|
||||
hud_state = "flame"
|
||||
|
||||
/* Practice rounds and blanks */
|
||||
|
||||
/obj/item/projectile/bullet/practice
|
||||
damage = 5
|
||||
hud_state = "smg_light"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/cap // Just the primer, such as a cap gun.
|
||||
name = "cap"
|
||||
damage_type = HALLOSS
|
||||
fire_sound = 'sound/effects/snap.ogg'
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
hud_state = "monkey"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/pistol/cap/process()
|
||||
loc = null
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/bullet/blank
|
||||
name = "blank"
|
||||
damage_type = HALLOSS
|
||||
fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' // Blanks still make loud noises.
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
hud_state = "smg_light"
|
||||
|
||||
/* BB Rounds */
|
||||
/obj/item/projectile/bullet/bb // Generic single BB
|
||||
name = "BB"
|
||||
damage = 0
|
||||
agony = 0
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
silenced = TRUE
|
||||
hud_state = "pistol_light"
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun/bb // Shotgun
|
||||
name = "BB"
|
||||
damage = 0
|
||||
agony = 0
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
pellets = 6
|
||||
range_step = 1
|
||||
spread_step = 10
|
||||
silenced = TRUE
|
||||
hud_state = "pistol_light"
|
||||
|
||||
/* toy projectiles */
|
||||
/obj/item/projectile/bullet/cap
|
||||
name = "cap"
|
||||
desc = "SNAP!"
|
||||
damage = 0 // It's a damn toy.
|
||||
embed_chance = 0
|
||||
nodamage = TRUE
|
||||
sharp = FALSE
|
||||
damage_type = HALLOSS
|
||||
impact_effect_type = null
|
||||
fire_sound = 'sound/effects/snap.ogg'
|
||||
combustion = FALSE
|
||||
hud_state = "pistol_light"
|
||||
|
||||
/obj/item/projectile/bullet/cap/process()
|
||||
loc = null
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart
|
||||
name = "foam dart"
|
||||
desc = "I hope you're wearing eye protection."
|
||||
damage = 0 // It's a damn toy.
|
||||
embed_chance = 0
|
||||
nodamage = TRUE
|
||||
sharp = FALSE
|
||||
damage_type = HALLOSS
|
||||
impact_effect_type = null
|
||||
fire_sound = 'sound/items/syringeproj.ogg'
|
||||
combustion = FALSE
|
||||
icon = 'icons/obj/gun_toy.dmi'
|
||||
icon_state = "foamdart_proj"
|
||||
range = 15
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart/on_impact(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart(get_turf(loc))
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart/on_range(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart(get_turf(loc))
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart_riot
|
||||
name = "riot foam dart"
|
||||
desc = "Whose smart idea was it to use toys as crowd control? Ages 18 and up."
|
||||
damage = 0 // It's a damn toy.
|
||||
embed_chance = 0
|
||||
agony = 50 // The riot part of the riot dart
|
||||
nodamage = TRUE
|
||||
sharp = FALSE
|
||||
damage_type = HALLOSS
|
||||
impact_effect_type = null
|
||||
fire_sound = 'sound/items/syringeproj.ogg'
|
||||
combustion = FALSE
|
||||
icon = 'icons/obj/gun_toy.dmi'
|
||||
icon_state = "foamdart_riot_proj"
|
||||
range = 15
|
||||
hud_state = "grenade_he"
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart_riot/on_impact(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart/riot(get_turf(loc))
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart_riot/on_range(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
/obj/item/projectile/bullet
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
fire_sound = 'sound/weapons/Gunshot4.ogg'
|
||||
damage = 60
|
||||
damage_type = BRUTE
|
||||
nodamage = 0
|
||||
check_armour = "bullet"
|
||||
embed_chance = 20 //Modified in the actual embed process, but this should keep embed chance about the same
|
||||
sharp = TRUE
|
||||
hitsound_wall = "ricochet"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
excavation_amount = 20
|
||||
var/mob_passthrough_check = 0
|
||||
hud_state = "pistol_lightap"
|
||||
hud_state_empty = "pistol_empty" // Just in case we somehow have no hud_state_empty defined
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bullet
|
||||
|
||||
/obj/item/projectile/bullet/on_hit(var/atom/target, var/blocked = 0)
|
||||
if (..(target, blocked))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
|
||||
/obj/item/projectile/bullet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
if(penetrating > 0 && damage > 20 && prob(damage))
|
||||
mob_passthrough_check = 1
|
||||
else
|
||||
mob_passthrough_check = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/can_embed()
|
||||
//prevent embedding if the projectile is passing through the mob
|
||||
if(mob_passthrough_check)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/check_penetrate(var/atom/A)
|
||||
if(!A || !A.density) return 1 //if whatever it was got destroyed when we hit it, then I guess we can just keep going
|
||||
|
||||
if(istype(A, /obj/mecha))
|
||||
return 1 //mecha have their own penetration handling
|
||||
|
||||
if(ismob(A))
|
||||
if(!mob_passthrough_check)
|
||||
return 0
|
||||
if(iscarbon(A))
|
||||
damage *= 0.7 //squishy mobs absorb KE
|
||||
return 1
|
||||
|
||||
var/chance = damage
|
||||
if(istype(A, /turf/simulated/wall))
|
||||
var/turf/simulated/wall/W = A
|
||||
chance = round(damage/W.material.integrity*180)
|
||||
else if(istype(A, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = A
|
||||
chance = round(damage/D.maxhealth*180)
|
||||
if(D.glass) chance *= 2
|
||||
else if(istype(A, /obj/structure/girder))
|
||||
chance = 100
|
||||
|
||||
if(prob(chance))
|
||||
if(A.opacity)
|
||||
//display a message so that people on the other side aren't so confused
|
||||
A.visible_message("<span class='warning'>\The [src] pierces through \the [A]!</span>")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/* short-casing projectiles, like the kind used in pistols or SMGs */
|
||||
|
||||
/obj/item/projectile/bullet/pistol // 9mm pistols and most SMGs. Sacrifice power for capacity.
|
||||
fire_sound = 'sound/weapons/gunshot2.ogg'
|
||||
damage = 20
|
||||
hud_state = "pistol"
|
||||
hud_state_empty = "pistol_empty"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/ap
|
||||
damage = 15
|
||||
armor_penetration = 30
|
||||
hud_state = "pistol_light_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/hp
|
||||
damage = 25
|
||||
armor_penetration = -50
|
||||
hud_state = "pistol_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium // .45 (and maybe .40 if it ever gets added) caliber security pistols. Balance between capacity and power.
|
||||
fire_sound = 'sound/weapons/gunshot3.ogg' // Snappier sound.
|
||||
damage = 25
|
||||
hud_state = "pistol"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium/ap
|
||||
damage = 20
|
||||
armor_penetration = 15
|
||||
hud_state = "pistol_light_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/medium/hp
|
||||
damage = 30
|
||||
armor_penetration = -50
|
||||
hud_state = "pistol_ap"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/strong // .357 and .44 caliber stuff. High power pistols like the Mateba or Desert Eagle. Sacrifice capacity for power.
|
||||
fire_sound = 'sound/weapons/gunshot4.ogg'
|
||||
damage = 60
|
||||
hud_state = "pistol_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/rubber/strong // "Rubber" bullets for high power pistols.
|
||||
fire_sound = 'sound/weapons/gunshot3.ogg' // Rubber shots have less powder, but these still have more punch than normal rubber shot.
|
||||
damage = 10
|
||||
agony = 60
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "pistol_special"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/rubber // "Rubber" bullets for all other pistols.
|
||||
name = "rubber bullet"
|
||||
damage = 5
|
||||
agony = 40
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "pistol_special"
|
||||
fire_sound ='sound/weapons/Gunshot_pathetic.ogg' // Rubber shots have less powder in the casing.
|
||||
|
||||
/* shotgun projectiles */
|
||||
|
||||
/obj/item/projectile/bullet/shotgun
|
||||
name = "slug"
|
||||
fire_sound = 'sound/weapons/Gunshot_shotgun.ogg'
|
||||
damage = 50
|
||||
armor_penetration = 20
|
||||
hud_state = "shotgun_slug"
|
||||
hud_state_empty = "shotgun_empty"
|
||||
|
||||
/obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets
|
||||
name = "beanbag"
|
||||
damage = 20
|
||||
agony = 60
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "shotgun_beanbag"
|
||||
|
||||
//Should do about 80 damage at 1 tile distance (adjacent), and 50 damage at 3 tiles distance.
|
||||
//Overall less damage than slugs in exchange for more damage at very close range and more embedding
|
||||
/obj/item/projectile/bullet/pellet/shotgun
|
||||
name = "shrapnel"
|
||||
fire_sound = 'sound/weapons/Gunshot_shotgun.ogg'
|
||||
damage = 13
|
||||
pellets = 6
|
||||
range_step = 1
|
||||
spread_step = 10
|
||||
hud_state = "shotgun_buckshot"
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun/flak
|
||||
damage = 2 //The main weapon using these fires four at a time, usually with different destinations. Usually.
|
||||
range_step = 2
|
||||
spread_step = 30
|
||||
armor_penetration = 10
|
||||
hud_state = "shotgun_flechette"
|
||||
|
||||
//EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used
|
||||
/obj/item/projectile/bullet/shotgun/ion
|
||||
name = "ion slug"
|
||||
fire_sound = 'sound/weapons/Laser.ogg' // Really? We got nothing better than this?
|
||||
damage = 15
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
check_armour = "melee"
|
||||
hud_state = "shotgun_ion"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/shotgun/ion/on_hit(var/atom/target, var/blocked = 0)
|
||||
..()
|
||||
empulse(target, 0, 0, 0, 0) //Only affects what it hits
|
||||
return 1
|
||||
|
||||
|
||||
/* "Rifle" rounds */
|
||||
|
||||
/obj/item/projectile/bullet/rifle
|
||||
fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg'
|
||||
armor_penetration = 15
|
||||
penetrating = 1
|
||||
hud_state = "rifle"
|
||||
hud_state_empty = "rifle_empty"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762
|
||||
fire_sound = 'sound/weapons/Gunshot_heavy.ogg'
|
||||
damage = 35
|
||||
hud_state = "rifle_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/sniper // Hitscan specifically for sniper ammo; to be implimented at a later date, probably for the SVD. -Ace
|
||||
fire_sound = 'sound/weapons/Gunshot_sniper.ogg'
|
||||
hitscan = 1 //so the ammo isn't useless as a sniper weapon
|
||||
hud_state = "hivelo"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/ap
|
||||
damage = 30
|
||||
armor_penetration = 50 // At 30 or more armor, this will do more damage than standard rounds.
|
||||
hud_state = "rifle_ap"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/hp
|
||||
damage = 40
|
||||
armor_penetration = -50
|
||||
penetrating = 0
|
||||
hud_state = "hivelo_iff"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a762/hunter // Optimized for killing simple animals and not people, because Balance(tm)
|
||||
damage = 20
|
||||
SA_bonus_damage = 50 // 70 total on animals.
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
hud_state = "rifle_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545
|
||||
fire_sound = 'sound/weapons/Gunshot_light.ogg'
|
||||
damage = 25
|
||||
hud_state = "rifle"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545/ap
|
||||
damage = 20
|
||||
armor_penetration = 50 // At 40 or more armor, this will do more damage than standard rounds.
|
||||
hud_state = "rifle_ap"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545/hp
|
||||
damage = 35
|
||||
armor_penetration = -50
|
||||
penetrating = 0
|
||||
hud_state = "hivelo_iff"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a545/hunter
|
||||
damage = 15
|
||||
SA_bonus_damage = 35 // 50 total on animals.
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
hud_state = "rifle_heavy"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a145 // 14.5�114mm is bigger than a .50 BMG round.
|
||||
fire_sound = 'sound/weapons/Gunshot_cannon.ogg' // This is literally an anti-tank rifle caliber. It better sound like a fucking cannon.
|
||||
damage = 80
|
||||
stun = 3
|
||||
weaken = 3
|
||||
penetrating = 5
|
||||
armor_penetration = 80
|
||||
hitscan = 1 //so the PTR isn't useless as a sniper weapon
|
||||
hud_state = "sniper"
|
||||
|
||||
icon_state = "bullet_alt"
|
||||
tracer_type = /obj/effect/projectile/tracer/cannon
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a145/highvel
|
||||
damage = 50
|
||||
stun = 1
|
||||
weaken = 0
|
||||
penetrating = 15
|
||||
armor_penetration = 90
|
||||
hud_state = "sniper_flak"
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a44rifle
|
||||
fire_sound = 'sound/weapons/gunshot4.ogg'
|
||||
damage = 50
|
||||
hud_state = "revolver"
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
/obj/item/projectile/bullet/suffocationbullet//How does this even work?
|
||||
name = "co bullet"
|
||||
damage = 20
|
||||
damage_type = OXY
|
||||
hud_state = "pistol_tranq"
|
||||
|
||||
/obj/item/projectile/bullet/cyanideround
|
||||
name = "poison bullet"
|
||||
damage = 40
|
||||
damage_type = TOX
|
||||
hud_state = "pistol_tranq"
|
||||
|
||||
/obj/item/projectile/bullet/burstbullet
|
||||
name = "exploding bullet"
|
||||
fire_sound = 'sound/effects/Explosion1.ogg'
|
||||
damage = 20
|
||||
embed_chance = 0
|
||||
edge = TRUE
|
||||
hud_state = "pistol_fire"
|
||||
|
||||
/obj/item/projectile/bullet/burstbullet/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isturf(target))
|
||||
explosion(target, -1, 0, 2)
|
||||
..()
|
||||
|
||||
/* Incendiary */
|
||||
|
||||
/obj/item/projectile/bullet/incendiary
|
||||
name = "incendiary bullet"
|
||||
icon_state = "bullet_alt"
|
||||
damage = 15
|
||||
damage_type = BURN
|
||||
incendiary = 0.5
|
||||
flammability = 2
|
||||
hud_state = "pistol_fire"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower
|
||||
name = "ball of fire"
|
||||
desc = "Don't stand in the fire."
|
||||
icon_state = "fireball"
|
||||
damage = 10
|
||||
embed_chance = 0
|
||||
incendiary = 2
|
||||
flammability = 4
|
||||
agony = 30
|
||||
range = 4
|
||||
vacuum_traversal = 0
|
||||
hud_state = "flame"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/after_move()
|
||||
..()
|
||||
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
for(var/obj/effect/plant/Victim in T)
|
||||
if(prob(max(20, 100 - (Victim.seed.get_trait(TRAIT_ENDURANCE))))) // Chance to immediately kill a vine or rampant growth, minimum of 20%.
|
||||
Victim.die_off()
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/large
|
||||
damage = 5
|
||||
incendiary = 3
|
||||
flammability = 2
|
||||
range = 6
|
||||
hud_state = "flame"
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/tiny
|
||||
damage = 2
|
||||
incendiary = 0
|
||||
flammability = 2
|
||||
modifier_type_to_apply = /datum/modifier/fire/stack_managed/weak
|
||||
modifier_duration = 20 SECONDS
|
||||
range = 6
|
||||
agony = 0
|
||||
hud_state = "flame"
|
||||
|
||||
/* Practice rounds and blanks */
|
||||
|
||||
/obj/item/projectile/bullet/practice
|
||||
damage = 5
|
||||
hud_state = "smg_light"
|
||||
|
||||
/obj/item/projectile/bullet/pistol/cap // Just the primer, such as a cap gun.
|
||||
name = "cap"
|
||||
damage_type = HALLOSS
|
||||
fire_sound = 'sound/effects/snap.ogg'
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
hud_state = "monkey"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/pistol/cap/process()
|
||||
loc = null
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/bullet/blank
|
||||
name = "blank"
|
||||
damage_type = HALLOSS
|
||||
fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' // Blanks still make loud noises.
|
||||
damage = 0
|
||||
nodamage = 1
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
hud_state = "smg_light"
|
||||
|
||||
/* BB Rounds */
|
||||
/obj/item/projectile/bullet/bb // Generic single BB
|
||||
name = "BB"
|
||||
damage = 0
|
||||
agony = 0
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
silenced = TRUE
|
||||
hud_state = "pistol_light"
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun/bb // Shotgun
|
||||
name = "BB"
|
||||
damage = 0
|
||||
agony = 0
|
||||
embed_chance = 0
|
||||
sharp = FALSE
|
||||
pellets = 6
|
||||
range_step = 1
|
||||
spread_step = 10
|
||||
silenced = TRUE
|
||||
hud_state = "pistol_light"
|
||||
|
||||
/* toy projectiles */
|
||||
/obj/item/projectile/bullet/cap
|
||||
name = "cap"
|
||||
desc = "SNAP!"
|
||||
damage = 0 // It's a damn toy.
|
||||
embed_chance = 0
|
||||
nodamage = TRUE
|
||||
sharp = FALSE
|
||||
damage_type = HALLOSS
|
||||
impact_effect_type = null
|
||||
fire_sound = 'sound/effects/snap.ogg'
|
||||
combustion = FALSE
|
||||
hud_state = "pistol_light"
|
||||
|
||||
/obj/item/projectile/bullet/cap/process()
|
||||
loc = null
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart
|
||||
name = "foam dart"
|
||||
desc = "I hope you're wearing eye protection."
|
||||
damage = 0 // It's a damn toy.
|
||||
embed_chance = 0
|
||||
nodamage = TRUE
|
||||
sharp = FALSE
|
||||
damage_type = HALLOSS
|
||||
impact_effect_type = null
|
||||
fire_sound = 'sound/items/syringeproj.ogg'
|
||||
combustion = FALSE
|
||||
icon = 'icons/obj/gun_toy.dmi'
|
||||
icon_state = "foamdart_proj"
|
||||
range = 15
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart/on_impact(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart(get_turf(loc))
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart/on_range(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart(get_turf(loc))
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart_riot
|
||||
name = "riot foam dart"
|
||||
desc = "Whose smart idea was it to use toys as crowd control? Ages 18 and up."
|
||||
damage = 0 // It's a damn toy.
|
||||
embed_chance = 0
|
||||
agony = 50 // The riot part of the riot dart
|
||||
nodamage = TRUE
|
||||
sharp = FALSE
|
||||
damage_type = HALLOSS
|
||||
impact_effect_type = null
|
||||
fire_sound = 'sound/items/syringeproj.ogg'
|
||||
combustion = FALSE
|
||||
icon = 'icons/obj/gun_toy.dmi'
|
||||
icon_state = "foamdart_riot_proj"
|
||||
range = 15
|
||||
hud_state = "grenade_he"
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart_riot/on_impact(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart/riot(get_turf(loc))
|
||||
|
||||
/obj/item/projectile/bullet/foam_dart_riot/on_range(var/atom/A)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(istype(T))
|
||||
new /obj/item/ammo_casing/afoam_dart/riot(get_turf(loc))
|
||||
@@ -1,101 +1,101 @@
|
||||
/obj/item/projectile/change
|
||||
name = "bolt of change"
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/change/on_hit(var/atom/change)
|
||||
wabbajack(change)
|
||||
|
||||
/obj/item/projectile/change/proc/wabbajack(var/mob/M)
|
||||
if(istype(M, /mob/living) && M.stat != DEAD)
|
||||
if(M.transforming)
|
||||
return
|
||||
if(M.has_brain_worms())
|
||||
return //Borer stuff - RR
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/Robot = M
|
||||
if(Robot.mmi)
|
||||
qdel(Robot.mmi)
|
||||
else
|
||||
for(var/obj/item/W in M)
|
||||
if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something
|
||||
qdel(W)
|
||||
continue
|
||||
M.drop_from_inventory(W)
|
||||
|
||||
var/mob/living/new_mob
|
||||
|
||||
var/options = list("robot", "slime")
|
||||
for(var/t in GLOB.all_species)
|
||||
options += t
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species)
|
||||
options -= H.species.name
|
||||
else if(isrobot(M))
|
||||
options -= "robot"
|
||||
else if(isslime(M))
|
||||
options -= "slime"
|
||||
|
||||
var/randomize = pick(options)
|
||||
switch(randomize)
|
||||
if("robot")
|
||||
new_mob = new /mob/living/silicon/robot(M.loc)
|
||||
new_mob.gender = M.gender
|
||||
new_mob.invisibility = 0
|
||||
new_mob.job = "Cyborg"
|
||||
var/mob/living/silicon/robot/Robot = new_mob
|
||||
Robot.mmi = new /obj/item/device/mmi(new_mob)
|
||||
Robot.mmi.transfer_identity(M) //Does not transfer key/client.
|
||||
if("slime")
|
||||
new_mob = new /mob/living/simple_mob/slime/xenobio(M.loc)
|
||||
new_mob.universal_speak = 1
|
||||
else
|
||||
var/mob/living/carbon/human/H
|
||||
if(ishuman(M))
|
||||
H = M
|
||||
else
|
||||
new_mob = new /mob/living/carbon/human(M.loc)
|
||||
H = new_mob
|
||||
|
||||
if(M.gender == MALE)
|
||||
H.gender = MALE
|
||||
H.name = pick(first_names_male)
|
||||
else if(M.gender == FEMALE)
|
||||
H.gender = FEMALE
|
||||
H.name = pick(first_names_female)
|
||||
else
|
||||
H.gender = NEUTER
|
||||
H.name = pick(first_names_female|first_names_male)
|
||||
|
||||
H.name += " [pick(last_names)]"
|
||||
H.real_name = H.name
|
||||
|
||||
H.set_species(randomize)
|
||||
H.universal_speak = 1
|
||||
var/datum/preferences/A = new() //Randomize appearance for the human
|
||||
A.randomize_appearance_and_body_for(H)
|
||||
|
||||
if(new_mob)
|
||||
for (var/spell/S in M.spell_list)
|
||||
new_mob.add_spell(new S.type)
|
||||
|
||||
new_mob.a_intent = "hurt"
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = M.key
|
||||
|
||||
to_chat(new_mob, "<span class='warning'>Your form morphs into that of \a [lowertext(randomize)].</span>")
|
||||
|
||||
qdel(M)
|
||||
return
|
||||
else
|
||||
to_chat(M, "<span class='warning'>Your form morphs into that of \a [lowertext(randomize)].</span>")
|
||||
/obj/item/projectile/change
|
||||
name = "bolt of change"
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/change/on_hit(var/atom/change)
|
||||
wabbajack(change)
|
||||
|
||||
/obj/item/projectile/change/proc/wabbajack(var/mob/M)
|
||||
if(istype(M, /mob/living) && M.stat != DEAD)
|
||||
if(M.transforming)
|
||||
return
|
||||
if(M.has_brain_worms())
|
||||
return //Borer stuff - RR
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/Robot = M
|
||||
if(Robot.mmi)
|
||||
qdel(Robot.mmi)
|
||||
else
|
||||
for(var/obj/item/W in M)
|
||||
if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something
|
||||
qdel(W)
|
||||
continue
|
||||
M.drop_from_inventory(W)
|
||||
|
||||
var/mob/living/new_mob
|
||||
|
||||
var/options = list("robot", "slime")
|
||||
for(var/t in GLOB.all_species)
|
||||
options += t
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species)
|
||||
options -= H.species.name
|
||||
else if(isrobot(M))
|
||||
options -= "robot"
|
||||
else if(isslime(M))
|
||||
options -= "slime"
|
||||
|
||||
var/randomize = pick(options)
|
||||
switch(randomize)
|
||||
if("robot")
|
||||
new_mob = new /mob/living/silicon/robot(M.loc)
|
||||
new_mob.gender = M.gender
|
||||
new_mob.invisibility = 0
|
||||
new_mob.job = "Cyborg"
|
||||
var/mob/living/silicon/robot/Robot = new_mob
|
||||
Robot.mmi = new /obj/item/device/mmi(new_mob)
|
||||
Robot.mmi.transfer_identity(M) //Does not transfer key/client.
|
||||
if("slime")
|
||||
new_mob = new /mob/living/simple_mob/slime/xenobio(M.loc)
|
||||
new_mob.universal_speak = 1
|
||||
else
|
||||
var/mob/living/carbon/human/H
|
||||
if(ishuman(M))
|
||||
H = M
|
||||
else
|
||||
new_mob = new /mob/living/carbon/human(M.loc)
|
||||
H = new_mob
|
||||
|
||||
if(M.gender == MALE)
|
||||
H.gender = MALE
|
||||
H.name = pick(first_names_male)
|
||||
else if(M.gender == FEMALE)
|
||||
H.gender = FEMALE
|
||||
H.name = pick(first_names_female)
|
||||
else
|
||||
H.gender = NEUTER
|
||||
H.name = pick(first_names_female|first_names_male)
|
||||
|
||||
H.name += " [pick(last_names)]"
|
||||
H.real_name = H.name
|
||||
|
||||
H.set_species(randomize)
|
||||
H.universal_speak = 1
|
||||
var/datum/preferences/A = new() //Randomize appearance for the human
|
||||
A.randomize_appearance_and_body_for(H)
|
||||
|
||||
if(new_mob)
|
||||
for (var/spell/S in M.spell_list)
|
||||
new_mob.add_spell(new S.type)
|
||||
|
||||
new_mob.a_intent = "hurt"
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = M.key
|
||||
|
||||
to_chat(new_mob, "<span class='warning'>Your form morphs into that of \a [lowertext(randomize)].</span>")
|
||||
|
||||
qdel(M)
|
||||
return
|
||||
else
|
||||
to_chat(M, "<span class='warning'>Your form morphs into that of \a [lowertext(randomize)].</span>")
|
||||
return
|
||||
@@ -1,337 +1,337 @@
|
||||
/obj/item/projectile/energy
|
||||
name = "energy"
|
||||
icon_state = "spark"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
check_armour = "energy"
|
||||
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
hitsound = 'sound/weapons/zapbang.ogg'
|
||||
hud_state = "plasma"
|
||||
hud_state_empty = "battery_empty"
|
||||
|
||||
var/flash_strength = 10
|
||||
|
||||
//releases a burst of light on impact or after travelling a distance
|
||||
/obj/item/projectile/energy/flash
|
||||
name = "chemical shell"
|
||||
icon_state = "bullet"
|
||||
fire_sound = 'sound/weapons/gunshot_pathetic.ogg'
|
||||
hitsound_wall = null
|
||||
damage = 5
|
||||
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
var/flash_range = 0
|
||||
var/brightness = 7
|
||||
var/light_colour = "#ffffff"
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/on_impact(var/atom/A)
|
||||
var/turf/T = flash_range? src.loc : get_turf(A)
|
||||
if(!istype(T)) return
|
||||
|
||||
//blind adjacent people
|
||||
for (var/mob/living/carbon/M in viewers(T, flash_range))
|
||||
if(M.eyecheck() < 1)
|
||||
M.flash_eyes()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
flash_strength *= H.species.flash_mod
|
||||
|
||||
if(flash_strength > 0)
|
||||
H.Confuse(flash_strength + 5)
|
||||
H.Blind(flash_strength)
|
||||
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
|
||||
H.adjustHalLoss(22 * (flash_strength / 5)) // Five flashes to stun. Bit weaker than melee flashes due to being ranged.
|
||||
|
||||
//snap pop
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
src.visible_message("<span class='warning'>\The [src] explodes in a bright flash!</span>")
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(2, 1, T)
|
||||
sparks.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows
|
||||
new /obj/effect/effect/smoke/illumination(T, 5, brightness, brightness, light_colour)
|
||||
|
||||
//blinds people like the flash round, but can also be used for temporary illumination
|
||||
/obj/item/projectile/energy/flash/flare
|
||||
fire_sound = 'sound/weapons/grenade_launcher.ogg'
|
||||
damage = 10
|
||||
flash_range = 1
|
||||
brightness = 15
|
||||
flash_strength = 20
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/flare/on_impact(var/atom/A)
|
||||
light_colour = pick("#e58775", "#ffffff", "#90ff90", "#a09030")
|
||||
|
||||
..() //initial flash
|
||||
|
||||
//residual illumination
|
||||
new /obj/effect/effect/smoke/illumination(src.loc, rand(190,240) SECONDS, range=8, power=3, color=light_colour) //same lighting power as flare
|
||||
|
||||
/obj/item/projectile/energy/electrode
|
||||
name = "electrode"
|
||||
icon_state = "spark"
|
||||
fire_sound = 'sound/weapons/Gunshot2.ogg'
|
||||
taser_effect = 1
|
||||
agony = 40
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#FFFFFF"
|
||||
hud_state = "taser"
|
||||
//Damage will be handled on the MOB side, to prevent window shattering.
|
||||
|
||||
/obj/item/projectile/energy/electrode/strong
|
||||
agony = 55
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/electrode/stunshot
|
||||
name = "stunshot"
|
||||
damage = 5
|
||||
agony = 80
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/electrode/stunshot/strong
|
||||
name = "stunshot"
|
||||
icon_state = "bullet"
|
||||
damage = 10
|
||||
taser_effect = 1
|
||||
agony = 100
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/declone
|
||||
name = "declone"
|
||||
icon_state = "declone"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
nodamage = 1
|
||||
damage_type = CLONE
|
||||
irradiate = 40
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#33CC00"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
|
||||
combustion = FALSE
|
||||
hud_state = "plasma_pistol"
|
||||
|
||||
/obj/item/projectile/energy/excavate
|
||||
name = "kinetic blast"
|
||||
icon_state = "kinetic_blast"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
damage_type = BRUTE
|
||||
damage = 30
|
||||
armor_penetration = 60
|
||||
excavation_amount = 200
|
||||
check_armour = "melee"
|
||||
|
||||
vacuum_traversal = 0
|
||||
combustion = FALSE
|
||||
hud_state = "plasma_blast"
|
||||
|
||||
/obj/item/projectile/energy/excavate/weak
|
||||
damage = 15
|
||||
excavation_amount = 100
|
||||
|
||||
/obj/item/projectile/energy/dart
|
||||
name = "dart"
|
||||
icon_state = "toxin"
|
||||
damage = 5
|
||||
damage_type = TOX
|
||||
agony = 120
|
||||
check_armour = "energy"
|
||||
hud_state = "pistol_tranq"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/bolt
|
||||
name = "bolt"
|
||||
icon_state = "cbbolt"
|
||||
damage = 10
|
||||
damage_type = TOX
|
||||
agony = 40
|
||||
stutter = 10
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bolt/large
|
||||
name = "largebolt"
|
||||
damage = 20
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bow
|
||||
name = "engergy bolt"
|
||||
icon_state = "cbbolt"
|
||||
damage = 20
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bow/heavy
|
||||
damage = 30
|
||||
icon_state = "cbbolt"
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bow/stun
|
||||
name = "stun bolt"
|
||||
agony = 30
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/acid //Slightly up-gunned (Read: The thing does agony and checks bio resist) variant of the simple alien mob's projectile, for queens and sentinels.
|
||||
name = "acidic spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 30
|
||||
damage_type = BURN
|
||||
agony = 10
|
||||
check_armour = "bio"
|
||||
armor_penetration = 25 // It's acid
|
||||
hitsound_wall = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hitsound = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hud_state = "electrothermal"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/neurotoxin
|
||||
name = "neurotoxic spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 0
|
||||
damage_type = BIOACID
|
||||
agony = 80
|
||||
check_armour = "bio"
|
||||
armor_penetration = 25 // It's acid-based
|
||||
hitsound_wall = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hitsound = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hud_state = "electrothermal"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/neurotoxin/toxic //New alien mob projectile to match the player-variant's projectiles.
|
||||
name = "neurotoxic spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 20
|
||||
damage_type = BIOACID
|
||||
agony = 20
|
||||
hud_state = "electrothermal"
|
||||
check_armour = "bio"
|
||||
armor_penetration = 25 // It's acid-based
|
||||
|
||||
/obj/item/projectile/energy/phoron
|
||||
name = "phoron bolt"
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 20
|
||||
damage_type = TOX
|
||||
irradiate = 20
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#33CC00"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
hud_state = "plasma_rifle"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/plasmastun
|
||||
name = "plasma pulse"
|
||||
icon_state = "plasma_stun"
|
||||
fire_sound = 'sound/weapons/blaster.ogg'
|
||||
armor_penetration = 10
|
||||
range = 4
|
||||
damage = 5
|
||||
agony = 55
|
||||
damage_type = BURN
|
||||
vacuum_traversal = 0 //Projectile disappears in empty space
|
||||
hud_state = "plasma_rifle_blast"
|
||||
|
||||
/obj/item/projectile/energy/plasmastun/proc/bang(var/mob/living/carbon/M)
|
||||
|
||||
to_chat(M, "<span class='danger'>You hear a loud roar.</span>")
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
var/ear_safety = 0
|
||||
ear_safety = M.get_ear_protection()
|
||||
if(ear_safety == 1)
|
||||
M.Confuse(150)
|
||||
else if (ear_safety > 1)
|
||||
M.Confuse(30)
|
||||
else if (!ear_safety)
|
||||
M.Stun(10)
|
||||
M.Weaken(2)
|
||||
M.ear_damage += rand(1, 10)
|
||||
M.ear_deaf = max(M.ear_deaf,15)
|
||||
if (M.ear_damage >= 15)
|
||||
to_chat(M, "<span class='danger'>Your ears start to ring badly!</span>")
|
||||
if (prob(M.ear_damage - 5))
|
||||
to_chat(M, "<span class='danger'>You can't hear anything!</span>")
|
||||
M.sdisabilities |= DEAF
|
||||
else
|
||||
if (M.ear_damage >= 5)
|
||||
to_chat(M, "<span class='danger'>Your ears start to ring!</span>")
|
||||
M.update_icons() //Just to apply matrix transform for laying asap
|
||||
|
||||
/obj/item/projectile/energy/plasmastun/on_hit(var/atom/target)
|
||||
bang(target)
|
||||
. = ..()
|
||||
|
||||
/obj/item/projectile/energy/blue_pellet
|
||||
name = "suppressive pellet"
|
||||
icon_state = "blue_pellet"
|
||||
fire_sound = 'sound/weapons/Laser4.ogg'
|
||||
damage = 5
|
||||
armor_penetration = 75
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
damage_type = BURN
|
||||
check_armour = "energy"
|
||||
light_color = "#00AAFF"
|
||||
|
||||
embed_chance = 0
|
||||
muzzle_type = /obj/effect/projectile/muzzle/pulse
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
hud_state = "plasma_sphere"
|
||||
|
||||
/obj/item/projectile/energy/phase
|
||||
name = "phase wave"
|
||||
icon_state = "phase"
|
||||
range = 6
|
||||
damage = 5
|
||||
SA_bonus_damage = 45 // 50 total on animals
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/phase/light
|
||||
range = 4
|
||||
SA_bonus_damage = 35 // 40 total on animals
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/phase/heavy
|
||||
range = 8
|
||||
SA_bonus_damage = 55 // 60 total on animals
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/phase/heavy/cannon
|
||||
range = 10
|
||||
damage = 15
|
||||
SA_bonus_damage = 60 // 75 total on animals
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/electrode/strong
|
||||
agony = 70
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy
|
||||
flash_strength = 10
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/flash
|
||||
flash_range = 1
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/strong
|
||||
name = "chemical shell"
|
||||
icon_state = "bullet"
|
||||
damage = 10
|
||||
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
flash_strength = 15
|
||||
brightness = 15
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/flare
|
||||
flash_range = 2
|
||||
hud_state = "grenade_dummy"
|
||||
/obj/item/projectile/energy
|
||||
name = "energy"
|
||||
icon_state = "spark"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
check_armour = "energy"
|
||||
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
hitsound = 'sound/weapons/zapbang.ogg'
|
||||
hud_state = "plasma"
|
||||
hud_state_empty = "battery_empty"
|
||||
|
||||
var/flash_strength = 10
|
||||
|
||||
//releases a burst of light on impact or after travelling a distance
|
||||
/obj/item/projectile/energy/flash
|
||||
name = "chemical shell"
|
||||
icon_state = "bullet"
|
||||
fire_sound = 'sound/weapons/gunshot_pathetic.ogg'
|
||||
hitsound_wall = null
|
||||
damage = 5
|
||||
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
var/flash_range = 0
|
||||
var/brightness = 7
|
||||
var/light_colour = "#ffffff"
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/on_impact(var/atom/A)
|
||||
var/turf/T = flash_range? src.loc : get_turf(A)
|
||||
if(!istype(T)) return
|
||||
|
||||
//blind adjacent people
|
||||
for (var/mob/living/carbon/M in viewers(T, flash_range))
|
||||
if(M.eyecheck() < 1)
|
||||
M.flash_eyes()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
flash_strength *= H.species.flash_mod
|
||||
|
||||
if(flash_strength > 0)
|
||||
H.Confuse(flash_strength + 5)
|
||||
H.Blind(flash_strength)
|
||||
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
|
||||
H.adjustHalLoss(22 * (flash_strength / 5)) // Five flashes to stun. Bit weaker than melee flashes due to being ranged.
|
||||
|
||||
//snap pop
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
src.visible_message("<span class='warning'>\The [src] explodes in a bright flash!</span>")
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(2, 1, T)
|
||||
sparks.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows
|
||||
new /obj/effect/effect/smoke/illumination(T, 5, brightness, brightness, light_colour)
|
||||
|
||||
//blinds people like the flash round, but can also be used for temporary illumination
|
||||
/obj/item/projectile/energy/flash/flare
|
||||
fire_sound = 'sound/weapons/grenade_launcher.ogg'
|
||||
damage = 10
|
||||
flash_range = 1
|
||||
brightness = 15
|
||||
flash_strength = 20
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/flare/on_impact(var/atom/A)
|
||||
light_colour = pick("#e58775", "#ffffff", "#90ff90", "#a09030")
|
||||
|
||||
..() //initial flash
|
||||
|
||||
//residual illumination
|
||||
new /obj/effect/effect/smoke/illumination(src.loc, rand(190,240) SECONDS, range=8, power=3, color=light_colour) //same lighting power as flare
|
||||
|
||||
/obj/item/projectile/energy/electrode
|
||||
name = "electrode"
|
||||
icon_state = "spark"
|
||||
fire_sound = 'sound/weapons/Gunshot2.ogg'
|
||||
taser_effect = 1
|
||||
agony = 40
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#FFFFFF"
|
||||
hud_state = "taser"
|
||||
//Damage will be handled on the MOB side, to prevent window shattering.
|
||||
|
||||
/obj/item/projectile/energy/electrode/strong
|
||||
agony = 55
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/electrode/stunshot
|
||||
name = "stunshot"
|
||||
damage = 5
|
||||
agony = 80
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/electrode/stunshot/strong
|
||||
name = "stunshot"
|
||||
icon_state = "bullet"
|
||||
damage = 10
|
||||
taser_effect = 1
|
||||
agony = 100
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/declone
|
||||
name = "declone"
|
||||
icon_state = "declone"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
nodamage = 1
|
||||
damage_type = CLONE
|
||||
irradiate = 40
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#33CC00"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
|
||||
combustion = FALSE
|
||||
hud_state = "plasma_pistol"
|
||||
|
||||
/obj/item/projectile/energy/excavate
|
||||
name = "kinetic blast"
|
||||
icon_state = "kinetic_blast"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
damage_type = BRUTE
|
||||
damage = 30
|
||||
armor_penetration = 60
|
||||
excavation_amount = 200
|
||||
check_armour = "melee"
|
||||
|
||||
vacuum_traversal = 0
|
||||
combustion = FALSE
|
||||
hud_state = "plasma_blast"
|
||||
|
||||
/obj/item/projectile/energy/excavate/weak
|
||||
damage = 15
|
||||
excavation_amount = 100
|
||||
|
||||
/obj/item/projectile/energy/dart
|
||||
name = "dart"
|
||||
icon_state = "toxin"
|
||||
damage = 5
|
||||
damage_type = TOX
|
||||
agony = 120
|
||||
check_armour = "energy"
|
||||
hud_state = "pistol_tranq"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/bolt
|
||||
name = "bolt"
|
||||
icon_state = "cbbolt"
|
||||
damage = 10
|
||||
damage_type = TOX
|
||||
agony = 40
|
||||
stutter = 10
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bolt/large
|
||||
name = "largebolt"
|
||||
damage = 20
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bow
|
||||
name = "engergy bolt"
|
||||
icon_state = "cbbolt"
|
||||
damage = 20
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bow/heavy
|
||||
damage = 30
|
||||
icon_state = "cbbolt"
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/bow/stun
|
||||
name = "stun bolt"
|
||||
agony = 30
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/acid //Slightly up-gunned (Read: The thing does agony and checks bio resist) variant of the simple alien mob's projectile, for queens and sentinels.
|
||||
name = "acidic spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 30
|
||||
damage_type = BURN
|
||||
agony = 10
|
||||
check_armour = "bio"
|
||||
armor_penetration = 25 // It's acid
|
||||
hitsound_wall = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hitsound = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hud_state = "electrothermal"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/neurotoxin
|
||||
name = "neurotoxic spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 0
|
||||
damage_type = BIOACID
|
||||
agony = 80
|
||||
check_armour = "bio"
|
||||
armor_penetration = 25 // It's acid-based
|
||||
hitsound_wall = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hitsound = 'sound/weapons/effects/alien_spit_wall.ogg'
|
||||
hud_state = "electrothermal"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/neurotoxin/toxic //New alien mob projectile to match the player-variant's projectiles.
|
||||
name = "neurotoxic spit"
|
||||
icon_state = "neurotoxin"
|
||||
damage = 20
|
||||
damage_type = BIOACID
|
||||
agony = 20
|
||||
hud_state = "electrothermal"
|
||||
check_armour = "bio"
|
||||
armor_penetration = 25 // It's acid-based
|
||||
|
||||
/obj/item/projectile/energy/phoron
|
||||
name = "phoron bolt"
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 20
|
||||
damage_type = TOX
|
||||
irradiate = 20
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#33CC00"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
hud_state = "plasma_rifle"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/energy/plasmastun
|
||||
name = "plasma pulse"
|
||||
icon_state = "plasma_stun"
|
||||
fire_sound = 'sound/weapons/blaster.ogg'
|
||||
armor_penetration = 10
|
||||
range = 4
|
||||
damage = 5
|
||||
agony = 55
|
||||
damage_type = BURN
|
||||
vacuum_traversal = 0 //Projectile disappears in empty space
|
||||
hud_state = "plasma_rifle_blast"
|
||||
|
||||
/obj/item/projectile/energy/plasmastun/proc/bang(var/mob/living/carbon/M)
|
||||
|
||||
to_chat(M, "<span class='danger'>You hear a loud roar.</span>")
|
||||
playsound(src, 'sound/effects/bang.ogg', 50, 1)
|
||||
var/ear_safety = 0
|
||||
ear_safety = M.get_ear_protection()
|
||||
if(ear_safety == 1)
|
||||
M.Confuse(150)
|
||||
else if (ear_safety > 1)
|
||||
M.Confuse(30)
|
||||
else if (!ear_safety)
|
||||
M.Stun(10)
|
||||
M.Weaken(2)
|
||||
M.ear_damage += rand(1, 10)
|
||||
M.ear_deaf = max(M.ear_deaf,15)
|
||||
if (M.ear_damage >= 15)
|
||||
to_chat(M, "<span class='danger'>Your ears start to ring badly!</span>")
|
||||
if (prob(M.ear_damage - 5))
|
||||
to_chat(M, "<span class='danger'>You can't hear anything!</span>")
|
||||
M.sdisabilities |= DEAF
|
||||
else
|
||||
if (M.ear_damage >= 5)
|
||||
to_chat(M, "<span class='danger'>Your ears start to ring!</span>")
|
||||
M.update_icons() //Just to apply matrix transform for laying asap
|
||||
|
||||
/obj/item/projectile/energy/plasmastun/on_hit(var/atom/target)
|
||||
bang(target)
|
||||
. = ..()
|
||||
|
||||
/obj/item/projectile/energy/blue_pellet
|
||||
name = "suppressive pellet"
|
||||
icon_state = "blue_pellet"
|
||||
fire_sound = 'sound/weapons/Laser4.ogg'
|
||||
damage = 5
|
||||
armor_penetration = 75
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
damage_type = BURN
|
||||
check_armour = "energy"
|
||||
light_color = "#00AAFF"
|
||||
|
||||
embed_chance = 0
|
||||
muzzle_type = /obj/effect/projectile/muzzle/pulse
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
hud_state = "plasma_sphere"
|
||||
|
||||
/obj/item/projectile/energy/phase
|
||||
name = "phase wave"
|
||||
icon_state = "phase"
|
||||
range = 6
|
||||
damage = 5
|
||||
SA_bonus_damage = 45 // 50 total on animals
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/phase/light
|
||||
range = 4
|
||||
SA_bonus_damage = 35 // 40 total on animals
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/phase/heavy
|
||||
range = 8
|
||||
SA_bonus_damage = 55 // 60 total on animals
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/phase/heavy/cannon
|
||||
range = 10
|
||||
damage = 15
|
||||
SA_bonus_damage = 60 // 75 total on animals
|
||||
hud_state = "laser_heat"
|
||||
|
||||
/obj/item/projectile/energy/electrode/strong
|
||||
agony = 70
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy
|
||||
flash_strength = 10
|
||||
hud_state = "taser"
|
||||
|
||||
/obj/item/projectile/energy/flash
|
||||
flash_range = 1
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/strong
|
||||
name = "chemical shell"
|
||||
icon_state = "bullet"
|
||||
damage = 10
|
||||
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
flash_strength = 15
|
||||
brightness = 15
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
/obj/item/projectile/energy/flash/flare
|
||||
flash_range = 2
|
||||
hud_state = "grenade_dummy"
|
||||
|
||||
@@ -1,364 +1,364 @@
|
||||
/obj/item/projectile/ion
|
||||
name = "ion bolt"
|
||||
icon_state = "ion"
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#55AAFF"
|
||||
hud_state = "plasma_blast"
|
||||
hud_state_empty = "battery_empty"
|
||||
|
||||
combustion = FALSE
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
hitsound = 'sound/weapons/ionrifle.ogg'
|
||||
|
||||
var/sev1_range = 0
|
||||
var/sev2_range = 1
|
||||
var/sev3_range = 1
|
||||
var/sev4_range = 1
|
||||
|
||||
/obj/item/projectile/ion/on_impact(var/atom/target)
|
||||
empulse(target, sev1_range, sev2_range, sev3_range, sev4_range)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/ion/small
|
||||
sev1_range = -1
|
||||
sev2_range = 0
|
||||
sev3_range = 0
|
||||
sev4_range = 1
|
||||
|
||||
/obj/item/projectile/ion/pistol
|
||||
sev1_range = 0
|
||||
sev2_range = 0
|
||||
sev3_range = 0
|
||||
sev4_range = 0
|
||||
|
||||
/obj/item/projectile/bullet/gyro
|
||||
name ="explosive bolt"
|
||||
icon_state= "bolter"
|
||||
damage = 50
|
||||
check_armour = "bullet"
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
hud_state = "rocket_fire"
|
||||
|
||||
/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
|
||||
explosion(target, -1, 0, 2)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/temp
|
||||
name = "freeze beam"
|
||||
icon_state = "ice_2"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
nodamage = 1
|
||||
check_armour = "energy" // It actually checks heat/cold protection.
|
||||
var/target_temperature = 50
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#55AAFF"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
hud_state = "water"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/temp/on_hit(atom/target, blocked = FALSE)
|
||||
..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
|
||||
var/protection = null
|
||||
var/potential_temperature_delta = null
|
||||
var/new_temperature = L.bodytemperature
|
||||
|
||||
if(target_temperature >= T20C) // Make it cold.
|
||||
protection = L.get_cold_protection(target_temperature)
|
||||
potential_temperature_delta = 75
|
||||
new_temperature = max(new_temperature - potential_temperature_delta, target_temperature)
|
||||
else // Make it hot.
|
||||
protection = L.get_heat_protection(target_temperature)
|
||||
potential_temperature_delta = 200 // Because spacemen temperature needs stupid numbers to actually hurt people.
|
||||
new_temperature = min(new_temperature + potential_temperature_delta, target_temperature)
|
||||
|
||||
var/temp_factor = abs(protection - 1)
|
||||
|
||||
new_temperature = round(new_temperature * temp_factor)
|
||||
L.bodytemperature = new_temperature
|
||||
//VOREStation Add Start - The last metroid has escaped from captivity, the galaxy is no longer safe.
|
||||
if(istype(L, /mob/living/simple_mob/vore/alienanimals/space_jellyfish) && target_temperature <= T0C)
|
||||
var/mob/living/simple_mob/vore/alienanimals/space_jellyfish/J = L
|
||||
J.adjustFireLoss(75)
|
||||
J.movement_cooldown *= 2
|
||||
//VOREStation Add End
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/temp/hot
|
||||
name = "heat beam"
|
||||
target_temperature = 1000
|
||||
hud_state = "flame"
|
||||
|
||||
combustion = TRUE
|
||||
|
||||
/obj/item/projectile/meteor
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "smallf"
|
||||
damage = 0
|
||||
damage_type = BRUTE
|
||||
nodamage = 1
|
||||
check_armour = "bullet"
|
||||
hud_state = "monkey"
|
||||
|
||||
/obj/item/projectile/meteor/Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return
|
||||
|
||||
sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits
|
||||
|
||||
if(src)//Do not add to this if() statement, otherwise the meteor won't delete them
|
||||
if(A)
|
||||
|
||||
A.ex_act(2)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 40, 1)
|
||||
|
||||
for(var/mob/M in range(10, src))
|
||||
if(!M.stat && !istype(M, /mob/living/silicon/ai))\
|
||||
shake_camera(M, 3, 1)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/projectile/energy/floramut
|
||||
name = "alpha somatoray"
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#33CC00"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
var/lasermod = 0
|
||||
combustion = FALSE
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/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((H.species.flags & IS_PLANT) && (M.nutrition < 500))
|
||||
if(prob(15))
|
||||
M.apply_effect((rand(30,80)),IRRADIATE)
|
||||
M.Weaken(5)
|
||||
var/datum/gender/TM = gender_datums[M.get_visible_gender()]
|
||||
for (var/mob/V in viewers(src))
|
||||
V.show_message(span_red("[M] writhes in pain as [TM.his] vacuoles boil."), 3, span_red("You hear the crunching of leaves."), 2)
|
||||
if(prob(35))
|
||||
// for (var/mob/V in viewers(src)) //Public messages commented out to prevent possible metaish genetics experimentation and stuff. - Cheridan
|
||||
// V.show_message("<font color='red'>[M] is mutated by the radiation beam.</font>", 3, "<font color='red'> You hear the snapping of twigs.</font>", 2)
|
||||
if(prob(80))
|
||||
randmutb(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
randmutg(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
M.adjustFireLoss(rand(5,15))
|
||||
M.show_message(span_red("The radiation beam singes you!"))
|
||||
// for (var/mob/V in viewers(src))
|
||||
// V.show_message("<font color='red'>[M] is singed by the radiation beam.</font>", 3, "<font color='red'> You hear the crackle of burning leaves.</font>", 2)
|
||||
else if(istype(target, /mob/living/carbon/))
|
||||
// for (var/mob/V in viewers(src))
|
||||
// V.show_message("The radiation beam dissipates harmlessly through [M]", 3)
|
||||
M.show_message(span_blue("The radiation beam dissipates harmlessly through your body."))
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/energy/floramut/gene
|
||||
name = "gamma somatoray"
|
||||
icon_state = "energy2"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
var/decl/plantgene/gene = null
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/florayield
|
||||
name = "beta somatoray"
|
||||
icon_state = "energy2"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#FFFFFF"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
var/lasermod = 0
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0)
|
||||
var/mob/living/M = target
|
||||
if(ishuman(target)) //These rays make plantmen fat.
|
||||
var/mob/living/carbon/human/H = M
|
||||
if((H.species.flags & IS_PLANT) && (M.nutrition < 500))
|
||||
M.adjust_nutrition(30)
|
||||
else if (istype(target, /mob/living/carbon/))
|
||||
M.show_message(span_blue("The radiation beam dissipates harmlessly through your body."))
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/projectile/beam/mindflayer
|
||||
name = "flayer ray"
|
||||
|
||||
combustion = FALSE
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
M.Confuse(rand(5,8))
|
||||
..()
|
||||
|
||||
/obj/item/projectile/chameleon
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
damage = 1 // stop trying to murderbone with a fake gun dumbass!!!
|
||||
embed_chance = 0 // nope
|
||||
nodamage = 1
|
||||
damage_type = HALLOSS
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bullet
|
||||
hud_state = "monkey"
|
||||
|
||||
/obj/item/projectile/bola
|
||||
name = "bola"
|
||||
icon_state = "bola"
|
||||
damage = 5
|
||||
embed_chance = 0 //Nada.
|
||||
damage_type = HALLOSS
|
||||
muzzle_type = null
|
||||
hud_state = "monkey"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/bola/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
var/obj/item/weapon/handcuffs/legcuffs/bola/B = new(src.loc)
|
||||
if(!B.place_legcuffs(M,firer))
|
||||
if(B)
|
||||
qdel(B)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/webball
|
||||
name = "ball of web"
|
||||
icon_state = "bola"
|
||||
damage = 10
|
||||
embed_chance = 0 //Nada.
|
||||
damage_type = BRUTE
|
||||
muzzle_type = null
|
||||
hud_state = "monkey"
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/webball/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isturf(target.loc))
|
||||
var/obj/effect/spider/stickyweb/W = locate() in get_turf(target)
|
||||
if(!W && prob(75))
|
||||
visible_message("<span class='danger'>\The [src] splatters a layer of web on \the [target]!</span>")
|
||||
new /obj/effect/spider/stickyweb(target.loc)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/tungsten
|
||||
name = "core of molten tungsten"
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/weapons/gauss_shoot.ogg'
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
damage = 70
|
||||
damage_type = BURN
|
||||
check_armour = "laser"
|
||||
light_range = 4
|
||||
light_power = 3
|
||||
light_color = "#3300ff"
|
||||
hud_state = "alloy_spike"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/tungsten
|
||||
tracer_type = /obj/effect/projectile/tracer/tungsten
|
||||
impact_type = /obj/effect/projectile/impact/tungsten
|
||||
|
||||
/obj/item/projectile/beam/tungsten/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.add_modifier(/datum/modifier/grievous_wounds, 30 SECONDS)
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
|
||||
var/target_armor = H.getarmor(def_zone, check_armour)
|
||||
var/obj/item/organ/external/target_limb = H.get_organ(def_zone)
|
||||
|
||||
var/armor_special = 0
|
||||
|
||||
if(target_armor >= 60)
|
||||
var/turf/T = get_step(H, pick(alldirs - src.dir))
|
||||
H.throw_at(T, 1, 1, src)
|
||||
H.apply_damage(20, BURN, def_zone)
|
||||
if(target_limb)
|
||||
armor_special = 2
|
||||
target_limb.fracture()
|
||||
|
||||
else if(target_armor >= 45)
|
||||
H.apply_damage(15, BURN, def_zone)
|
||||
if(target_limb)
|
||||
armor_special = 1
|
||||
target_limb.dislocate()
|
||||
|
||||
else if(target_armor >= 30)
|
||||
H.apply_damage(10, BURN, def_zone)
|
||||
if(prob(30) && target_limb)
|
||||
armor_special = 1
|
||||
target_limb.dislocate()
|
||||
|
||||
else if(target_armor >= 15)
|
||||
H.apply_damage(5, BURN, def_zone)
|
||||
if(prob(15) && target_limb)
|
||||
armor_special = 1
|
||||
target_limb.dislocate()
|
||||
|
||||
if(armor_special > 1)
|
||||
target.visible_message("<span class='cult'>\The [src] slams into \the [target]'s [target_limb], reverberating loudly!</span>")
|
||||
|
||||
else if(armor_special)
|
||||
target.visible_message("<span class='cult'>\The [src] slams into \the [target]'s [target_limb] with a low rumble!</span>")
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/tungsten/on_impact(var/atom/A)
|
||||
if(istype(A,/turf/simulated/shuttle/wall) || istype(A,/turf/simulated/wall) || (istype(A,/turf/simulated/mineral) && A.density) || istype(A,/obj/mecha) || istype(A,/obj/machinery/door))
|
||||
var/blast_dir = src.dir
|
||||
A.visible_message("<span class='danger'>\The [A] begins to glow!</span>")
|
||||
spawn(2 SECONDS)
|
||||
var/blastloc = get_step(A, blast_dir)
|
||||
if(blastloc)
|
||||
explosion(blastloc, -1, -1, 2, 3)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/tungsten/Bump(atom/A, forced=0)
|
||||
if(istype(A, /obj/structure/window)) //It does not pass through windows. It pulverizes them.
|
||||
var/obj/structure/window/W = A
|
||||
W.shatter()
|
||||
return 0
|
||||
..()
|
||||
/obj/item/projectile/ion
|
||||
name = "ion bolt"
|
||||
icon_state = "ion"
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#55AAFF"
|
||||
hud_state = "plasma_blast"
|
||||
hud_state_empty = "battery_empty"
|
||||
|
||||
combustion = FALSE
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
|
||||
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
|
||||
hitsound = 'sound/weapons/ionrifle.ogg'
|
||||
|
||||
var/sev1_range = 0
|
||||
var/sev2_range = 1
|
||||
var/sev3_range = 1
|
||||
var/sev4_range = 1
|
||||
|
||||
/obj/item/projectile/ion/on_impact(var/atom/target)
|
||||
empulse(target, sev1_range, sev2_range, sev3_range, sev4_range)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/ion/small
|
||||
sev1_range = -1
|
||||
sev2_range = 0
|
||||
sev3_range = 0
|
||||
sev4_range = 1
|
||||
|
||||
/obj/item/projectile/ion/pistol
|
||||
sev1_range = 0
|
||||
sev2_range = 0
|
||||
sev3_range = 0
|
||||
sev4_range = 0
|
||||
|
||||
/obj/item/projectile/bullet/gyro
|
||||
name ="explosive bolt"
|
||||
icon_state= "bolter"
|
||||
damage = 50
|
||||
check_armour = "bullet"
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
hud_state = "rocket_fire"
|
||||
|
||||
/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0)
|
||||
explosion(target, -1, 0, 2)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/temp
|
||||
name = "freeze beam"
|
||||
icon_state = "ice_2"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
nodamage = 1
|
||||
check_armour = "energy" // It actually checks heat/cold protection.
|
||||
var/target_temperature = 50
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#55AAFF"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
hud_state = "water"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/temp/on_hit(atom/target, blocked = FALSE)
|
||||
..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
|
||||
var/protection = null
|
||||
var/potential_temperature_delta = null
|
||||
var/new_temperature = L.bodytemperature
|
||||
|
||||
if(target_temperature >= T20C) // Make it cold.
|
||||
protection = L.get_cold_protection(target_temperature)
|
||||
potential_temperature_delta = 75
|
||||
new_temperature = max(new_temperature - potential_temperature_delta, target_temperature)
|
||||
else // Make it hot.
|
||||
protection = L.get_heat_protection(target_temperature)
|
||||
potential_temperature_delta = 200 // Because spacemen temperature needs stupid numbers to actually hurt people.
|
||||
new_temperature = min(new_temperature + potential_temperature_delta, target_temperature)
|
||||
|
||||
var/temp_factor = abs(protection - 1)
|
||||
|
||||
new_temperature = round(new_temperature * temp_factor)
|
||||
L.bodytemperature = new_temperature
|
||||
//VOREStation Add Start - The last metroid has escaped from captivity, the galaxy is no longer safe.
|
||||
if(istype(L, /mob/living/simple_mob/vore/alienanimals/space_jellyfish) && target_temperature <= T0C)
|
||||
var/mob/living/simple_mob/vore/alienanimals/space_jellyfish/J = L
|
||||
J.adjustFireLoss(75)
|
||||
J.movement_cooldown *= 2
|
||||
//VOREStation Add End
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/temp/hot
|
||||
name = "heat beam"
|
||||
target_temperature = 1000
|
||||
hud_state = "flame"
|
||||
|
||||
combustion = TRUE
|
||||
|
||||
/obj/item/projectile/meteor
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "smallf"
|
||||
damage = 0
|
||||
damage_type = BRUTE
|
||||
nodamage = 1
|
||||
check_armour = "bullet"
|
||||
hud_state = "monkey"
|
||||
|
||||
/obj/item/projectile/meteor/Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return
|
||||
|
||||
sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits
|
||||
|
||||
if(src)//Do not add to this if() statement, otherwise the meteor won't delete them
|
||||
if(A)
|
||||
|
||||
A.ex_act(2)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 40, 1)
|
||||
|
||||
for(var/mob/M in range(10, src))
|
||||
if(!M.stat && !istype(M, /mob/living/silicon/ai))\
|
||||
shake_camera(M, 3, 1)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/projectile/energy/floramut
|
||||
name = "alpha somatoray"
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#33CC00"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
var/lasermod = 0
|
||||
combustion = FALSE
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/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((H.species.flags & IS_PLANT) && (M.nutrition < 500))
|
||||
if(prob(15))
|
||||
M.apply_effect((rand(30,80)),IRRADIATE)
|
||||
M.Weaken(5)
|
||||
var/datum/gender/TM = gender_datums[M.get_visible_gender()]
|
||||
for (var/mob/V in viewers(src))
|
||||
V.show_message(span_red("[M] writhes in pain as [TM.his] vacuoles boil."), 3, span_red("You hear the crunching of leaves."), 2)
|
||||
if(prob(35))
|
||||
// for (var/mob/V in viewers(src)) //Public messages commented out to prevent possible metaish genetics experimentation and stuff. - Cheridan
|
||||
// V.show_message("<font color='red'>[M] is mutated by the radiation beam.</font>", 3, "<font color='red'> You hear the snapping of twigs.</font>", 2)
|
||||
if(prob(80))
|
||||
randmutb(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
randmutg(M)
|
||||
domutcheck(M,null)
|
||||
else
|
||||
M.adjustFireLoss(rand(5,15))
|
||||
M.show_message(span_red("The radiation beam singes you!"))
|
||||
// for (var/mob/V in viewers(src))
|
||||
// V.show_message("<font color='red'>[M] is singed by the radiation beam.</font>", 3, "<font color='red'> You hear the crackle of burning leaves.</font>", 2)
|
||||
else if(istype(target, /mob/living/carbon/))
|
||||
// for (var/mob/V in viewers(src))
|
||||
// V.show_message("The radiation beam dissipates harmlessly through [M]", 3)
|
||||
M.show_message(span_blue("The radiation beam dissipates harmlessly through your body."))
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/energy/floramut/gene
|
||||
name = "gamma somatoray"
|
||||
icon_state = "energy2"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
var/decl/plantgene/gene = null
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/florayield
|
||||
name = "beta somatoray"
|
||||
icon_state = "energy2"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
damage = 0
|
||||
damage_type = TOX
|
||||
nodamage = 1
|
||||
check_armour = "energy"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#FFFFFF"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
|
||||
var/lasermod = 0
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0)
|
||||
var/mob/living/M = target
|
||||
if(ishuman(target)) //These rays make plantmen fat.
|
||||
var/mob/living/carbon/human/H = M
|
||||
if((H.species.flags & IS_PLANT) && (M.nutrition < 500))
|
||||
M.adjust_nutrition(30)
|
||||
else if (istype(target, /mob/living/carbon/))
|
||||
M.show_message(span_blue("The radiation beam dissipates harmlessly through your body."))
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/projectile/beam/mindflayer
|
||||
name = "flayer ray"
|
||||
|
||||
combustion = FALSE
|
||||
hud_state = "electrothermal"
|
||||
|
||||
/obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
M.Confuse(rand(5,8))
|
||||
..()
|
||||
|
||||
/obj/item/projectile/chameleon
|
||||
name = "bullet"
|
||||
icon_state = "bullet"
|
||||
damage = 1 // stop trying to murderbone with a fake gun dumbass!!!
|
||||
embed_chance = 0 // nope
|
||||
nodamage = 1
|
||||
damage_type = HALLOSS
|
||||
muzzle_type = /obj/effect/projectile/muzzle/bullet
|
||||
hud_state = "monkey"
|
||||
|
||||
/obj/item/projectile/bola
|
||||
name = "bola"
|
||||
icon_state = "bola"
|
||||
damage = 5
|
||||
embed_chance = 0 //Nada.
|
||||
damage_type = HALLOSS
|
||||
muzzle_type = null
|
||||
hud_state = "monkey"
|
||||
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/bola/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/M = target
|
||||
var/obj/item/weapon/handcuffs/legcuffs/bola/B = new(src.loc)
|
||||
if(!B.place_legcuffs(M,firer))
|
||||
if(B)
|
||||
qdel(B)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/webball
|
||||
name = "ball of web"
|
||||
icon_state = "bola"
|
||||
damage = 10
|
||||
embed_chance = 0 //Nada.
|
||||
damage_type = BRUTE
|
||||
muzzle_type = null
|
||||
hud_state = "monkey"
|
||||
combustion = FALSE
|
||||
|
||||
/obj/item/projectile/webball/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isturf(target.loc))
|
||||
var/obj/effect/spider/stickyweb/W = locate() in get_turf(target)
|
||||
if(!W && prob(75))
|
||||
visible_message("<span class='danger'>\The [src] splatters a layer of web on \the [target]!</span>")
|
||||
new /obj/effect/spider/stickyweb(target.loc)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/tungsten
|
||||
name = "core of molten tungsten"
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/weapons/gauss_shoot.ogg'
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
damage = 70
|
||||
damage_type = BURN
|
||||
check_armour = "laser"
|
||||
light_range = 4
|
||||
light_power = 3
|
||||
light_color = "#3300ff"
|
||||
hud_state = "alloy_spike"
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/tungsten
|
||||
tracer_type = /obj/effect/projectile/tracer/tungsten
|
||||
impact_type = /obj/effect/projectile/impact/tungsten
|
||||
|
||||
/obj/item/projectile/beam/tungsten/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.add_modifier(/datum/modifier/grievous_wounds, 30 SECONDS)
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
|
||||
var/target_armor = H.getarmor(def_zone, check_armour)
|
||||
var/obj/item/organ/external/target_limb = H.get_organ(def_zone)
|
||||
|
||||
var/armor_special = 0
|
||||
|
||||
if(target_armor >= 60)
|
||||
var/turf/T = get_step(H, pick(alldirs - src.dir))
|
||||
H.throw_at(T, 1, 1, src)
|
||||
H.apply_damage(20, BURN, def_zone)
|
||||
if(target_limb)
|
||||
armor_special = 2
|
||||
target_limb.fracture()
|
||||
|
||||
else if(target_armor >= 45)
|
||||
H.apply_damage(15, BURN, def_zone)
|
||||
if(target_limb)
|
||||
armor_special = 1
|
||||
target_limb.dislocate()
|
||||
|
||||
else if(target_armor >= 30)
|
||||
H.apply_damage(10, BURN, def_zone)
|
||||
if(prob(30) && target_limb)
|
||||
armor_special = 1
|
||||
target_limb.dislocate()
|
||||
|
||||
else if(target_armor >= 15)
|
||||
H.apply_damage(5, BURN, def_zone)
|
||||
if(prob(15) && target_limb)
|
||||
armor_special = 1
|
||||
target_limb.dislocate()
|
||||
|
||||
if(armor_special > 1)
|
||||
target.visible_message("<span class='cult'>\The [src] slams into \the [target]'s [target_limb], reverberating loudly!</span>")
|
||||
|
||||
else if(armor_special)
|
||||
target.visible_message("<span class='cult'>\The [src] slams into \the [target]'s [target_limb] with a low rumble!</span>")
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/tungsten/on_impact(var/atom/A)
|
||||
if(istype(A,/turf/simulated/shuttle/wall) || istype(A,/turf/simulated/wall) || (istype(A,/turf/simulated/mineral) && A.density) || istype(A,/obj/mecha) || istype(A,/obj/machinery/door))
|
||||
var/blast_dir = src.dir
|
||||
A.visible_message("<span class='danger'>\The [A] begins to glow!</span>")
|
||||
spawn(2 SECONDS)
|
||||
var/blastloc = get_step(A, blast_dir)
|
||||
if(blastloc)
|
||||
explosion(blastloc, -1, -1, 2, 3)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/tungsten/Bump(atom/A, forced=0)
|
||||
if(istype(A, /obj/structure/window)) //It does not pass through windows. It pulverizes them.
|
||||
var/obj/structure/window/W = A
|
||||
W.shatter()
|
||||
return 0
|
||||
..()
|
||||
|
||||
Reference in New Issue
Block a user