Files
Polaris/code/modules/reagents/reagent_containers/syringes.dm
Neerti 828dacf485 Centralizes weight class definitions
A lot of new defines are now in inventory_sizes.dm, which contains;
All the size identifiers (the thing that tells the game if something is bulky, or w/e).
Storage costs for all the sizes, which are exponents of two, as previously.
A few constants for inventory size.

Also changes all storage item's capacity definitions by basing it off of how many 'normal slots' exist for it.  This allows one to change the definition for all of the defines in the file, and everything will follow along without needing to change 500 files.  In testing, I made all ITEMSIZE_COST_* defines doubled, and nothing had broke.

The benefit of doing all of this is that it makes adding new weight classes in the future much simpler, and makes knowing how much space a container has easier, as seeing ITEMSIZE_COST_NORMAL * 7 means it can hold seven normal items.
2016-09-22 00:51:51 -04:00

365 lines
12 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
/// Syringes.
////////////////////////////////////////////////////////////////////////////////
#define SYRINGE_DRAW 0
#define SYRINGE_INJECT 1
#define SYRINGE_BROKEN 2
/obj/item/weapon/reagent_containers/syringe
name = "syringe"
desc = "A syringe."
icon = 'icons/obj/syringe.dmi'
item_state = "syringe_0"
icon_state = "0"
matter = list("glass" = 150)
amount_per_transfer_from_this = 5
possible_transfer_amounts = null
volume = 15
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
sharp = 1
unacidable = 1 //glass
var/mode = SYRINGE_DRAW
var/image/filling //holds a reference to the current filling overlay
var/visible_name = "a syringe"
var/time = 30
/obj/item/weapon/reagent_containers/syringe/on_reagent_change()
update_icon()
/obj/item/weapon/reagent_containers/syringe/pickup(mob/user)
..()
update_icon()
/obj/item/weapon/reagent_containers/syringe/dropped(mob/user)
..()
update_icon()
/obj/item/weapon/reagent_containers/syringe/attack_self(mob/user as mob)
switch(mode)
if(SYRINGE_DRAW)
mode = SYRINGE_INJECT
if(SYRINGE_INJECT)
mode = SYRINGE_DRAW
if(SYRINGE_BROKEN)
return
update_icon()
/obj/item/weapon/reagent_containers/syringe/attack_hand()
..()
update_icon()
/obj/item/weapon/reagent_containers/syringe/attackby(obj/item/I as obj, mob/user as mob)
return
/obj/item/weapon/reagent_containers/syringe/do_surgery(mob/living/carbon/M, mob/living/user)
if(user.a_intent == I_HURT)
return 0
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
return ..()
afterattack(M, user, 1)
return 1
/obj/item/weapon/reagent_containers/syringe/afterattack(obj/target, mob/user, proximity)
if(!proximity || !target.reagents)
return
if(mode == SYRINGE_BROKEN)
user << "<span class='warning'>This syringe is broken!</span>"
return
if(user.a_intent == I_HURT && ismob(target))
if((CLUMSY in user.mutations) && prob(50))
target = user
syringestab(target, user)
return
switch(mode)
if(SYRINGE_DRAW)
if(!reagents.get_free_space())
user << "<span class='warning'>The syringe is full.</span>"
mode = SYRINGE_INJECT
return
if(ismob(target))//Blood!
if(reagents.has_reagent("blood"))
user << "<span class='notice'>There is already a blood sample in this syringe.</span>"
return
if(istype(target, /mob/living/carbon))
if(istype(target, /mob/living/carbon/slime))
user << "<span class='warning'>You are unable to locate any blood.</span>"
return
var/amount = reagents.get_free_space()
var/mob/living/carbon/T = target
if(!T.dna)
user << "<span class='warning'>You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum).</span>"
return
if(NOCLONE in T.mutations) //target done been et, no more blood in him
user << "<span class='warning'>You are unable to locate any blood.</span>"
return
var/datum/reagent/B
if(istype(T, /mob/living/carbon/human))
var/mob/living/carbon/human/H = T
if(H.species && !H.should_have_organ(O_HEART))
H.reagents.trans_to_obj(src, amount)
else
B = T.take_blood(src, amount)
else
B = T.take_blood(src,amount)
if (B)
reagents.reagent_list += B
reagents.update_total()
on_reagent_change()
reagents.handle_reactions()
user << "<span class='notice'>You take a blood sample from [target].</span>"
for(var/mob/O in viewers(4, user))
O.show_message("<span class='notice'>[user] takes a blood sample from [target].</span>", 1)
else //if not mob
if(!target.reagents.total_volume)
user << "<span class='notice'>[target] is empty.</span>"
return
if(!target.is_open_container() && !istype(target, /obj/structure/reagent_dispensers) && !istype(target, /obj/item/slime_extract))
user << "<span class='notice'>You cannot directly remove reagents from this object.</span>"
return
var/trans = target.reagents.trans_to_obj(src, amount_per_transfer_from_this)
user << "<span class='notice'>You fill the syringe with [trans] units of the solution.</span>"
update_icon()
if(!reagents.get_free_space())
mode = SYRINGE_INJECT
update_icon()
if(SYRINGE_INJECT)
if(!reagents.total_volume)
user << "<span class='notice'>The syringe is empty.</span>"
mode = SYRINGE_DRAW
return
if(istype(target, /obj/item/weapon/implantcase/chem))
return
if(!target.is_open_container() && !ismob(target) && !istype(target, /obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/slime_extract) && !istype(target, /obj/item/clothing/mask/smokable/cigarette) && !istype(target, /obj/item/weapon/storage/fancy/cigarettes))
user << "<span class='notice'>You cannot directly fill this object.</span>"
return
if(!target.reagents.get_free_space())
user << "<span class='notice'>[target] is full.</span>"
return
var/mob/living/carbon/human/H = target
if(istype(H))
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
if(!affected)
user << "<span class='danger'>\The [H] is missing that limb!</span>"
return
else if(affected.robotic >= ORGAN_ROBOT)
user << "<span class='danger'>You cannot inject a robotic limb.</span>"
return
if(ismob(target) && target != user)
var/injtime = time //Injecting through a hardsuit takes longer due to needing to find a port.
if(istype(H))
if(H.wear_suit)
if(istype(H.wear_suit, /obj/item/clothing/suit/space))
injtime = injtime * 2
else if(!H.can_inject(user, 1))
return
else if(isliving(target))
var/mob/living/M = target
if(!M.can_inject(user, 1))
return
if(injtime == time)
user.visible_message("<span class='warning'>[user] is trying to inject [target] with [visible_name]!</span>")
else
user.visible_message("<span class='warning'>[user] begins hunting for an injection port on [target]'s suit!</span>")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
if(!do_mob(user, target, injtime))
return
user.visible_message("<span class='warning'>[user] injects [target] with the syringe!</span>")
var/trans
if(ismob(target))
var/contained = reagentlist()
trans = reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
admin_inject_log(user, target, src, contained, trans)
else
trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units.</span>"
if (reagents.total_volume <= 0 && mode == SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
return
/obj/item/weapon/reagent_containers/syringe/update_icon()
overlays.Cut()
if(mode == SYRINGE_BROKEN)
icon_state = "broken"
return
var/rounded_vol = round(reagents.total_volume, round(reagents.maximum_volume / 3))
if(ismob(loc))
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "inject"
overlays += injoverlay
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(reagents.total_volume)
filling = image('icons/obj/reagentfillings.dmi', src, "syringe10")
filling.icon_state = "syringe[rounded_vol]"
filling.color = reagents.get_color()
overlays += filling
/obj/item/weapon/reagent_containers/syringe/proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob)
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
var/target_zone = ran_zone(check_zone(user.zone_sel.selecting, target))
var/obj/item/organ/external/affecting = H.get_organ(target_zone)
if (!affecting || affecting.is_stump())
user << "<span class='danger'>They are missing that limb!</span>"
return
var/hit_area = affecting.name
if((user != target) && H.check_shields(7, src, user, "\the [src]"))
return
if (target != user && H.getarmor(target_zone, "melee") > 5 && prob(50))
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!</B>"), 1)
user.remove_from_mob(src)
qdel(src)
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [target.name] ([target.ckey]) with \the [src] (INTENT: HARM).</font>"
target.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: HARM).</font>"
msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(target)] with [src.name] (INTENT: HARM) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
return
user.visible_message("<span class='danger'>[user] stabs [target] in \the [hit_area] with [src.name]!</span>")
if(affecting.take_damage(3))
H.UpdateDamageIcon()
else
user.visible_message("<span class='danger'>[user] stabs [target] with [src.name]!</span>")
target.take_organ_damage(3)// 7 is the same as crowbar punch
var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand
var/contained_reagents = reagents.get_reagents()
var/trans = reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD)
if(isnull(trans)) trans = 0
admin_inject_log(user, target, src, contained_reagents, trans, violent=1)
break_syringe(target, user)
/obj/item/weapon/reagent_containers/syringe/proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user)
desc += " It is broken."
mode = SYRINGE_BROKEN
if(target)
add_blood(target)
if(user)
add_fingerprint(user)
update_icon()
/obj/item/weapon/reagent_containers/syringe/ld50_syringe
name = "Lethal Injection Syringe"
desc = "A syringe used for lethal injections."
amount_per_transfer_from_this = 50
volume = 50
visible_name = "a giant syringe"
time = 300
/obj/item/weapon/reagent_containers/syringe/ld50_syringe/afterattack(obj/target, mob/user, flag)
if(mode == SYRINGE_DRAW && ismob(target)) // No drawing 50 units of blood at once
user << "<span class='notice'>This needle isn't designed for drawing blood.</span>"
return
if(user.a_intent == "hurt" && ismob(target)) // No instant injecting
user << "<span class='notice'>This syringe is too big to stab someone with it.</span>"
..()
////////////////////////////////////////////////////////////////////////////////
/// Syringes. END
////////////////////////////////////////////////////////////////////////////////
/obj/item/weapon/reagent_containers/syringe/inaprovaline
name = "Syringe (inaprovaline)"
desc = "Contains inaprovaline - used to stabilize patients."
/obj/item/weapon/reagent_containers/syringe/inaprovaline/New()
..()
reagents.add_reagent("inaprovaline", 15)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/antitoxin
name = "Syringe (anti-toxin)"
desc = "Contains anti-toxins."
/obj/item/weapon/reagent_containers/syringe/antitoxin/New()
..()
reagents.add_reagent("anti_toxin", 15)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/antiviral
name = "Syringe (spaceacillin)"
desc = "Contains antiviral agents."
/obj/item/weapon/reagent_containers/syringe/antiviral/New()
..()
reagents.add_reagent("spaceacillin", 15)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/drugs
name = "Syringe (drugs)"
desc = "Contains aggressive drugs meant for torture."
/obj/item/weapon/reagent_containers/syringe/drugs/New()
..()
reagents.add_reagent("space_drugs", 5)
reagents.add_reagent("mindbreaker", 5)
reagents.add_reagent("cryptobiolin", 5)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral/New()
..()
reagents.add_reagent("chloralhydrate", 50)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/steroid
name = "Syringe (anabolic steroids)"
desc = "Contains drugs for muscle growth."
/obj/item/weapon/reagent_containers/syringe/steroid/New()
..()
reagents.add_reagent("adrenaline",5)
reagents.add_reagent("hyperzine",10)