attack chain migration: reagent containers (#28699)

* migrate reagent_containers.dm

* applicator migration + game test

* borg hypo migration

* condiment migration + game test

* fixed and expanded applicator game test, helper proc for puppet activate_self

* expanded condiment game test, added negative any_chatlog define

* drinks_base.dm migration

* bottle.dm migrated

* molotov migrated

* cans migrated

* drinking glass migrated

* shot glass migration

* bottles suck

* some fixes

* more bottle.dm

* bottles finally behave

* bottle fixed, shotglass fixed, everfull migrated

* bottle tests

* cyborg trashbag can crush autopickup is broken

* fixed cans insertion into backpacks

* added zone targeting to puppet

* more tests for drinks

* dropper migration

* dropper finished, removed a repeated proc

* smol tweak

* glass containers

* glass containers finished

* fixed can and bottle tests

* molotov test

* drinking glass and started shot glass

* fixed puppet activate_self + done with drinkingglass

* med containers, shuffle tests around a tiny bit

* fix autoinjectors

* remove return value from spawn block

* Apply suggestions from code review

Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

---------

Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: Toastical <toast@toaster.com>
Co-authored-by: Toastical <toastical@toaster.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
warriorstar-orion
2025-03-21 20:42:24 +00:00
committed by GitHub
co-authored by Burzah Toastical Toastical
parent 1df64695d1
commit 7eb404f562
30 changed files with 596 additions and 323 deletions
+24 -11
View File
@@ -14,6 +14,21 @@
var/has_lid = FALSE // Used for containers where we want to put lids on and off
var/temperature_min = 0 // To limit the temperature of a reagent container can atain when exposed to heat/cold
var/temperature_max = 10000
new_attack_chain = TRUE
/obj/item/reagent_containers/interact_with_atom(atom/target, mob/living/user, list/modifiers)
if(isliving(target) && mob_act(target, user))
return ITEM_INTERACT_COMPLETE
if(normal_act(target, user))
return ITEM_INTERACT_COMPLETE
return ..()
// Overriden inside its subtypes. Might add the basic container shit here (eg, beaker/bucket behaviour)
/obj/item/reagent_containers/proc/mob_act(mob/target, mob/living/user)
return FALSE
/obj/item/reagent_containers/proc/normal_act(atom/target, mob/living/user)
return FALSE
/obj/item/reagent_containers/proc/can_set_transfer_amount(mob/user)
if(!length(possible_transfer_amounts))
@@ -88,18 +103,16 @@
container_type |= REFILLABLE | DRAINABLE
update_icon(UPDATE_OVERLAYS)
/obj/item/reagent_containers/attack_self__legacy__attackchain(mob/user)
if(has_lid)
if(is_open_container())
to_chat(usr, "<span class='notice'>You put the lid on [src].</span>")
add_lid()
else
to_chat(usr, "<span class='notice'>You take the lid off [src].</span>")
remove_lid()
/obj/item/reagent_containers/activate_self(mob/user)
if(..() || !has_lid)
return
/obj/item/reagent_containers/attack__legacy__attackchain(mob/M, mob/user, def_zone)
if(user.a_intent == INTENT_HARM)
return ..()
if(is_open_container())
to_chat(usr, "<span class='notice'>You put the lid on [src].</span>")
add_lid()
else
to_chat(usr, "<span class='notice'>You take the lid off [src].</span>")
remove_lid()
/obj/item/reagent_containers/wash(mob/user, atom/source)
if(is_open_container())
@@ -11,6 +11,7 @@
container_type = REFILLABLE | AMOUNT_VISIBLE
temperature_min = 270
temperature_max = 350
var/delay = 10
var/ignore_flags = FALSE
var/applied_amount = 8 // How much it applies
var/applying = FALSE // So it can't be spammed.
@@ -72,8 +73,6 @@
if(applying)
to_chat(user, "<span class='warning'>You're already applying [src].</span>")
return
if(!iscarbon(M))
return
if(ignore_flags || M.can_inject(user, TRUE))
if(M == user)
@@ -83,7 +82,7 @@
if(M.reagents)
applying = TRUE
update_icon(UPDATE_ICON_STATE)
while(do_after(user, 10, target = M))
while(do_after(user, delay, target = M))
measured_health = M.health
apply_to(M, user, 1, FALSE)
if(measured_health == M.health)
@@ -96,11 +95,16 @@
update_icon()
user.changeNext_move(CLICK_CD_MELEE)
/obj/item/reagent_containers/applicator/attack__legacy__attackchain(mob/living/M, mob/user)
return apply(M, user)
/obj/item/reagent_containers/applicator/interact_with_atom(atom/target, mob/living/user, list/modifiers)
if(!iscarbon(target))
return ..()
apply(target, user)
return ITEM_INTERACT_COMPLETE
/obj/item/reagent_containers/applicator/attack_self__legacy__attackchain(mob/user)
return apply(user, user)
/obj/item/reagent_containers/applicator/activate_self(mob/user)
if(..() || !iscarbon(user))
return
apply(user, user)
/obj/item/reagent_containers/applicator/proc/apply_to(mob/living/carbon/M, mob/user, multiplier = 1, show_message = TRUE)
var/total_applied_amount = applied_amount * multiplier
@@ -88,28 +88,36 @@
robot.cell.use(charge_cost)
total_reagents = min((total_reagents + BORGHYPO_REFILL_VALUE), maximum_reagents)
/obj/item/reagent_containers/borghypo/attack__legacy__attackchain(mob/living/carbon/human/M, mob/user)
if(!total_reagents)
to_chat(user, "<span class='warning'>The injector is empty.</span>")
return
if(!istype(M))
return
if(total_reagents && M.can_inject(user, TRUE, user.zone_selected, penetrate_thick))
to_chat(user, "<span class='notice'>You inject [M] with the injector.</span>")
to_chat(M, "<span class='notice'>You feel a tiny prick!</span>")
/obj/item/reagent_containers/borghypo/interact_with_atom(atom/target, mob/living/user, list/modifiers)
if(ishuman(target))
var/mob/living/carbon/human/mob = target
if(!total_reagents)
to_chat(user, "<span class='warning'>The injector is empty.</span>")
return ITEM_INTERACT_COMPLETE
if(!mob.can_inject(user, TRUE, user.zone_selected, penetrate_thick))
return ITEM_INTERACT_COMPLETE
M.reagents.add_reagent(choosen_reagent, 5)
to_chat(user, "<span class='notice'>You inject [mob] with the injector.</span>")
to_chat(mob, "<span class='notice'>You feel a tiny prick!</span>")
mob.reagents.add_reagent(choosen_reagent, 5)
total_reagents = (total_reagents - 5)
if(M.reagents)
if(mob.reagents)
var/datum/reagent/injected = GLOB.chemical_reagents_list[choosen_reagent]
var/contained = injected.name
add_attack_logs(user, M, "Injected with [name] containing [contained], transfered [5] units", injected.harmless ? ATKLOG_ALMOSTALL : null)
add_attack_logs(user, mob, "Injected with [name] containing [contained], transfered [5] units", injected.harmless ? ATKLOG_ALMOSTALL : null)
to_chat(user, "<span class='notice'>[5] units injected. [total_reagents] units remaining.</span>")
return ITEM_INTERACT_COMPLETE
if(isliving(target)) // ignore non-human mobs
return ITEM_INTERACT_COMPLETE
/obj/item/reagent_containers/borghypo/proc/get_radial_contents()
return reagent_icons & reagent_ids
/obj/item/reagent_containers/borghypo/attack_self__legacy__attackchain(mob/user)
/obj/item/reagent_containers/borghypo/activate_self(mob/user)
if(..())
return
playsound(loc, 'sound/effects/pop.ogg', 50, 0)
var/selected_reagent = show_radial_menu(user, src, get_radial_contents(), radius = 48)
if(!selected_reagent)
@@ -18,12 +18,7 @@
else
icon_state = "[initial(icon_state)]1"
/obj/item/reagent_containers/dropper/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone)
return
/obj/item/reagent_containers/dropper/afterattack__legacy__attackchain(atom/target, mob/user, proximity)
if(!proximity)
return
/obj/item/reagent_containers/dropper/mob_act(mob/target, mob/living/user)
var/to_transfer = 0
if(iscarbon(target))
var/mob/living/carbon/C = target
@@ -67,34 +62,37 @@
to_transfer = reagents.trans_to(C, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [to_transfer] units of the solution.</span>")
if(isobj(target))
if(!target.reagents)
/obj/item/reagent_containers/dropper/normal_act(atom/target, mob/living/user)
. = FALSE
var/to_transfer = 0
if(!target.reagents)
return
if(reagents.total_volume)
if(!target.is_open_container() && !(isfood(target) && !ispill(target)) && !istype(target, /obj/item/clothing/mask/cigarette))
to_chat(user, "<span class='warning'>You cannot directly fill this object.</span>")
return
if(reagents.total_volume)
if(!target.is_open_container() && !(isfood(target) && !ispill(target)) && !istype(target, /obj/item/clothing/mask/cigarette))
to_chat(user, "<span class='warning'>You cannot directly fill this object.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
to_transfer = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [to_transfer] units of the solution.</span>")
to_transfer = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [to_transfer] units of the solution.</span>")
else
if(!target.is_open_container() && !istype(target, /obj/structure/reagent_dispensers))
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target].</span>")
return
else
if(!target.is_open_container() && !istype(target, /obj/structure/reagent_dispensers))
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target].</span>")
return
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty.</span>")
return
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty.</span>")
return
to_transfer = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_transfer = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [to_transfer] units of the solution.</span>")
to_chat(user, "<span class='notice'>You fill [src] with [to_transfer] units of the solution.</span>")
return TRUE
/obj/item/reagent_containers/dropper/cyborg
name = "Industrial Dropper"
@@ -113,10 +111,10 @@
//Syndicate item. Virus transmitting mini hypospray
/obj/item/reagent_containers/dropper/precision/viral_injector
/obj/item/reagent_containers/dropper/precision/viral_injector/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone)
if(M.can_inject(user, TRUE))
to_chat(user, "<span class='warning'>You stealthily stab [M] with [src].</span>")
if(reagents.total_volume && M.reagents)
/obj/item/reagent_containers/dropper/precision/viral_injector/mob_act(mob/living/target, mob/living/user)
if(target.can_inject(user, TRUE))
to_chat(user, "<span class='warning'>You stealthily stab [target] with [src].</span>")
if(reagents.total_volume && target.reagents)
var/list/injected = list()
for(var/datum/reagent/R in reagents.reagent_list)
injected += R.name
@@ -135,10 +133,10 @@
virusData += " ([english_list(english_symptoms)])"
virList += virusData
var/str = english_list(virList)
add_attack_logs(user, M, "Infected with [str].")
add_attack_logs(user, target, "Infected with [str].")
reagents.reaction(M, REAGENT_INGEST, reagents.total_volume)
reagents.trans_to(M, 1)
reagents.reaction(target, REAGENT_INGEST, reagents.total_volume)
reagents.trans_to(target, 1)
var/contained = english_list(injected)
add_attack_logs(user, M, "Injected with [src] containing ([contained])")
add_attack_logs(user, target, "Injected with [src] containing ([contained])")
@@ -27,58 +27,53 @@
. += "<span class='notice'>[src] can hold up to [reagents.maximum_volume] units.</span>"
/obj/item/reagent_containers/glass/attack__legacy__attackchain(mob/M, mob/user, def_zone)
/obj/item/reagent_containers/glass/mob_act(mob/target, mob/living/user)
if(!is_open_container())
return ..()
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(istype(M))
if(istype(target))
var/list/transferred = list()
for(var/datum/reagent/R in reagents.reagent_list)
transferred += R.name
var/contained = english_list(transferred)
if(user.a_intent == INTENT_HARM)
M.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [M]!</span>", \
"<span class='userdanger'>[user] splashes the contents of [src] onto [M]!</span>")
add_attack_logs(user, M, "Splashed with [name] containing [contained]", !!M.ckey ? null : ATKLOG_ALL)
target.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
"<span class='userdanger'>[user] splashes the contents of [src] onto [target]!</span>")
add_attack_logs(user, target, "Splashed with [name] containing [contained]", !!target.ckey ? null : ATKLOG_ALL)
reagents.reaction(M, REAGENT_TOUCH)
reagents.reaction(target, REAGENT_TOUCH)
reagents.clear_reagents()
else
if(!iscarbon(M)) // Non-carbons can't process reagents
to_chat(user, "<span class='warning'>You cannot find a way to feed [M].</span>")
if(!iscarbon(target)) // Non-carbons can't process reagents
to_chat(user, "<span class='warning'>You cannot find a way to feed [target].</span>")
return
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
if(target != user)
target.visible_message("<span class='danger'>[user] attempts to feed something to [target].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
if(!do_mob(user, M))
if(!do_mob(user, target))
return
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
M.visible_message("<span class='danger'>[user] feeds something to [M].</span>", "<span class='userdanger'>[user] feeds something to you.</span>")
add_attack_logs(user, M, "Fed with [name] containing [contained]", !!M.ckey ? null : ATKLOG_ALL)
target.visible_message("<span class='danger'>[user] feeds something to [target].</span>", "<span class='userdanger'>[user] feeds something to you.</span>")
add_attack_logs(user, target, "Fed with [name] containing [contained]", !!target.ckey ? null : ATKLOG_ALL)
else
to_chat(user, "<span class='notice'>You swallow a gulp of [src].</span>")
var/fraction = min(5 / reagents.total_volume, 1)
reagents.reaction(M, REAGENT_INGEST, fraction)
addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), M, 5), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
reagents.reaction(target, REAGENT_INGEST, fraction)
addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), target, 5), 5)
playsound(target.loc,'sound/items/drink.ogg', rand(10,50), TRUE)
/obj/item/reagent_containers/glass/afterattack__legacy__attackchain(obj/target, mob/user, proximity)
if((!proximity) || !check_allowed_items(target, target_self = TRUE))
return
if(!is_open_container())
return
if(!reagents)
/obj/item/reagent_containers/glass/normal_act(atom/target, mob/living/user)
if(!check_allowed_items(target, target_self = TRUE) || !is_open_container() || !reagents)
return
. = TRUE
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
@@ -110,13 +105,13 @@
reagents.reaction(target, REAGENT_TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/glass/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(is_pen(I))
var/t = rename_interactive(user, I)
/obj/item/reagent_containers/glass/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(is_pen(used))
var/t = rename_interactive(user, used)
if(!isnull(t))
label_text = t
else
return ..()
return ITEM_INTERACT_COMPLETE
return ..()
/obj/item/reagent_containers/glass/beaker
name = "beaker"
@@ -178,17 +173,17 @@
if(reagents)
reagents.temperature_reagents(4000)
/obj/item/reagent_containers/glass/beaker/attackby__legacy__attackchain(obj/item/W, mob/user, params)
if(istype(W, /obj/item/assembly_holder) && can_assembly)
/obj/item/reagent_containers/glass/beaker/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(istype(used, /obj/item/assembly_holder) && can_assembly)
if(assembly)
to_chat(usr, "<span class='warning'>[src] already has an assembly.</span>")
return ..()
assembly = W
user.drop_item()
W.forceMove(src)
update_icon(UPDATE_OVERLAYS)
else
..()
else
assembly = used
user.drop_item()
used.forceMove(src)
update_icon(UPDATE_OVERLAYS)
return ITEM_INTERACT_COMPLETE
return ..()
/obj/item/reagent_containers/glass/beaker/HasProximity(atom/movable/AM)
if(assembly)
@@ -332,19 +327,19 @@
reagents.reaction(user, REAGENT_TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/glass/bucket/attackby__legacy__attackchain(obj/D, mob/user, params)
if(istype(D, /obj/item/mop))
var/obj/item/mop/m = D
m.wet_mop(src, user)
return
if(isprox(D))
to_chat(user, "You add [D] to [src].")
qdel(D)
/obj/item/reagent_containers/glass/bucket/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(istype(used, /obj/item/mop))
var/obj/item/mop/mop = used
mop.wet_mop(src, user)
return ITEM_INTERACT_COMPLETE
if(isprox(used))
to_chat(user, "<span class='notice'>You add [used] to [src].</span>")
qdel(used)
user.put_in_hands(new /obj/item/bucket_sensor)
user.unequip(src)
qdel(src)
else
..()
return ITEM_INTERACT_COMPLETE
return ..()
/obj/item/reagent_containers/glass/beaker/waterbottle
name = "bottle of water"
@@ -69,16 +69,20 @@
reagents.reaction(M, REAGENT_INGEST, 0.1)
return TRUE
/obj/item/reagent_containers/hypospray/attack__legacy__attackchain(mob/living/M, mob/user)
return apply(M, user)
/obj/item/reagent_containers/hypospray/mob_act(mob/target, mob/living/user)
apply(target, user)
return TRUE
/obj/item/reagent_containers/hypospray/attack_self__legacy__attackchain(mob/user)
return apply(user, user)
/obj/item/reagent_containers/hypospray/activate_self(mob/user)
if(..())
return FINISH_ATTACK
/obj/item/reagent_containers/hypospray/attackby__legacy__attackchain(obj/item/I, mob/user, params)
apply(user, user)
/obj/item/reagent_containers/hypospray/item_interaction(mob/living/user, obj/item/I, list/modifiers)
if(is_pen(I))
rename_interactive(user, I, use_prefix = TRUE, prompt = "Give [src] a title.")
return TRUE
return ITEM_INTERACT_COMPLETE
return ..()
@@ -189,18 +193,16 @@
container_type = DRAWABLE
flags = null
/obj/item/reagent_containers/hypospray/autoinjector/attack__legacy__attackchain(mob/M, mob/user)
/obj/item/reagent_containers/hypospray/autoinjector/mob_act(mob/target, mob/living/user)
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
..()
return TRUE
. = ..()
update_icon(UPDATE_ICON_STATE)
return TRUE
/obj/item/reagent_containers/hypospray/autoinjector/attack_self__legacy__attackchain(mob/user)
..()
/obj/item/reagent_containers/hypospray/autoinjector/activate_self(mob/user)
. = ..()
update_icon(UPDATE_ICON_STATE)
return TRUE
/obj/item/reagent_containers/hypospray/autoinjector/update_icon_state()
if(reagents.total_volume > 0)
@@ -268,9 +270,9 @@
volume = 40
list_reagents = list("nanocalcium" = 30, "epinephrine" = 10)
/obj/item/reagent_containers/hypospray/autoinjector/nanocalcium/attack__legacy__attackchain(mob/living/M, mob/user)
/obj/item/reagent_containers/hypospray/autoinjector/nanocalcium/apply(mob/living/M, mob/user)
if(..())
playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 20, 1)
playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 20, TRUE)
/obj/item/reagent_containers/hypospray/autoinjector/zombiecure
name = "\improper Anti-Plague Sequence Alpha autoinjector"
@@ -281,7 +283,7 @@
container_type = null //No sucking out the reagent
list_reagents = list("zombiecure1" = 15)
/obj/item/reagent_containers/hypospray/autoinjector/zombiecure/attack__legacy__attackchain(mob/living/M, mob/user)
/obj/item/reagent_containers/hypospray/autoinjector/zombiecure/apply(mob/living/M, mob/user)
if(..())
playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 20, TRUE) //Sucker for sounds, also gets zombies attention.
@@ -16,6 +16,7 @@
var/label_text
var/mode = IV_INJECT
var/mob/living/carbon/human/injection_target
var/injection_action_delay = 3 SECONDS
/obj/item/reagent_containers/iv_bag/Destroy()
end_processing()
@@ -32,8 +33,10 @@
..()
update_icon(UPDATE_OVERLAYS)
/obj/item/reagent_containers/iv_bag/attack_self__legacy__attackchain(mob/user)
..()
/obj/item/reagent_containers/iv_bag/activate_self(mob/user)
if(..())
return
mode = !mode
update_icon(UPDATE_OVERLAYS)
@@ -87,12 +90,7 @@
injection_target.reagents.trans_id_to(src, reagent.id, amount_per_transfer_from_this / 10)
update_icon(UPDATE_OVERLAYS)
/obj/item/reagent_containers/iv_bag/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone)
return
/obj/item/reagent_containers/iv_bag/afterattack__legacy__attackchain(atom/target, mob/user, proximity)
if(!proximity)
return
/obj/item/reagent_containers/iv_bag/mob_act(mob/target, mob/living/user)
if(!target.reagents)
return
@@ -105,7 +103,7 @@
if(L != user)
L.visible_message("<span class='danger'>[user] is trying to remove [src]'s needle from [L]'s arm!</span>", \
"<span class='userdanger'>[user] is trying to remove [src]'s needle from [L]'s arm!</span>")
if(!do_mob(user, L))
if(!do_mob(user, L, injection_action_delay))
return
L.visible_message("<span class='danger'>[user] removes [src]'s needle from [L]'s arm!</span>", \
"<span class='userdanger'>[user] removes [src]'s needle from [L]'s arm!</span>")
@@ -119,7 +117,7 @@
if(L != user)
L.visible_message("<span class='danger'>[user] is trying to insert [src]'s needle into [L]'s arm!</span>", \
"<span class='userdanger'>[user] is trying to insert [src]'s needle into [L]'s arm!</span>")
if(!do_mob(user, L))
if(!do_mob(user, L, injection_action_delay))
return
L.visible_message("<span class='danger'>[user] inserts [src]'s needle into [L]'s arm!</span>", \
"<span class='userdanger'>[user] inserts [src]'s needle into [L]'s arm!</span>")
@@ -157,9 +155,10 @@
if(IV_INJECT)
. += "inject"
/obj/item/reagent_containers/iv_bag/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(is_pen(I))
rename_interactive(user, I)
/obj/item/reagent_containers/iv_bag/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(is_pen(used))
rename_interactive(user, used)
return ITEM_INTERACT_COMPLETE
// PRE-FILLED IV BAGS BELOW
@@ -12,11 +12,9 @@
var/instant_application = FALSE
var/needs_to_apply_reagents = TRUE
/obj/item/reagent_containers/patch/attack__legacy__attackchain(mob/living/carbon/C, mob/user)
return apply(C, user)
/obj/item/reagent_containers/patch/attack_self__legacy__attackchain(mob/user)
return apply(user, user)
/obj/item/reagent_containers/patch/mob_act(mob/target, mob/living/user)
if(!apply(target, user))
return ITEM_INTERACT_COMPLETE
/obj/item/reagent_containers/patch/proc/apply(mob/living/carbon/C, mob/user)
if(!istype(C))
@@ -47,14 +47,13 @@
qdel(src)
return TRUE
/obj/item/reagent_containers/pill/attack__legacy__attackchain(mob/living/carbon/C, mob/user)
return apply(C, user)
/obj/item/reagent_containers/pill/mob_act(mob/target, mob/living/user)
apply(target, user)
return TRUE
/obj/item/reagent_containers/pill/attack_self__legacy__attackchain(mob/user)
return apply(user, user)
/obj/item/reagent_containers/pill/afterattack__legacy__attackchain(obj/target, mob/user, proximity)
if(!proximity || !target.is_refillable())
/obj/item/reagent_containers/pill/normal_act(atom/target, mob/living/user)
. = TRUE
if(!target.is_refillable())
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
@@ -23,7 +23,8 @@
. = ..()
ADD_TRAIT(src, TRAIT_CAN_POINT_WITH, ROUNDSTART_TRAIT)
/obj/item/reagent_containers/spray/afterattack__legacy__attackchain(atom/A, mob/user)
/obj/item/reagent_containers/spray/normal_act(atom/A, mob/living/user)
. = TRUE
if(isstorage(A) || ismodcontrol(A) || istype(A, /obj/structure/table) || istype(A, /obj/structure/rack) || istype(A, /obj/structure/closet) \
|| istype(A, /obj/item/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
@@ -86,7 +87,9 @@
chem_puff.RegisterSignal(our_loop, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/obj/effect/decal/chempuff, loop_ended))
chem_puff.RegisterSignal(our_loop, COMSIG_MOVELOOP_POSTPROCESS, TYPE_PROC_REF(/obj/effect/decal/chempuff, check_move))
/obj/item/reagent_containers/spray/attack_self__legacy__attackchain(mob/user)
/obj/item/reagent_containers/spray/activate_self(mob/user)
if(..())
return FINISH_ATTACK
amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10)
spray_currentrange = (spray_currentrange == 1 ? spray_maxrange : 1)
@@ -126,7 +129,9 @@
amount_per_transfer_from_this = 10
list_reagents = list("cleaner" = 250)
/obj/item/reagent_containers/spray/cleaner/attack_self__legacy__attackchain(mob/user)
/obj/item/reagent_containers/spray/cleaner/activate_self(mob/user)
if(..())
return
amount_per_transfer_from_this = (amount_per_transfer_from_this == 5 ? 10 : 5)
spray_currentrange = (spray_currentrange == 1 ? spray_maxrange : 1)
to_chat(user, "<span class='notice'>You [amount_per_transfer_from_this == 5 ? "remove" : "fix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray.</span>")
@@ -206,8 +211,10 @@
volume = 10
list_reagents = list("water" = 10)
/obj/item/reagent_containers/spray/waterflower/attack_self__legacy__attackchain(mob/user) //Don't allow changing how much the flower sprays
return
/obj/item/reagent_containers/spray/waterflower/Initialize(mapload)
. = ..()
// Don't allow changing how much the flower sprays
RegisterSignal(src, COMSIG_ACTIVATE_SELF, TYPE_PROC_REF(/datum, signal_cancel_activate_self))
//chemsprayer
/obj/item/reagent_containers/spray/chemsprayer
@@ -262,7 +269,9 @@
/obj/item/reagent_containers/spray/chemsprayer/attack_self__legacy__attackchain(mob/user)
/obj/item/reagent_containers/spray/chemsprayer/activate_self(mob/user)
if(..())
return
amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10)
to_chat(user, "<span class='notice'>You adjust the output switch. You'll now use [amount_per_transfer_from_this] units per spray.</span>")
@@ -15,6 +15,7 @@
container_type = TRANSPARENT
///If this variable is true, the syringe will work through hardsuits / modsuits / biosuits.
var/penetrates_thick = FALSE
var/syringe_draw_time = 3 SECONDS
/obj/item/reagent_containers/syringe/Initialize(mapload)
. = ..()
@@ -38,7 +39,10 @@
..()
update_icon()
/obj/item/reagent_containers/syringe/attack_self__legacy__attackchain(mob/user)
/obj/item/reagent_containers/syringe/activate_self(mob/user)
if(..())
return
mode = !mode
update_icon()
@@ -46,16 +50,8 @@
..()
update_icon()
/obj/item/reagent_containers/syringe/attack__legacy__attackchain(mob/living/M, mob/living/user, def_zone)
return
/obj/item/reagent_containers/syringe/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(istype(I, /obj/item/storage/bag))
..()
/obj/item/reagent_containers/syringe/afterattack__legacy__attackchain(atom/target, mob/user , proximity)
if(!proximity)
return
/obj/item/reagent_containers/syringe/mob_act(mob/target, mob/living/user)
. = TRUE
if(!target.reagents)
return
@@ -78,7 +74,7 @@
target.visible_message("<span class='danger'>[user] is trying to take a blood sample from [target]!</span>", \
"<span class='userdanger'>[user] is trying to take a blood sample from [target]!</span>")
busy = TRUE
if(!do_mob(user, target))
if(!do_mob(user, target, syringe_draw_time))
busy = FALSE
return
if(reagents.holder_full())