mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Much nicer syringe gun implementation
Makes syringe guns a type of launcher gun, and removes the hack projectile. Also moves syringe and dart gun source files into the modules/projectile folder.
This commit is contained in:
@@ -1331,7 +1331,9 @@
|
|||||||
#include "code\modules\projectiles\guns\launcher\crossbow.dm"
|
#include "code\modules\projectiles\guns\launcher\crossbow.dm"
|
||||||
#include "code\modules\projectiles\guns\launcher\pneumatic.dm"
|
#include "code\modules\projectiles\guns\launcher\pneumatic.dm"
|
||||||
#include "code\modules\projectiles\guns\launcher\rocket.dm"
|
#include "code\modules\projectiles\guns\launcher\rocket.dm"
|
||||||
|
#include "code\modules\projectiles\guns\launcher\syringe_gun.dm"
|
||||||
#include "code\modules\projectiles\guns\projectile\automatic.dm"
|
#include "code\modules\projectiles\guns\projectile\automatic.dm"
|
||||||
|
#include "code\modules\projectiles\guns\projectile\dartgun.dm"
|
||||||
#include "code\modules\projectiles\guns\projectile\pistol.dm"
|
#include "code\modules\projectiles\guns\projectile\pistol.dm"
|
||||||
#include "code\modules\projectiles\guns\projectile\revolver.dm"
|
#include "code\modules\projectiles\guns\projectile\revolver.dm"
|
||||||
#include "code\modules\projectiles\guns\projectile\shotgun.dm"
|
#include "code\modules\projectiles\guns\projectile\shotgun.dm"
|
||||||
@@ -1351,11 +1353,9 @@
|
|||||||
#include "code\modules\reagents\Chemistry-Reagents-Antidepressants.dm"
|
#include "code\modules\reagents\Chemistry-Reagents-Antidepressants.dm"
|
||||||
#include "code\modules\reagents\Chemistry-Reagents.dm"
|
#include "code\modules\reagents\Chemistry-Reagents.dm"
|
||||||
#include "code\modules\reagents\Chemistry-Recipes.dm"
|
#include "code\modules\reagents\Chemistry-Recipes.dm"
|
||||||
#include "code\modules\reagents\dartgun.dm"
|
|
||||||
#include "code\modules\reagents\grenade_launcher.dm"
|
#include "code\modules\reagents\grenade_launcher.dm"
|
||||||
#include "code\modules\reagents\reagent_containers.dm"
|
#include "code\modules\reagents\reagent_containers.dm"
|
||||||
#include "code\modules\reagents\reagent_dispenser.dm"
|
#include "code\modules\reagents\reagent_dispenser.dm"
|
||||||
#include "code\modules\reagents\syringe_gun.dm"
|
|
||||||
#include "code\modules\reagents\reagent_containers\blood_pack.dm"
|
#include "code\modules\reagents\reagent_containers\blood_pack.dm"
|
||||||
#include "code\modules\reagents\reagent_containers\borghydro.dm"
|
#include "code\modules\reagents\reagent_containers\borghydro.dm"
|
||||||
#include "code\modules\reagents\reagent_containers\dropper.dm"
|
#include "code\modules\reagents\reagent_containers\dropper.dm"
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
icon_state = "bike_horn"
|
icon_state = "bike_horn"
|
||||||
item_state = "bike_horn"
|
item_state = "bike_horn"
|
||||||
throwforce = 3
|
throwforce = 3
|
||||||
w_class = 1.0
|
w_class = 2
|
||||||
throw_speed = 3
|
throw_speed = 3
|
||||||
throw_range = 15
|
throw_range = 15
|
||||||
attack_verb = list("HONKED")
|
attack_verb = list("HONKED")
|
||||||
|
|||||||
@@ -99,13 +99,13 @@
|
|||||||
|
|
||||||
New()
|
New()
|
||||||
..()
|
..()
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
new /obj/item/ammo_casing/gas_cartridge( src )
|
new /obj/item/weapon/syringe_cartridge( src )
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/storage/box/beakers
|
/obj/item/weapon/storage/box/beakers
|
||||||
|
|||||||
@@ -304,10 +304,7 @@ emp_act
|
|||||||
throw_mode_off()
|
throw_mode_off()
|
||||||
return
|
return
|
||||||
|
|
||||||
var/dtype = BRUTE
|
var/dtype = O.damtype
|
||||||
if(istype(O,/obj/item/weapon))
|
|
||||||
var/obj/item/weapon/W = O
|
|
||||||
dtype = W.damtype
|
|
||||||
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
|
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
|
||||||
|
|
||||||
var/zone
|
var/zone
|
||||||
@@ -370,17 +367,21 @@ emp_act
|
|||||||
affecting.embed(I)
|
affecting.embed(I)
|
||||||
|
|
||||||
// Begin BS12 momentum-transfer code.
|
// Begin BS12 momentum-transfer code.
|
||||||
if(O.throw_source && speed >= THROWNOBJ_KNOCKBACK_SPEED)
|
var/mass = 1.5
|
||||||
var/obj/item/weapon/W = O
|
if(istype(O, /obj/item))
|
||||||
var/momentum = speed/THROWNOBJ_KNOCKBACK_DIVISOR
|
var/obj/item/I = O
|
||||||
|
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
|
||||||
|
var/momentum = speed*mass
|
||||||
|
|
||||||
|
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
|
||||||
var/dir = get_dir(O.throw_source, src)
|
var/dir = get_dir(O.throw_source, src)
|
||||||
|
|
||||||
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
|
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
|
||||||
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||||
|
|
||||||
if(!W || !src) return
|
if(!O || !src) return
|
||||||
|
|
||||||
if(W.loc == src && W.sharp) //Projectile is embedded and suitable for pinning.
|
if(O.loc == src && O.sharp) //Projectile is embedded and suitable for pinning.
|
||||||
var/turf/T = near_wall(dir,2)
|
var/turf/T = near_wall(dir,2)
|
||||||
|
|
||||||
if(T)
|
if(T)
|
||||||
|
|||||||
@@ -103,10 +103,7 @@
|
|||||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
|
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
|
||||||
if(istype(AM,/obj/))
|
if(istype(AM,/obj/))
|
||||||
var/obj/O = AM
|
var/obj/O = AM
|
||||||
var/dtype = BRUTE
|
var/dtype = O.damtype
|
||||||
if(istype(O,/obj/item/weapon))
|
|
||||||
var/obj/item/weapon/W = O
|
|
||||||
dtype = W.damtype
|
|
||||||
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
|
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
|
||||||
|
|
||||||
var/miss_chance = 15
|
var/miss_chance = 15
|
||||||
@@ -136,17 +133,21 @@
|
|||||||
msg_admin_attack("[src.name] ([src.ckey]) was hit by a [O], thrown by [M.name] ([assailant.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
|
msg_admin_attack("[src.name] ([src.ckey]) was hit by a [O], thrown by [M.name] ([assailant.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
|
||||||
|
|
||||||
// Begin BS12 momentum-transfer code.
|
// Begin BS12 momentum-transfer code.
|
||||||
if(O.throw_source && speed >= THROWNOBJ_KNOCKBACK_SPEED)
|
var/mass = 1.5
|
||||||
var/obj/item/weapon/W = O
|
if(istype(O, /obj/item))
|
||||||
var/momentum = speed/THROWNOBJ_KNOCKBACK_DIVISOR
|
var/obj/item/I = O
|
||||||
|
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
|
||||||
|
var/momentum = speed*mass
|
||||||
|
|
||||||
|
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
|
||||||
var/dir = get_dir(O.throw_source, src)
|
var/dir = get_dir(O.throw_source, src)
|
||||||
|
|
||||||
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
|
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
|
||||||
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||||
|
|
||||||
if(!W || !src) return
|
if(!O || !src) return
|
||||||
|
|
||||||
if(W.sharp) //Projectile is suitable for pinning.
|
if(O.sharp) //Projectile is suitable for pinning.
|
||||||
//Handles embedding for non-humans and simple_animals.
|
//Handles embedding for non-humans and simple_animals.
|
||||||
embed(O)
|
embed(O)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//Vox pinning weapon.
|
//Vox pinning weapon.
|
||||||
/obj/item/weapon/gun/launcher/spikethrower
|
/obj/item/weapon/gun/launcher/spikethrower
|
||||||
name = "Vox spike thrower"
|
name = "vox spike thrower"
|
||||||
desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
|
desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
|
||||||
|
|
||||||
var/last_regen = 0
|
var/last_regen = 0
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
projectile_type = /obj/item/projectile/energy/dart
|
projectile_type = /obj/item/projectile/energy/dart
|
||||||
|
|
||||||
/obj/item/weapon/gun/energy/crossbow/largecrossbow
|
/obj/item/weapon/gun/energy/crossbow/largecrossbow
|
||||||
name = "Energy Crossbow"
|
name = "energy crossbow"
|
||||||
desc = "A weapon favored by mercenary infiltration teams."
|
desc = "A weapon favored by mercenary infiltration teams."
|
||||||
w_class = 4
|
w_class = 4
|
||||||
force = 10
|
force = 10
|
||||||
|
|||||||
@@ -22,14 +22,10 @@
|
|||||||
/obj/item/weapon/gun/launcher/proc/update_release_force(obj/item/projectile)
|
/obj/item/weapon/gun/launcher/proc/update_release_force(obj/item/projectile)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
/obj/item/weapon/gun/launcher/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0)
|
/obj/item/weapon/gun/launcher/process_projectile(obj/item/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0)
|
||||||
if(!istype(projectile, /obj/item)) return 0
|
update_release_force(projectile)
|
||||||
|
projectile.loc = get_turf(user)
|
||||||
var/obj/item/I = projectile
|
projectile.throw_at(target, throw_distance, release_force, user)
|
||||||
|
|
||||||
update_release_force(I)
|
|
||||||
I.loc = get_turf(user)
|
|
||||||
I.throw_at(target, throw_distance, release_force, user)
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob)
|
/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
icon_state = "pneumatic-tank"
|
icon_state = "pneumatic-tank"
|
||||||
item_state = "pneumatic-tank"
|
item_state = "pneumatic-tank"
|
||||||
user.update_icons()
|
user.update_icons()
|
||||||
else if(W.w_class <= max_w_class)
|
else if(istype(W) && W.w_class <= max_w_class)
|
||||||
var/total_stored = 0
|
var/total_stored = 0
|
||||||
for(var/obj/item/O in src.contents)
|
for(var/obj/item/O in src.contents)
|
||||||
total_stored += O.w_class
|
total_stored += O.w_class
|
||||||
|
|||||||
135
code/modules/projectiles/guns/launcher/syringe_gun.dm
Normal file
135
code/modules/projectiles/guns/launcher/syringe_gun.dm
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/obj/item/weapon/syringe_cartridge
|
||||||
|
name = "compressed gas cartridge"
|
||||||
|
desc = "An impact-triggered compressed gas cartridge that can fitted to a syringe for rapid injection."
|
||||||
|
icon = 'icons/obj/ammo.dmi'
|
||||||
|
icon_state = "syringe-cartridge"
|
||||||
|
var/icon_flight = "syringe-cartridge-flight" //so it doesn't look so weird when shot
|
||||||
|
flags = CONDUCT
|
||||||
|
slot_flags = SLOT_BELT
|
||||||
|
throwforce = 3
|
||||||
|
force = 3
|
||||||
|
w_class = 1
|
||||||
|
var/obj/item/weapon/reagent_containers/syringe/syringe
|
||||||
|
var/primed = 0
|
||||||
|
|
||||||
|
/obj/item/weapon/syringe_cartridge/update_icon()
|
||||||
|
underlays.Cut()
|
||||||
|
if(syringe)
|
||||||
|
underlays += image(syringe.icon, src, syringe.icon_state)
|
||||||
|
underlays += syringe.filling
|
||||||
|
|
||||||
|
/obj/item/weapon/syringe_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
|
||||||
|
sharp = 1
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
/obj/item/weapon/syringe_cartridge/attack_self(mob/user)
|
||||||
|
if(syringe)
|
||||||
|
user << "<span class='notice'>You remove [syringe] from [src].</span>"
|
||||||
|
user.put_in_hands(syringe)
|
||||||
|
syringe = null
|
||||||
|
sharp = initial(sharp)
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
/obj/item/weapon/syringe_cartridge/proc/prime()
|
||||||
|
//the icon state will revert back when update_icon() is called from throw_impact()
|
||||||
|
icon_state = icon_flight
|
||||||
|
underlays.Cut()
|
||||||
|
primed = 1
|
||||||
|
|
||||||
|
/obj/item/weapon/syringe_cartridge/throw_impact(atom/hit_atom, var/speed)
|
||||||
|
..() //handles embedding for us. Should have a decent chance if thrown fast enough
|
||||||
|
if(syringe)
|
||||||
|
//check speed to see if we hit hard enough to trigger the rapid injection
|
||||||
|
//incidentally, this means syringe_cartridges can be used with the pneumatic launcher
|
||||||
|
if(speed >= 10 && primed && isliving(hit_atom))
|
||||||
|
var/mob/living/L = hit_atom
|
||||||
|
//unfortuately we don't know where the dart will actually hit, since that's done by the parent.
|
||||||
|
if(L.can_inject())
|
||||||
|
if(syringe.reagents)
|
||||||
|
syringe.reagents.trans_to(L, 15)
|
||||||
|
|
||||||
|
syringe.break_syringe(iscarbon(hit_atom)? hit_atom : null)
|
||||||
|
syringe.update_icon()
|
||||||
|
|
||||||
|
icon_state = initial(icon_state) //reset icon state
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/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
|
||||||
|
force = 7
|
||||||
|
matter = list("metal" = 2000)
|
||||||
|
slot_flags = SLOT_BELT
|
||||||
|
|
||||||
|
fire_sound = 'sound/weapons/empty.ogg'
|
||||||
|
fire_sound_text = "a metallic thunk"
|
||||||
|
recoil = 0
|
||||||
|
release_force = 10
|
||||||
|
throw_distance = 10
|
||||||
|
|
||||||
|
var/list/darts = list()
|
||||||
|
var/max_darts = 1
|
||||||
|
var/obj/item/weapon/syringe_cartridge/next
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/syringe/consume_next_projectile()
|
||||||
|
if(next)
|
||||||
|
next.prime()
|
||||||
|
return next
|
||||||
|
return null
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/syringe/handle_post_fire()
|
||||||
|
..()
|
||||||
|
darts -= next
|
||||||
|
next = null
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/syringe/attack_self(mob/living/user as mob)
|
||||||
|
if(next)
|
||||||
|
user.visible_message("[user] unlatches and carefully relax the bolt on [src].", "<span class='notice'>You unlatch and carefully relax the bolt on [src], unloading the spring.</span>")
|
||||||
|
next = null
|
||||||
|
else if(darts.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>")
|
||||||
|
next = darts[1]
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/syringe/attack_hand(mob/living/user as mob)
|
||||||
|
if(src in user)
|
||||||
|
if(!darts.len)
|
||||||
|
user << "<span class='warning'>[src] is empty.</span>"
|
||||||
|
return
|
||||||
|
if(next)
|
||||||
|
user << "<span class='warning'>The cover on [src] is locked shut.</span>"
|
||||||
|
return
|
||||||
|
var/obj/item/weapon/syringe_cartridge/C = darts[1]
|
||||||
|
darts -= C
|
||||||
|
user.put_in_hands(C)
|
||||||
|
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||||
|
else
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/syringe/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||||
|
if(istype(A, /obj/item/weapon/syringe_cartridge))
|
||||||
|
var/obj/item/weapon/syringe_cartridge/C = A
|
||||||
|
if(darts.len >= max_darts)
|
||||||
|
user << "<span class='warning'>[src] is full!</span>"
|
||||||
|
return
|
||||||
|
user.remove_from_mob(C)
|
||||||
|
C.loc = src
|
||||||
|
darts += C //add to the end
|
||||||
|
user.visible_message("[user] inserts \a [C] into [src].", "<span class='notice'>You insert \a [C] into [src].</span>")
|
||||||
|
else
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/item/weapon/gun/launcher/syringe/rapid
|
||||||
|
name = "rapid syringe gun"
|
||||||
|
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_darts = 4
|
||||||
@@ -78,12 +78,12 @@
|
|||||||
switch(AM.mag_type)
|
switch(AM.mag_type)
|
||||||
if(MAGAZINE)
|
if(MAGAZINE)
|
||||||
if(ammo_magazine)
|
if(ammo_magazine)
|
||||||
user << "<span class='warning'>[src] already has a magazine loaded!</span>" //already a magazine here
|
user << "<span class='warning'>[src] already has a magazine loaded.</span>" //already a magazine here
|
||||||
return
|
return
|
||||||
user.remove_from_mob(AM)
|
user.remove_from_mob(AM)
|
||||||
AM.loc = src
|
AM.loc = src
|
||||||
ammo_magazine = AM
|
ammo_magazine = AM
|
||||||
user.visible_message("[user] inserts [AM] into [src].", "<span class='notice'>You insert [AM] into [src]!</span>")
|
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)
|
playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||||
if(SPEEDLOADER)
|
if(SPEEDLOADER)
|
||||||
if(loaded.len >= max_shells)
|
if(loaded.len >= max_shells)
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way...
|
AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way...
|
||||||
count++
|
count++
|
||||||
if(count)
|
if(count)
|
||||||
user.visible_message("[user] reloads [src].", "<span class='notice'>You load [count] round\s into [src]!</span>")
|
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)
|
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
|
||||||
AM.update_icon()
|
AM.update_icon()
|
||||||
else if(istype(A, /obj/item/ammo_casing))
|
else if(istype(A, /obj/item/ammo_casing))
|
||||||
@@ -107,13 +107,13 @@
|
|||||||
if(!(load_method & SINGLE_CASING) || caliber != C.caliber)
|
if(!(load_method & SINGLE_CASING) || caliber != C.caliber)
|
||||||
return //incompatible
|
return //incompatible
|
||||||
if(loaded.len >= max_shells)
|
if(loaded.len >= max_shells)
|
||||||
user << "<span class='warning'>[src] is full!</span>"
|
user << "<span class='warning'>[src] is full.</span>"
|
||||||
return
|
return
|
||||||
|
|
||||||
user.remove_from_mob(C)
|
user.remove_from_mob(C)
|
||||||
C.loc = src
|
C.loc = src
|
||||||
loaded.Insert(1, C) //add to the head of the list
|
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>")
|
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)
|
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
|
||||||
|
|
||||||
update_icon()
|
update_icon()
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1)
|
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1)
|
||||||
if(ammo_magazine)
|
if(ammo_magazine)
|
||||||
user.put_in_hands(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>")
|
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)
|
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
|
||||||
ammo_magazine.update_icon()
|
ammo_magazine.update_icon()
|
||||||
ammo_magazine = null
|
ammo_magazine = null
|
||||||
@@ -138,14 +138,14 @@
|
|||||||
count++
|
count++
|
||||||
loaded.Cut()
|
loaded.Cut()
|
||||||
if(count)
|
if(count)
|
||||||
user.visible_message("[user] unloads [src].", "<span class='notice'>You unload [count] round\s from [src]!</span>")
|
user.visible_message("[user] unloads [src].", "<span class='notice'>You unload [count] round\s from [src].</span>")
|
||||||
else if(load_method & SINGLE_CASING)
|
else if(load_method & SINGLE_CASING)
|
||||||
var/obj/item/ammo_casing/C = loaded[loaded.len]
|
var/obj/item/ammo_casing/C = loaded[loaded.len]
|
||||||
loaded.len--
|
loaded.len--
|
||||||
user.put_in_hands(C)
|
user.put_in_hands(C)
|
||||||
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src]!</span>")
|
user.visible_message("[user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
|
||||||
else
|
else
|
||||||
user << "<span class='warning'>[src] is empty!</span>"
|
user << "<span class='warning'>[src] is empty.</span>"
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
|
/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob)
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
/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/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
|
|
||||||
force = 7
|
|
||||||
matter = list("metal" = 2000)
|
|
||||||
slot_flags = SLOT_BELT
|
|
||||||
|
|
||||||
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/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/projectile/syringe/handle_post_fire()
|
|
||||||
..()
|
|
||||||
chambered = null
|
|
||||||
max_shells = initial(max_shells)
|
|
||||||
|
|
||||||
/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. The spring still needs to be drawn between shots."
|
|
||||||
icon_state = "rapidsyringegun"
|
|
||||||
max_shells = 4
|
|
||||||
@@ -1312,7 +1312,7 @@ datum/design/item/weapon/rapidsyringe
|
|||||||
id = "rapidsyringe"
|
id = "rapidsyringe"
|
||||||
req_tech = list("combat" = 3, "materials" = 3, "engineering" = 3, "biotech" = 2)
|
req_tech = list("combat" = 3, "materials" = 3, "engineering" = 3, "biotech" = 2)
|
||||||
materials = list("$metal" = 5000, "$glass" = 1000)
|
materials = list("$metal" = 5000, "$glass" = 1000)
|
||||||
build_path = /obj/item/weapon/gun/projectile/syringe/rapid
|
build_path = /obj/item/weapon/gun/launcher/syringe/rapid
|
||||||
/*
|
/*
|
||||||
datum/design/item/weapon/largecrossbow
|
datum/design/item/weapon/largecrossbow
|
||||||
name = "Energy Crossbow"
|
name = "Energy Crossbow"
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
#define FIRE_MAX_FIRESUIT_STACKS 20 // If the number of stacks goes above this firesuits won't protect you anymore. If not, you can walk around while on fire like a badass.
|
#define FIRE_MAX_FIRESUIT_STACKS 20 // If the number of stacks goes above this firesuits won't protect you anymore. If not, you can walk around while on fire like a badass.
|
||||||
|
|
||||||
#define THROWFORCE_SPEED_DIVISOR 5 // The throwing speed value at which the throwforce multiplier is exactly 1.
|
#define THROWFORCE_SPEED_DIVISOR 5 // The throwing speed value at which the throwforce multiplier is exactly 1.
|
||||||
#define THROWNOBJ_KNOCKBACK_SPEED 15 // The minumum speed of a thrown object that will cause living mobs it hits to be knocked back.
|
#define THROWNOBJ_KNOCKBACK_SPEED 15 // The minumum speed of a w_class 2 thrown object that will cause living mobs it hits to be knocked back. Heavier objects can cause knockback at lower speeds.
|
||||||
#define THROWNOBJ_KNOCKBACK_DIVISOR 2 // Affects how much speed the mob is knocked back with.
|
#define THROWNOBJ_KNOCKBACK_DIVISOR 2 // Affects how much speed the mob is knocked back with.
|
||||||
|
|
||||||
#define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE.
|
#define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE.
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.9 KiB |
@@ -5795,7 +5795,7 @@
|
|||||||
"chw" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virologyaccess)
|
"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)
|
"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)
|
"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/projectile/syringe,/obj/item/weapon/storage/box/syringegun,/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/launcher/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)
|
"chA" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/research_port)
|
||||||
"chB" = (/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)
|
"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)
|
||||||
|
|||||||
Reference in New Issue
Block a user