mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Rewrites syringe and dart guns
This commit is contained in:
@@ -79,7 +79,7 @@
|
||||
/obj/item/weapon/storage/box/syringes
|
||||
name = "box of syringes"
|
||||
desc = "A box full of syringes."
|
||||
desc = "A biohazard alert warning is printed on the box"
|
||||
// desc = "A biohazard alert warning is printed on the box"
|
||||
icon_state = "syringe"
|
||||
|
||||
New()
|
||||
@@ -92,6 +92,22 @@
|
||||
new /obj/item/weapon/reagent_containers/syringe( src )
|
||||
new /obj/item/weapon/reagent_containers/syringe( src )
|
||||
|
||||
/obj/item/weapon/storage/box/syringegun
|
||||
name = "box of compressed gas cartridges"
|
||||
desc = "A box full of compressed gas cartridges."
|
||||
icon_state = "syringe"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/beakers
|
||||
name = "box of beakers"
|
||||
icon_state = "beaker"
|
||||
|
||||
@@ -37,7 +37,7 @@ var/global/vox_tick = 1
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
|
||||
equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_l_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/raider(src), slot_r_hand)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/raider(src), slot_r_hand)
|
||||
equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand)
|
||||
|
||||
if(4) // Vox medic!
|
||||
@@ -46,7 +46,7 @@ var/global/vox_tick = 1
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) // Who needs actual surgical tools?
|
||||
equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
|
||||
equip_to_slot_or_del(new /obj/item/weapon/circular_saw(src), slot_l_store)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/medical, slot_r_hand)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/medical, slot_r_hand)
|
||||
|
||||
equip_to_slot_or_del(new /obj/item/clothing/mask/breath(src), slot_wear_mask)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back)
|
||||
|
||||
@@ -1220,9 +1220,10 @@
|
||||
/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone)
|
||||
. = 1
|
||||
|
||||
if(!target_zone)
|
||||
if(!user)
|
||||
target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head")
|
||||
else if(!target_zone)
|
||||
else
|
||||
target_zone = user.zone_sel.selecting
|
||||
|
||||
switch(target_zone)
|
||||
|
||||
@@ -389,6 +389,13 @@ emp_act
|
||||
src.anchored = 1
|
||||
src.pinned += O
|
||||
|
||||
/mob/living/carbon/human/embed(var/obj/O, var/def_zone=null)
|
||||
if(!def_zone) ..()
|
||||
|
||||
var/datum/organ/external/affecting = get_organ(def_zone)
|
||||
if(affecting)
|
||||
affecting.embed(O)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2)
|
||||
if (gloves)
|
||||
|
||||
@@ -148,8 +148,7 @@
|
||||
|
||||
if(W.sharp) //Projectile is suitable for pinning.
|
||||
//Handles embedding for non-humans and simple_animals.
|
||||
O.loc = src
|
||||
src.embedded += O
|
||||
embed(O)
|
||||
|
||||
var/turf/T = near_wall(dir,2)
|
||||
|
||||
@@ -158,6 +157,10 @@
|
||||
visible_message("<span class='warning'>[src] is pinned to the wall by [O]!</span>","<span class='warning'>You are pinned to the wall by [O]!</span>")
|
||||
src.anchored = 1
|
||||
src.pinned += O
|
||||
|
||||
/mob/living/proc/embed(var/obj/O, var/def_zone=null)
|
||||
O.loc = src
|
||||
src.embedded += O
|
||||
src.verbs += /mob/proc/yank_out_object
|
||||
|
||||
//This is called when the mob is thrown into a dense turf
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
if(recoil)
|
||||
spawn()
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
update_icon()
|
||||
|
||||
//does the actual shooting
|
||||
/obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define HOLD_CASINGS 0 //do not do anything after firing. Manual action, like pump shotguns
|
||||
#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
|
||||
|
||||
@@ -53,10 +53,12 @@
|
||||
..()
|
||||
if(chambered)
|
||||
chambered.expend()
|
||||
|
||||
//check chambered again in case it deleted itself
|
||||
if(chambered && handle_casings != HOLD_CASINGS)
|
||||
switch(handle_casings)
|
||||
if(EJECT_CASINGS) //eject casing onto ground.
|
||||
chambered.loc = get_turf(src)
|
||||
chambered = null
|
||||
if(CYCLE_CASINGS) //cycle the casing back to the end.
|
||||
if(ammo_magazine)
|
||||
ammo_magazine.stored_ammo += chambered
|
||||
@@ -64,6 +66,7 @@
|
||||
loaded += chambered
|
||||
chambered = null
|
||||
|
||||
|
||||
//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)
|
||||
@@ -81,6 +84,7 @@
|
||||
AM.loc = src
|
||||
ammo_magazine = AM
|
||||
user.visible_message("[user] inserts [AM] into [src].", "<span class='notice'>You insert [AM] into [src]!</span>")
|
||||
playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
if(SPEEDLOADER)
|
||||
if(loaded.len >= max_shells)
|
||||
user << "<span class='warning'>[src] is full!</span>"
|
||||
@@ -96,6 +100,7 @@
|
||||
count++
|
||||
if(count)
|
||||
user.visible_message("[user] reloads [src].", "<span class='notice'>You load [count] round\s into [src]!</span>")
|
||||
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
|
||||
AM.update_icon()
|
||||
else if(istype(A, /obj/item/ammo_casing))
|
||||
var/obj/item/ammo_casing/C = A
|
||||
@@ -109,20 +114,22 @@
|
||||
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.loc, 'sound/weapons/empty.ogg', 50, 1)
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
//attempts to unload src
|
||||
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user)
|
||||
//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.loc, 'sound/weapons/empty.ogg', 50, 1)
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
else if(loaded.len)
|
||||
//presumably, if it can be speed-loaded, it can be speed-unloaded.
|
||||
if(load_method & SPEEDLOADER)
|
||||
if(allow_dump && load_method & SPEEDLOADER)
|
||||
var/count = 0
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
@@ -145,17 +152,11 @@
|
||||
load_ammo(A, user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
|
||||
if (aim_targets) //TODO replace untargeting with a hotkey
|
||||
return ..()
|
||||
unload_ammo(user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob)
|
||||
//allow guns with both SPEEDLOADER and SINGLE_CASING a way to remove casings without dumping everything on the floor
|
||||
if((load_method & SINGLE_CASING) && loaded.len && (src in user))
|
||||
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>")
|
||||
if(src in user)
|
||||
unload_ammo(user, allow_dump=0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -229,6 +229,7 @@
|
||||
/obj/item/projectile/process()
|
||||
spawn while(src)
|
||||
if(kill_count-- < 1)
|
||||
on_impact(src.loc) //for any final impact behaviours
|
||||
del(src)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
|
||||
|
||||
@@ -1,66 +1,94 @@
|
||||
/obj/item/weapon/dart_cartridge
|
||||
/obj/item/projectile/bullet/chemdart
|
||||
name = "dart"
|
||||
icon_state = "cbbolt"
|
||||
damage = 3
|
||||
sharp = 1
|
||||
embed = 1
|
||||
var/reagent_amount = 15
|
||||
kill_count = 10 //short range
|
||||
|
||||
/obj/item/projectile/bullet/chemdart/New()
|
||||
reagents = new/datum/reagents(reagent_amount)
|
||||
reagents.my_atom = src
|
||||
|
||||
/obj/item/projectile/bullet/chemdart/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
if(blocked < 2 && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.can_inject(target_zone=def_zone))
|
||||
reagents.trans_to(L, reagent_amount)
|
||||
|
||||
/obj/item/ammo_casing/chemdart
|
||||
name = "chemical dart"
|
||||
desc = "A small hollow dart."
|
||||
icon_state = "dart"
|
||||
caliber = "dart"
|
||||
projectile_type = /obj/item/projectile/bullet/chemdart
|
||||
|
||||
/obj/item/ammo_magazine/chemdart
|
||||
name = "dart cartridge"
|
||||
desc = "A rack of hollow darts."
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "darts-5"
|
||||
icon_state = "darts"
|
||||
item_state = "rcdammo"
|
||||
opacity = 0
|
||||
density = 0
|
||||
anchored = 0.0
|
||||
origin_tech = "materials=2"
|
||||
var/darts = 5
|
||||
mag_type = MAGAZINE
|
||||
caliber = "dart"
|
||||
max_ammo = 5
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/weapon/dart_cartridge/update_icon()
|
||||
if(!darts)
|
||||
icon_state = "darts-0"
|
||||
else if(darts > 5)
|
||||
icon_state = "darts-5"
|
||||
else
|
||||
icon_state = "darts-[darts]"
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/dartgun
|
||||
/obj/item/weapon/gun/projectile/dartgun
|
||||
name = "dart gun"
|
||||
desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances."
|
||||
icon_state = "dartgun-empty"
|
||||
|
||||
caliber = "dart"
|
||||
fire_sound = 'sound/weapons/empty.ogg'
|
||||
fire_sound_text = "a metallic click"
|
||||
recoil = 0
|
||||
silenced = 1
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/chemdart
|
||||
auto_eject = 0
|
||||
|
||||
var/list/beakers = list() //All containers inside the gun.
|
||||
var/list/mixing = list() //Containers being used for mixing.
|
||||
var/obj/item/weapon/dart_cartridge/cartridge = null //Container of darts.
|
||||
var/max_beakers = 3
|
||||
var/dart_reagent_amount = 15
|
||||
var/container_type = /obj/item/weapon/reagent_containers/glass/beaker
|
||||
var/list/starting_chems = null
|
||||
|
||||
/obj/item/weapon/gun/dartgun/update_icon()
|
||||
|
||||
if(!cartridge)
|
||||
icon_state = "dartgun-empty"
|
||||
return 1
|
||||
|
||||
if(!cartridge.darts)
|
||||
icon_state = "dartgun-0"
|
||||
else if(cartridge.darts > 5)
|
||||
icon_state = "dartgun-5"
|
||||
else
|
||||
icon_state = "dartgun-[cartridge.darts]"
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/dartgun/New()
|
||||
|
||||
/obj/item/weapon/gun/projectile/dartgun/dartgun/New()
|
||||
..()
|
||||
if(starting_chems)
|
||||
for(var/chem in starting_chems)
|
||||
var/obj/B = new container_type(src)
|
||||
B.reagents.add_reagent(chem, 50)
|
||||
B.reagents.add_reagent(chem, 60)
|
||||
beakers += B
|
||||
cartridge = new /obj/item/weapon/dart_cartridge(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/dartgun/examine(mob/user)
|
||||
update_icon()
|
||||
if (!..(user, 2))
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/dartgun/update_icon()
|
||||
if(!ammo_magazine)
|
||||
icon_state = "dartgun-empty"
|
||||
return 1
|
||||
|
||||
if(!ammo_magazine.stored_ammo || ammo_magazine.stored_ammo.len)
|
||||
icon_state = "dartgun-0"
|
||||
else if(ammo_magazine.stored_ammo.len > 5)
|
||||
icon_state = "dartgun-5"
|
||||
else
|
||||
icon_state = "dartgun-[ammo_magazine.stored_ammo.len]"
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/dartgun/consume_next_projectile()
|
||||
. = ..()
|
||||
var/obj/item/projectile/bullet/chemdart/dart = .
|
||||
if(istype(dart))
|
||||
fill_dart(dart)
|
||||
|
||||
/obj/item/weapon/gun/projectile/dartgun/examine(mob/user)
|
||||
//update_icon()
|
||||
//if (!..(user, 2))
|
||||
// return
|
||||
..()
|
||||
if (beakers.len)
|
||||
user << "\blue [src] contains:"
|
||||
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers)
|
||||
@@ -68,28 +96,7 @@
|
||||
for(var/datum/reagent/R in B.reagents.reagent_list)
|
||||
user << "\blue [R.volume] units of [R.name]"
|
||||
|
||||
/obj/item/weapon/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/dart_cartridge))
|
||||
|
||||
var/obj/item/weapon/dart_cartridge/D = I
|
||||
|
||||
if(!D.darts)
|
||||
user << "\blue [D] is empty."
|
||||
return 0
|
||||
|
||||
if(cartridge)
|
||||
if(cartridge.darts <= 0)
|
||||
src.remove_cartridge()
|
||||
else
|
||||
user << "\blue There's already a cartridge in [src]."
|
||||
return 0
|
||||
|
||||
user.drop_item()
|
||||
cartridge = D
|
||||
D.loc = src
|
||||
user << "\blue You slot [D] into [src]."
|
||||
update_icon()
|
||||
return
|
||||
/obj/item/weapon/gun/projectile/dartgun/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
if(!istype(I, container_type))
|
||||
user << "\blue [I] doesn't seem to fit into [src]."
|
||||
@@ -103,112 +110,16 @@
|
||||
beakers += B
|
||||
user << "\blue You slot [B] into [src]."
|
||||
src.updateUsrDialog()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/dartgun/can_fire()
|
||||
if(!cartridge)
|
||||
return 0
|
||||
else
|
||||
return cartridge.darts
|
||||
|
||||
/obj/item/weapon/gun/dartgun/proc/has_selected_beaker_reagents()
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/dartgun/proc/remove_cartridge()
|
||||
if(cartridge)
|
||||
usr << "\blue You pop the cartridge out of [src]."
|
||||
var/obj/item/weapon/dart_cartridge/C = cartridge
|
||||
C.loc = get_turf(src)
|
||||
C.update_icon()
|
||||
cartridge = null
|
||||
src.update_icon()
|
||||
|
||||
/obj/item/weapon/gun/dartgun/proc/get_mixed_syringe()
|
||||
if (!cartridge)
|
||||
return 0
|
||||
if(!cartridge.darts)
|
||||
return 0
|
||||
|
||||
var/obj/item/weapon/reagent_containers/syringe/dart = new(src)
|
||||
|
||||
//fills the given dart with reagents
|
||||
/obj/item/weapon/gun/projectile/dartgun/proc/fill_dart(var/obj/item/projectile/bullet/chemdart/dart)
|
||||
if(mixing.len)
|
||||
var/mix_amount = dart_reagent_amount/mixing.len
|
||||
var/mix_amount = dart.reagent_amount/mixing.len
|
||||
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing)
|
||||
B.reagents.trans_to(dart, mix_amount)
|
||||
|
||||
return dart
|
||||
|
||||
/obj/item/weapon/gun/dartgun/proc/fire_dart(atom/target, mob/user)
|
||||
if (locate (/obj/structure/table, src.loc))
|
||||
return
|
||||
else
|
||||
var/turf/trg = get_turf(target)
|
||||
var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src))
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = get_mixed_syringe()
|
||||
if(!S)
|
||||
user << "\red There are no darts in [src]!"
|
||||
return
|
||||
if(!S.reagents)
|
||||
user << "\red There are no reagents available!"
|
||||
return
|
||||
cartridge.darts--
|
||||
src.update_icon()
|
||||
S.reagents.trans_to(D, S.reagents.total_volume)
|
||||
del(S)
|
||||
D.icon_state = "syringeproj"
|
||||
D.name = "syringe"
|
||||
D.flags |= NOREACT
|
||||
playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
|
||||
for(var/i=0, i<6, i++)
|
||||
if(!D) break
|
||||
if(D.loc == trg) break
|
||||
step_towards(D,trg)
|
||||
|
||||
if(D)
|
||||
for(var/mob/living/carbon/M in D.loc)
|
||||
if(!istype(M,/mob/living/carbon)) continue
|
||||
if(M == user) continue
|
||||
//Syringe gun attack logging by Yvarov
|
||||
var/R
|
||||
if(D.reagents)
|
||||
for(var/datum/reagent/A in D.reagents.reagent_list)
|
||||
R += A.id + " ("
|
||||
R += num2text(A.volume) + "),"
|
||||
if (istype(M, /mob))
|
||||
M.attack_log += "\[[time_stamp()]\] <b>[user]/[user.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>dartgun</b> ([R])"
|
||||
user.attack_log += "\[[time_stamp()]\] <b>[user]/[user.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>dartgun</b> ([R])"
|
||||
msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a dartgun ([R]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
else
|
||||
M.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[M]/[M.ckey]</b> with a <b>dartgun</b> ([R])"
|
||||
msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a <b>dartgun</b> ([R]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
if(D.reagents)
|
||||
D.reagents.trans_to(M, 15)
|
||||
M << "<span class='danger'>You feel a slight prick.</span>"
|
||||
|
||||
del(D)
|
||||
break
|
||||
if(D)
|
||||
for(var/atom/A in D.loc)
|
||||
if(A == user) continue
|
||||
if(A.density) del(D)
|
||||
|
||||
sleep(1)
|
||||
|
||||
if (D) spawn(10) del(D)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/dartgun/afterattack(obj/target, mob/user , flag)
|
||||
if(!isturf(target.loc) || target == user) return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/dartgun/can_hit(var/mob/living/target as mob, var/mob/living/user as mob)
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/dartgun/attack_self(mob/user)
|
||||
|
||||
/obj/item/weapon/gun/projectile/dartgun/attack_self(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = "<b>[src] mixing control:</b><br><br>"
|
||||
|
||||
@@ -230,9 +141,9 @@
|
||||
else
|
||||
dat += "There are no beakers inserted!<br><br>"
|
||||
|
||||
if(cartridge)
|
||||
if(cartridge.darts)
|
||||
dat += "The dart cartridge has [cartridge.darts] shots remaining."
|
||||
if(ammo_magazine)
|
||||
if(ammo_magazine.stored_ammo && ammo_magazine.stored_ammo.len)
|
||||
dat += "The dart cartridge has [ammo_magazine.stored_ammo.len] shots remaining."
|
||||
else
|
||||
dat += "<font color='red'>The dart cartridge is empty!</font>"
|
||||
dat += " \[<A href='?src=\ref[src];eject_cart=1'>Eject</A>\]"
|
||||
@@ -240,7 +151,7 @@
|
||||
user << browse(dat, "window=dartgun")
|
||||
onclose(user, "dartgun", src)
|
||||
|
||||
/obj/item/weapon/gun/dartgun/proc/check_beaker_mixing(var/obj/item/B)
|
||||
/obj/item/weapon/gun/projectile/dartgun/proc/check_beaker_mixing(var/obj/item/B)
|
||||
if(!mixing || !beakers)
|
||||
return 0
|
||||
for(var/obj/item/M in mixing)
|
||||
@@ -248,7 +159,7 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/dartgun/Topic(href, href_list)
|
||||
/obj/item/weapon/gun/projectile/dartgun/Topic(href, href_list)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["stop_mix"])
|
||||
var/index = text2num(href_list["stop_mix"])
|
||||
@@ -271,23 +182,16 @@
|
||||
beakers -= B
|
||||
B.loc = get_turf(src)
|
||||
else if (href_list["eject_cart"])
|
||||
remove_cartridge()
|
||||
unload_ammo(usr)
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/dartgun/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
|
||||
if(cartridge)
|
||||
spawn(0) fire_dart(target,user)
|
||||
else
|
||||
usr << "\red [src] is empty."
|
||||
|
||||
|
||||
/obj/item/weapon/gun/dartgun/vox
|
||||
/obj/item/weapon/gun/projectile/dartgun/vox
|
||||
name = "alien dart gun"
|
||||
desc = "A small gas-powered dartgun, fitted for nonhuman hands."
|
||||
|
||||
/obj/item/weapon/gun/dartgun/vox/medical
|
||||
/obj/item/weapon/gun/projectile/dartgun/vox/medical
|
||||
starting_chems = list("kelotane","bicaridine","anti_toxin")
|
||||
|
||||
/obj/item/weapon/gun/dartgun/vox/raider
|
||||
/obj/item/weapon/gun/projectile/dartgun/vox/raider
|
||||
starting_chems = list("space_drugs","stoxin","impedrezene")
|
||||
@@ -18,6 +18,7 @@
|
||||
w_class = 1
|
||||
sharp = 1
|
||||
var/mode = SYRINGE_DRAW
|
||||
var/image/filling //holds a reference to the current filling overlay
|
||||
|
||||
on_reagent_change()
|
||||
update_icon()
|
||||
@@ -217,7 +218,7 @@
|
||||
item_state = "syringe_[rounded_vol]"
|
||||
|
||||
if(reagents.total_volume)
|
||||
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "syringe10")
|
||||
filling = image('icons/obj/reagentfillings.dmi', src, "syringe10")
|
||||
|
||||
filling.icon_state = "syringe[rounded_vol]"
|
||||
|
||||
@@ -225,7 +226,7 @@
|
||||
overlays += filling
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/syringe/proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob)
|
||||
proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob)
|
||||
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [target.name] ([target.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
target.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
@@ -268,13 +269,19 @@
|
||||
src.reagents.reaction(target, INGEST)
|
||||
var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand
|
||||
src.reagents.trans_to(target, syringestab_amount_transferred)
|
||||
src.break_syringe(target, user)
|
||||
|
||||
proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user)
|
||||
src.desc += " It is broken."
|
||||
src.mode = SYRINGE_BROKEN
|
||||
if(target)
|
||||
src.add_blood(target)
|
||||
src.add_fingerprint(usr)
|
||||
if(user)
|
||||
src.add_fingerprint(user)
|
||||
src.update_icon()
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/ld50_syringe
|
||||
name = "Lethal Injection Syringe"
|
||||
desc = "A syringe used for lethal injections."
|
||||
|
||||
@@ -1,137 +1,130 @@
|
||||
/obj/item/ammo_casing/gas_cartridge
|
||||
name = "compressed gas cartridge"
|
||||
desc = "An impact-triggered compressed gas cartridge that can fitted to a syringe for rapid injection. It's not very useful until primed though." //i.e. only works when shot out of a syringe gun.
|
||||
icon_state = "syringe-cartridge"
|
||||
caliber = "syringe"
|
||||
projectile_type = /obj/item/projectile/bullet/syringe
|
||||
w_class = 2 //mainly so that they can be yanked out
|
||||
var/obj/item/weapon/reagent_containers/syringe/syringe
|
||||
|
||||
/obj/item/ammo_casing/gas_cartridge/update_icon()
|
||||
underlays.Cut()
|
||||
if(syringe)
|
||||
underlays += image(syringe.icon, src, syringe.icon_state)
|
||||
underlays += syringe.filling
|
||||
|
||||
/obj/item/ammo_casing/gas_cartridge/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/syringe))
|
||||
syringe = I
|
||||
user << "<span class='notice'>You carefully insert [syringe] into [src].</span>"
|
||||
user.remove_from_mob(syringe)
|
||||
syringe.loc = src
|
||||
var/obj/item/projectile/bullet/syringe/S = BB
|
||||
if(istype(S))
|
||||
S.damage = 1
|
||||
S.sharp = 1
|
||||
update_icon()
|
||||
|
||||
/obj/item/ammo_casing/gas_cartridge/attack_self(mob/user)
|
||||
if(syringe)
|
||||
user << "<span class='notice'>You remove [syringe] from [src].</span>"
|
||||
user.put_in_hands(syringe)
|
||||
syringe = null
|
||||
var/obj/item/projectile/bullet/syringe/S = BB
|
||||
if(istype(S))
|
||||
S.damage = initial(S.damage)
|
||||
S.sharp = initial(S.sharp)
|
||||
update_icon()
|
||||
|
||||
//This was kind of rushed, there may very well be a simpler way to implement this.
|
||||
//Sort of hacky, though nearly not as bad as the previous implementation:
|
||||
//Basically the syringe gun is supposed to launch the entire syringe+cartrige assemby, but hitby() isn't powerfull enough to do what we need.
|
||||
//Instead, we fire a projectile that transfers the reagents, and teleport the cartridge once we impact something.
|
||||
/obj/item/projectile/bullet/syringe
|
||||
name = "syringe dart"
|
||||
icon_state = "cbbolt"
|
||||
damage = 3
|
||||
check_armour = "bullet"
|
||||
sharp = 0
|
||||
embed = 0 //we handle this ourselves
|
||||
var/obj/item/ammo_casing/gas_cartridge/cartridge
|
||||
var/embedded = 0
|
||||
kill_count = 10 //short range
|
||||
|
||||
/obj/item/projectile/bullet/syringe/New(newloc)
|
||||
..()
|
||||
//ensure that cartridge is always set
|
||||
cartridge = newloc
|
||||
if(!istype(cartridge))
|
||||
del(src)
|
||||
|
||||
/obj/item/projectile/bullet/syringe/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
|
||||
//..() //not really necessary
|
||||
if(blocked < 2 && cartridge.syringe && isliving(target))
|
||||
var/mob/living/L = target
|
||||
|
||||
//inject
|
||||
if(L.can_inject(target_zone=def_zone))
|
||||
if(cartridge.syringe.reagents)
|
||||
cartridge.syringe.reagents.trans_to(L, 15)
|
||||
cartridge.syringe.update_icon()
|
||||
cartridge.update_icon()
|
||||
|
||||
//embed
|
||||
L.embed(cartridge, def_zone)
|
||||
embedded = 1
|
||||
|
||||
/obj/item/projectile/bullet/syringe/on_impact(atom/A)
|
||||
if(!embedded)
|
||||
cartridge.loc = src.loc
|
||||
if(cartridge.syringe)
|
||||
cartridge.syringe.break_syringe(iscarbon(A)? A : null)
|
||||
cartridge.update_icon()
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/gun/syringe
|
||||
/obj/item/weapon/gun/projectile/syringe
|
||||
name = "syringe gun"
|
||||
desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "syringegun"
|
||||
item_state = "syringegun"
|
||||
w_class = 3.0
|
||||
throw_speed = 2
|
||||
throw_range = 10
|
||||
force = 4.0
|
||||
var/list/syringes = new/list()
|
||||
var/max_syringes = 1
|
||||
w_class = 3
|
||||
force = 7
|
||||
matter = list("metal" = 2000)
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/weapon/gun/syringe/examine(mob/user)
|
||||
if(..(user, 2))
|
||||
user << "\blue [syringes.len] / [max_syringes] syringes."
|
||||
caliber = "syringe"
|
||||
fire_sound = 'sound/weapons/empty.ogg'
|
||||
fire_sound_text = "a metallic thunk"
|
||||
recoil = 0
|
||||
handle_casings = HOLD_CASINGS
|
||||
load_method = SINGLE_CASING
|
||||
max_shells = 1
|
||||
var/drawn = 0
|
||||
|
||||
/obj/item/weapon/gun/syringe/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/syringe))
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = I
|
||||
if(S.mode != 2)//SYRINGE_BROKEN in syringes.dm
|
||||
if(syringes.len < max_syringes)
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
syringes += I
|
||||
user << "\blue You put the syringe in [src]."
|
||||
user << "\blue [syringes.len] / [max_syringes] syringes."
|
||||
else
|
||||
usr << "\red [src] cannot hold more syringes."
|
||||
else
|
||||
usr << "\red This syringe is broken!"
|
||||
/obj/item/weapon/gun/projectile/syringe/consume_next_projectile()
|
||||
if(chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/syringe/attack_self(mob/living/user as mob)
|
||||
if(!chambered && loaded.len)
|
||||
playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
user.visible_message("[user] draws back the bolt on [src], clicking it into place.", "<span class='warning'>You draw back the bolt on the [src], loading the spring!</span>")
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
chambered = AC
|
||||
max_shells -= 1 //to prevent people from storing an extra syringe
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/syringe/afterattack(obj/target, mob/user , flag)
|
||||
if(!isturf(target.loc) || target == user) return
|
||||
/obj/item/weapon/gun/projectile/syringe/handle_post_fire()
|
||||
..()
|
||||
chambered = null
|
||||
max_shells = initial(max_shells)
|
||||
|
||||
/obj/item/weapon/gun/syringe/can_fire()
|
||||
return syringes.len
|
||||
|
||||
/obj/item/weapon/gun/syringe/can_hit(var/mob/living/target as mob, var/mob/living/user as mob)
|
||||
return 1 //SHOOT AND LET THE GOD GUIDE IT (probably will hit a wall anyway)
|
||||
|
||||
/obj/item/weapon/gun/syringe/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
|
||||
if(syringes.len)
|
||||
spawn(0) fire_syringe(target,user)
|
||||
else
|
||||
usr << "\red [src] is empty."
|
||||
|
||||
/obj/item/weapon/gun/syringe/proc/fire_syringe(atom/target, mob/user)
|
||||
if (locate (/obj/structure/table, src.loc))
|
||||
return
|
||||
else
|
||||
var/turf/trg = get_turf(target)
|
||||
var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src))
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = syringes[1]
|
||||
if((!S) || (!S.reagents)) //ho boy! wot runtimes!
|
||||
return
|
||||
S.reagents.trans_to(D, S.reagents.total_volume)
|
||||
syringes -= S
|
||||
del(S)
|
||||
D.icon_state = "syringeproj"
|
||||
D.name = "syringe"
|
||||
playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
|
||||
for(var/i=0, i<6, i++)
|
||||
if(!D) break
|
||||
if(D.loc == trg) break
|
||||
step_towards(D,trg)
|
||||
|
||||
if(D)
|
||||
for(var/mob/living/carbon/M in D.loc)
|
||||
if(!istype(M,/mob/living/carbon)) continue
|
||||
if(M == user) continue
|
||||
//Syringe gun attack logging by Yvarov
|
||||
var/R
|
||||
if(D.reagents)
|
||||
for(var/datum/reagent/A in D.reagents.reagent_list)
|
||||
R += A.id + " ("
|
||||
R += num2text(A.volume) + "),"
|
||||
if (istype(M, /mob))
|
||||
M.attack_log += "\[[time_stamp()]\] <b>[user]/[user.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>syringegun</b> ([R])"
|
||||
user.attack_log += "\[[time_stamp()]\] <b>[user]/[user.ckey]</b> shot <b>[M]/[M.ckey]</b> with a <b>syringegun</b> ([R])"
|
||||
msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a syringegun ([R]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
else
|
||||
M.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[M]/[M.ckey]</b> with a <b>syringegun</b> ([R])"
|
||||
msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a <b>syringegun</b> ([R]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
var/mob/living/T
|
||||
if(istype(M,/mob/living))
|
||||
T = M
|
||||
|
||||
M.visible_message("<span class='danger'>[M] is hit by the syringe!</span>")
|
||||
|
||||
if(T && istype(T) && T.can_inject())
|
||||
if(D.reagents)
|
||||
D.reagents.trans_to(M, 15)
|
||||
else
|
||||
M.visible_message("<span class='danger'>The syringe bounces off [M]!</span>")
|
||||
|
||||
del(D)
|
||||
break
|
||||
if(D)
|
||||
for(var/atom/A in D.loc)
|
||||
if(A == user) continue
|
||||
if(A.density) del(D)
|
||||
|
||||
sleep(1)
|
||||
|
||||
if (D) spawn(10) del(D)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/syringe/rapidsyringe
|
||||
/obj/item/weapon/gun/projectile/syringe/rapid
|
||||
name = "rapid syringe gun"
|
||||
desc = "A modification of the syringe gun design, using a rotating cylinder to store up to four syringes."
|
||||
desc = "A modification of the syringe gun design, using a rotating cylinder to store up to four syringes. The spring still needs to be drawn between shots."
|
||||
icon_state = "rapidsyringegun"
|
||||
max_syringes = 4
|
||||
|
||||
|
||||
/obj/effect/syringe_gun_dummy
|
||||
name = ""
|
||||
desc = ""
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "null"
|
||||
anchored = 1
|
||||
density = 0
|
||||
|
||||
New()
|
||||
var/datum/reagents/R = new/datum/reagents(15)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
max_shells = 4
|
||||
|
||||
@@ -1312,7 +1312,7 @@ datum/design/item/weapon/rapidsyringe
|
||||
id = "rapidsyringe"
|
||||
req_tech = list("combat" = 3, "materials" = 3, "engineering" = 3, "biotech" = 2)
|
||||
materials = list("$metal" = 5000, "$glass" = 1000)
|
||||
build_path = /obj/item/weapon/gun/syringe/rapidsyringe
|
||||
build_path = /obj/item/weapon/gun/projectile/syringe/rapid
|
||||
/*
|
||||
datum/design/item/weapon/largecrossbow
|
||||
name = "Energy Crossbow"
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -5795,7 +5795,7 @@
|
||||
"chw" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virologyaccess)
|
||||
"chx" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plating/airless,/area/medical/virology)
|
||||
"chy" = (/obj/structure/bedsheetbin,/obj/structure/table,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage)
|
||||
"chz" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/weapon/gun/syringe,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage)
|
||||
"chz" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/weapon/gun/projectile/syringe,/obj/item/weapon/storage/box/syringegun,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage)
|
||||
"chA" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/research_port)
|
||||
"chB" = (/turf/simulated/floor/plating,/area/maintenance/research_port)
|
||||
"chC" = (/obj/machinery/door/airlock/medical{autoclose = 0; icon_state = "door_open"; id_tag = "cubicle1"; name = "Cubicle 1"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing)
|
||||
|
||||
@@ -1912,7 +1912,7 @@
|
||||
"KN" = (/obj/machinery/atmospherics/pipe/tank/nitrogen{dir = 1; initialize_directions = 1; start_pressure = 493.6},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KO" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KP" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/dartgun/vox/raider,/obj/item/weapon/gun/projectile/dartgun/vox/medical,/obj/item/ammo_magazine/chemdart,/obj/item/ammo_magazine/chemdart,/obj/item/ammo_magazine/chemdart,/obj/item/ammo_magazine/chemdart,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KR" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KS" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/pneumatic,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
"KT" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
|
||||
|
||||
Reference in New Issue
Block a user