This commit is contained in:
Putnam
2020-01-14 03:27:03 -08:00
1098 changed files with 194826 additions and 196589 deletions
@@ -92,8 +92,15 @@
/obj/machinery/chem_dispenser/Initialize()
. = ..()
for(var/list/L in list(dispensable_reagents, emagged_reagents, upgrade_reagents, upgrade_reagents2, upgrade_reagents3))
L = sortList(L, /proc/cmp_reagents_asc)
if(emagged_reagents)
emagged_reagents = sortList(emagged_reagents, /proc/cmp_reagents_asc)
if(upgrade_reagents)
upgrade_reagents = sortList(upgrade_reagents, /proc/cmp_reagents_asc)
if(upgrade_reagents2)
upgrade_reagents2 = sortList(upgrade_reagents2, /proc/cmp_reagents_asc)
if(upgrade_reagents3)
upgrade_reagents3 = sortList(upgrade_reagents3, /proc/cmp_reagents_asc)
dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc)
update_icon()
/obj/machinery/chem_dispenser/Destroy()
@@ -709,3 +709,41 @@
id = /datum/reagent/carpet/royalblue
results = list(/datum/reagent/carpet/royalblue = 2)
required_reagents = list(/datum/reagent/carpet = 1, /datum/reagent/medicine/clonexadone = 1)
//////////////////////////////////// Glitter ///////////////////////////////////////////
/datum/chemical_reaction/white_glitter/blue
name = "white glitter from blue"
id = "white_glitter_blue"
results = list(/datum/reagent/glitter/white = 2)
required_reagents = list(/datum/reagent/glitter/blue = 1, /datum/reagent/colorful_reagent/crayonpowder/white = 1)
/datum/chemical_reaction/white_glitter/pink
name = "white glitter from pink"
id = "white_glitter_pink"
results = list(/datum/reagent/glitter/white = 2)
required_reagents = list(/datum/reagent/glitter/pink = 1, /datum/reagent/colorful_reagent/crayonpowder/white = 1)
/datum/chemical_reaction/pink_glitter/blue
name = "pink glitter from blue"
id = "pink_glitter_blue"
results = list(/datum/reagent/glitter/pink = 2)
required_reagents = list(/datum/reagent/glitter/blue = 1, /datum/reagent/colorful_reagent/crayonpowder/red = 1)
/datum/chemical_reaction/pink_glitter/white
name = "pink glitter from white"
id = "pink_glitter_white"
results = list(/datum/reagent/glitter/pink = 2)
required_reagents = list(/datum/reagent/glitter/white = 1, /datum/reagent/colorful_reagent/crayonpowder/red = 1)
/datum/chemical_reaction/blue_glitter/pink
name = "blue glitter from pink"
id = "blue_glitter_pink"
results = list(/datum/reagent/glitter/blue = 2)
required_reagents = list(/datum/reagent/glitter/pink = 1, /datum/reagent/colorful_reagent/crayonpowder/blue = 1)
/datum/chemical_reaction/blue_glitter/white
name = "blue glitter from white"
id = "blue_glitter_white"
results = list(/datum/reagent/glitter/blue = 2)
required_reagents = list(/datum/reagent/glitter/white = 1, /datum/reagent/colorful_reagent/crayonpowder/blue = 1)
+246 -246
View File
@@ -1,246 +1,246 @@
#define PH_WEAK (1 << 0)
#define TEMP_WEAK (1 << 1)
/obj/item/reagent_containers
name = "Container"
desc = "..."
icon = 'icons/obj/chemical.dmi'
icon_state = null
w_class = WEIGHT_CLASS_TINY
var/amount_per_transfer_from_this = 5
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
var/APTFT_altclick = TRUE //will the set amount_per_transfer_from_this proc be called on AltClick() ?
var/volume = 30
var/reagent_flags
var/list/list_reagents = null
var/spawned_disease = null
var/disease_amount = 20
var/spillable = FALSE
var/beaker_weakness_bitflag = NONE//Bitflag!
var/container_HP = 2
var/cached_icon
/obj/item/reagent_containers/Initialize(mapload, vol)
. = ..()
if(isnum(vol) && vol > 0)
volume = vol
if(length(possible_transfer_amounts))
verbs += /obj/item/reagent_containers/proc/set_APTFT
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
reagents.add_reagent(/datum/reagent/blood, disease_amount, data)
add_initial_reagents()
/obj/item/reagent_containers/examine(mob/user)
. = ..()
if(length(possible_transfer_amounts) > 1)
. += "Currently transferring [amount_per_transfer_from_this] units per use."
if(APTFT_altclick && user.Adjacent(src))
. += "<span class='notice'>Alt-click it to set its transfer amount.</span>"
/obj/item/reagent_containers/AltClick(mob/user)
. = ..()
if(APTFT_altclick && length(possible_transfer_amounts) > 1 && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
set_APTFT()
return TRUE
/obj/item/reagent_containers/proc/set_APTFT(mob/user) //set amount_per_transfer_from_this
set name = "Set Transfer Amount"
set category = "Object"
set waitfor = FALSE
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if(N)
amount_per_transfer_from_this = N
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
/obj/item/reagent_containers/proc/add_initial_reagents()
if(list_reagents)
reagents.add_reagent_list(list_reagents)
/obj/item/reagent_containers/attack_self(mob/user)
if(possible_transfer_amounts.len)
var/i=0
for(var/A in possible_transfer_amounts)
i++
if(A == amount_per_transfer_from_this)
if(i<possible_transfer_amounts.len)
amount_per_transfer_from_this = possible_transfer_amounts[i+1]
else
amount_per_transfer_from_this = possible_transfer_amounts[1]
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
return
/obj/item/reagent_containers/attack(mob/M, mob/user, def_zone)
if(user.a_intent == INTENT_HARM)
return ..()
/obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user)
if(!iscarbon(eater))
return 0
var/mob/living/carbon/C = eater
var/covered = ""
if(C.is_mouth_covered(head_only = 1))
covered = "headgear"
else if(C.is_mouth_covered(mask_only = 1))
covered = "mask"
if(covered)
var/who = (isnull(user) || eater == user) ? "your" : "[eater.p_their()]"
to_chat(user, "<span class='warning'>You have to remove [who] [covered] first!</span>")
return 0
return 1
/obj/item/reagent_containers/ex_act()
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
R.on_ex_act()
if(!QDELETED(src))
..()
/obj/item/reagent_containers/fire_act(exposed_temperature, exposed_volume)
reagents.expose_temperature(exposed_temperature)
..()
/obj/item/reagent_containers/throw_impact(atom/target)
. = ..()
SplashReagents(target, TRUE)
/obj/item/reagent_containers/proc/bartender_check(atom/target)
. = FALSE
if(target.CanPass(src, get_turf(src)) && thrownby && thrownby.actions)
for(var/datum/action/innate/drink_fling/D in thrownby.actions)
if(D.active)
return TRUE
/obj/item/reagent_containers/proc/ForceResetRotation()
transform = initial(transform)
/obj/item/reagent_containers/proc/SplashReagents(atom/target, thrown = FALSE)
if(!reagents || !reagents.total_volume || !spillable)
return
if(ismob(target) && target.reagents)
if(thrown)
reagents.total_volume *= rand(5,10) * 0.1 //Not all of it makes contact with the target
var/mob/M = target
var/R
target.visible_message("<span class='danger'>[M] has been splashed with something!</span>", \
"<span class='userdanger'>[M] has been splashed with something!</span>")
for(var/datum/reagent/A in reagents.reagent_list)
R += "[A.type] ([A.volume]),"
if(thrownby)
log_combat(thrownby, M, "splashed", R)
reagents.reaction(target, TOUCH)
else if(bartender_check(target) && thrown)
visible_message("<span class='notice'>[src] lands onto the [target.name] without spilling a single drop.</span>")
transform = initial(transform)
addtimer(CALLBACK(src, .proc/ForceResetRotation), 1)
return
else
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]", "in [AREACOORD(target)]")
log_game("[key_name(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [AREACOORD(target)].")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [ADMIN_VERBOSEJMP(target)].")
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
reagents.reaction(target, TOUCH)
if(QDELETED(src))
return
reagents.clear_reagents()
//melts plastic beakers
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
reagents.expose_temperature(1000)
if(beaker_weakness_bitflag & TEMP_WEAK)
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
for(var/mob/H in seen)
to_chat(H, "<span class='notice'>[iconhtml] \The [src]'s melts from the temperature!</span>")
playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1)
qdel(src)
..()
//melts plastic beakers
/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
reagents.expose_temperature(exposed_temperature)
temp_check()
/obj/item/reagent_containers/proc/temp_check()
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)//assuming polypropylene
START_PROCESSING(SSobj, src)
//melts glass beakers
/obj/item/reagent_containers/proc/pH_check()
if(beaker_weakness_bitflag & PH_WEAK)
if((reagents.pH < 1.5) || (reagents.pH > 12.5))
START_PROCESSING(SSobj, src)
else if((reagents.pH < -3) || (reagents.pH > 17))
visible_message("<span class='notice'>[icon2html(src, viewers(src))] \The [src] is damaged by the super pH and begins to deform!</span>")
reagents.pH = CLAMP(reagents.pH, -3, 17)
container_HP -= 1
/obj/item/reagent_containers/process()
if(!cached_icon)
cached_icon = icon_state
var/damage
var/cause
if(beaker_weakness_bitflag & PH_WEAK)
if(reagents.pH < 2)
damage = (2 - reagents.pH)/20
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
if(reagents.pH > 12)
damage = (reagents.pH - 12)/20
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)
if(damage)
damage += (reagents.chem_temp/444)/5
else
damage = (reagents.chem_temp/444)/5
if(cause)
cause += " and "
cause += "from the high temperature"
playsound(get_turf(src), 'sound/FermiChem/heatdam.ogg', 50, 1)
if(!damage || damage <= 0)
STOP_PROCESSING(SSobj, src)
container_HP -= damage
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
var/damage_percent = ((container_HP / initial(container_HP)*100))
switch(damage_percent)
if(-INFINITY to 0)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts [cause]!</span>")
playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted")
STOP_PROCESSING(SSobj, src)
qdel(src)
return
if(0 to 35)
icon_state = "[cached_icon]_m3"
desc = "[initial(desc)] It is severely deformed."
if(35 to 70)
icon_state = "[cached_icon]_m2"
desc = "[initial(desc)] It is deformed."
if(70 to 85)
desc = "[initial(desc)] It is mildly deformed."
icon_state = "[cached_icon]_m1"
update_icon()
if(prob(25))
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s is damaged by [cause] and begins to deform!</span>")
#define PH_WEAK (1 << 0)
#define TEMP_WEAK (1 << 1)
/obj/item/reagent_containers
name = "Container"
desc = "..."
icon = 'icons/obj/chemical.dmi'
icon_state = null
w_class = WEIGHT_CLASS_TINY
var/amount_per_transfer_from_this = 5
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
var/APTFT_altclick = TRUE //will the set amount_per_transfer_from_this proc be called on AltClick() ?
var/volume = 30
var/reagent_flags
var/list/list_reagents = null
var/spawned_disease = null
var/disease_amount = 20
var/spillable = FALSE
var/beaker_weakness_bitflag = NONE//Bitflag!
var/container_HP = 2
var/cached_icon
/obj/item/reagent_containers/Initialize(mapload, vol)
. = ..()
if(isnum(vol) && vol > 0)
volume = vol
if(length(possible_transfer_amounts))
verbs += /obj/item/reagent_containers/proc/set_APTFT
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
reagents.add_reagent(/datum/reagent/blood, disease_amount, data)
add_initial_reagents()
/obj/item/reagent_containers/examine(mob/user)
. = ..()
if(length(possible_transfer_amounts) > 1)
. += "Currently transferring [amount_per_transfer_from_this] units per use."
if(APTFT_altclick && user.Adjacent(src))
. += "<span class='notice'>Alt-click it to set its transfer amount.</span>"
/obj/item/reagent_containers/AltClick(mob/user)
. = ..()
if(APTFT_altclick && length(possible_transfer_amounts) > 1 && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
set_APTFT()
return TRUE
/obj/item/reagent_containers/proc/set_APTFT(mob/user) //set amount_per_transfer_from_this
set name = "Set Transfer Amount"
set category = "Object"
set waitfor = FALSE
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if(N)
amount_per_transfer_from_this = N
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
/obj/item/reagent_containers/proc/add_initial_reagents()
if(list_reagents)
reagents.add_reagent_list(list_reagents)
/obj/item/reagent_containers/attack_self(mob/user)
if(possible_transfer_amounts.len)
var/i=0
for(var/A in possible_transfer_amounts)
i++
if(A == amount_per_transfer_from_this)
if(i<possible_transfer_amounts.len)
amount_per_transfer_from_this = possible_transfer_amounts[i+1]
else
amount_per_transfer_from_this = possible_transfer_amounts[1]
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
return
/obj/item/reagent_containers/attack(mob/M, mob/user, def_zone)
if(user.a_intent == INTENT_HARM)
return ..()
/obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user)
if(!iscarbon(eater))
return 0
var/mob/living/carbon/C = eater
var/covered = ""
if(C.is_mouth_covered(head_only = 1))
covered = "headgear"
else if(C.is_mouth_covered(mask_only = 1))
covered = "mask"
if(covered)
var/who = (isnull(user) || eater == user) ? "your" : "[eater.p_their()]"
to_chat(user, "<span class='warning'>You have to remove [who] [covered] first!</span>")
return 0
return 1
/obj/item/reagent_containers/ex_act()
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
R.on_ex_act()
if(!QDELETED(src))
..()
/obj/item/reagent_containers/fire_act(exposed_temperature, exposed_volume)
reagents.expose_temperature(exposed_temperature)
..()
/obj/item/reagent_containers/throw_impact(atom/target)
. = ..()
SplashReagents(target, TRUE)
/obj/item/reagent_containers/proc/bartender_check(atom/target)
. = FALSE
if(target.CanPass(src, get_turf(src)) && thrownby && thrownby.actions)
for(var/datum/action/innate/drink_fling/D in thrownby.actions)
if(D.active)
return TRUE
/obj/item/reagent_containers/proc/ForceResetRotation()
transform = initial(transform)
/obj/item/reagent_containers/proc/SplashReagents(atom/target, thrown = FALSE)
if(!reagents || !reagents.total_volume || !spillable)
return
if(ismob(target) && target.reagents)
if(thrown)
reagents.total_volume *= rand(5,10) * 0.1 //Not all of it makes contact with the target
var/mob/M = target
var/R
target.visible_message("<span class='danger'>[M] has been splashed with something!</span>", \
"<span class='userdanger'>[M] has been splashed with something!</span>")
for(var/datum/reagent/A in reagents.reagent_list)
R += "[A.type] ([A.volume]),"
if(thrownby)
log_combat(thrownby, M, "splashed", R)
reagents.reaction(target, TOUCH)
else if(bartender_check(target) && thrown)
visible_message("<span class='notice'>[src] lands onto the [target.name] without spilling a single drop.</span>")
transform = initial(transform)
addtimer(CALLBACK(src, .proc/ForceResetRotation), 1)
return
else
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]", "in [AREACOORD(target)]")
log_game("[key_name(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [AREACOORD(target)].")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] in [ADMIN_VERBOSEJMP(target)].")
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
reagents.reaction(target, TOUCH)
if(QDELETED(src))
return
reagents.clear_reagents()
//melts plastic beakers
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
reagents.expose_temperature(1000)
if(beaker_weakness_bitflag & TEMP_WEAK)
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
for(var/mob/H in seen)
to_chat(H, "<span class='notice'>[iconhtml] \The [src]'s melts from the temperature!</span>")
playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1)
qdel(src)
..()
//melts plastic beakers
/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
reagents.expose_temperature(exposed_temperature)
temp_check()
/obj/item/reagent_containers/proc/temp_check()
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)//assuming polypropylene
START_PROCESSING(SSobj, src)
//melts glass beakers
/obj/item/reagent_containers/proc/pH_check()
if(beaker_weakness_bitflag & PH_WEAK)
if((reagents.pH < 1.5) || (reagents.pH > 12.5))
START_PROCESSING(SSobj, src)
else if((reagents.pH < -3) || (reagents.pH > 17))
visible_message("<span class='notice'>[icon2html(src, viewers(src))] \The [src] is damaged by the super pH and begins to deform!</span>")
reagents.pH = CLAMP(reagents.pH, -3, 17)
container_HP -= 1
/obj/item/reagent_containers/process()
if(!cached_icon)
cached_icon = icon_state
var/damage
var/cause
if(beaker_weakness_bitflag & PH_WEAK)
if(reagents.pH < 2)
damage = (2 - reagents.pH)/20
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
if(reagents.pH > 12)
damage = (reagents.pH - 12)/20
cause = "from the extreme pH"
playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1)
if(beaker_weakness_bitflag & TEMP_WEAK)
if(reagents.chem_temp >= 444)
if(damage)
damage += (reagents.chem_temp/444)/5
else
damage = (reagents.chem_temp/444)/5
if(cause)
cause += " and "
cause += "from the high temperature"
playsound(get_turf(src), 'sound/FermiChem/heatdam.ogg', 50, 1)
if(!damage || damage <= 0)
STOP_PROCESSING(SSobj, src)
container_HP -= damage
var/list/seen = viewers(5, get_turf(src))
var/iconhtml = icon2html(src, seen)
var/damage_percent = ((container_HP / initial(container_HP)*100))
switch(damage_percent)
if(-INFINITY to 0)
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s melts [cause]!</span>")
playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted")
STOP_PROCESSING(SSobj, src)
qdel(src)
return
if(0 to 35)
icon_state = "[cached_icon]_m3"
desc = "[initial(desc)] It is severely deformed."
if(35 to 70)
icon_state = "[cached_icon]_m2"
desc = "[initial(desc)] It is deformed."
if(70 to 85)
desc = "[initial(desc)] It is mildly deformed."
icon_state = "[cached_icon]_m1"
update_icon()
if(prob(25))
for(var/mob/M in seen)
to_chat(M, "<span class='notice'>[iconhtml] \The [src]'s is damaged by [cause] and begins to deform!</span>")
@@ -1,261 +1,264 @@
/*
Contains:
Borg Hypospray
Borg Shaker
Nothing to do with hydroponics in here. Sorry to dissapoint you.
*/
/*
Borg Hypospray
*/
/obj/item/reagent_containers/borghypo
name = "cyborg hypospray"
desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
icon = 'icons/obj/syringe.dmi'
item_state = "hypo"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
icon_state = "borghypo"
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = list()
var/mode = 1
var/charge_cost = 50
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
var/bypass_protection = 0 //If the hypospray can go through armor or thick material
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list(/datum/reagent/medicine/dexalin, /datum/reagent/medicine/kelotane, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/antitoxin,
/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution, /datum/reagent/medicine/insulin)
var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed.
var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values.
//Used as list for input() in shakers.
/obj/item/reagent_containers/borghypo/Initialize()
. = ..()
for(var/R in reagent_ids)
add_reagent(R)
START_PROCESSING(SSobj, src)
/obj/item/reagent_containers/borghypo/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg
charge_tick++
if(charge_tick >= recharge_time)
regenerate_reagents()
charge_tick = 0
//update_icon()
return 1
// Use this to add more chemicals for the borghypo to produce.
/obj/item/reagent_containers/borghypo/proc/add_reagent(reagent)
reagent_ids |= reagent
var/datum/reagents/RG = new(30)
RG.my_atom = src
reagent_list += RG
var/datum/reagents/R = reagent_list[reagent_list.len]
R.add_reagent(reagent, 30)
modes[reagent] = modes.len + 1
/obj/item/reagent_containers/borghypo/proc/del_reagent(reagent)
reagent_ids -= reagent
var/datum/reagents/RG
var/datum/reagents/TRG
for(var/i in 1 to reagent_ids.len)
TRG = reagent_list[i]
if (TRG.has_reagent(reagent))
RG = TRG
break
if (RG)
reagent_list -= RG
RG.del_reagent(reagent)
modes[reagent] = modes.len - 1
/obj/item/reagent_containers/borghypo/proc/regenerate_reagents()
if(iscyborg(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
for(var/i in 1 to reagent_ids.len)
var/datum/reagents/RG = reagent_list[i]
if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full.
R.cell.use(charge_cost) //Take power from borg...
RG.add_reagent(reagent_ids[i], 5) //And fill hypo with reagent.
/obj/item/reagent_containers/borghypo/attack(mob/living/carbon/M, mob/user)
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
to_chat(user, "<span class='notice'>The injector is empty.</span>")
return
if(!istype(M))
return
if(R.total_volume && M.can_inject(user, 1, user.zone_selected,bypass_protection))
to_chat(M, "<span class='warning'>You feel a tiny prick!</span>")
to_chat(user, "<span class='notice'>You inject [M] with the injector.</span>")
var/fraction = min(amount_per_transfer_from_this/R.total_volume, 1)
R.reaction(M, INJECT, fraction)
if(M.reagents)
var/trans = R.trans_to(M, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>[trans] unit\s injected. [R.total_volume] unit\s remaining.</span>")
var/list/injected = list()
for(var/datum/reagent/RG in R.reagent_list)
injected += RG.name
log_combat(user, M, "injected", src, "(CHEMICALS: [english_list(injected)])")
/obj/item/reagent_containers/borghypo/attack_self(mob/user)
var/chosen_reagent = modes[input(user, "What reagent do you want to dispense?") as null|anything in reagent_ids]
if(!chosen_reagent)
return
mode = chosen_reagent
playsound(loc, 'sound/effects/pop.ogg', 50, 0)
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_ids[mode]]
to_chat(user, "<span class='notice'>[src] is now dispensing '[R.name]'.</span>")
return
/obj/item/reagent_containers/borghypo/examine(mob/user)
. = ..()
. += DescribeContents() //Because using the standardized reagents datum was just too cool for whatever fuckwit wrote this
/obj/item/reagent_containers/borghypo/proc/DescribeContents()
var/empty = 1
for(var/datum/reagents/RS in reagent_list)
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
. += "<span class='notice'>It currently has [R.volume] unit\s of [R.name] stored.</span>"
empty = 0
if(empty)
. += "<span class='warning'>It is currently empty! Allow some time for the internal syntheszier to produce more.</span>"
/obj/item/reagent_containers/borghypo/hacked
icon_state = "borghypo_s"
reagent_ids = list (/datum/reagent/toxin/acid, /datum/reagent/toxin/mutetoxin, /datum/reagent/toxin/cyanide, /datum/reagent/toxin/sodium_thiopental, /datum/reagent/toxin/heparin, /datum/reagent/toxin/lexorin)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/clown
name = "laughter injector"
desc = "Keeps the crew happy and productive!"
reagent_ids = list(/datum/reagent/consumable/laughter)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/clown/hacked
name = "laughter injector"
desc = "Keeps the crew so happy they don't work!"
reagent_ids = list(/datum/reagent/consumable/superlaughter)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/syndicate
name = "syndicate cyborg hypospray"
desc = "An experimental piece of Syndicate technology used to produce powerful restorative nanites used to very quickly restore injuries of all types. Also metabolizes potassium iodide, for radiation poisoning, and morphine, for offense."
icon_state = "borghypo_s"
charge_cost = 20
recharge_time = 2
reagent_ids = list(/datum/reagent/medicine/syndicate_nanites, /datum/reagent/medicine/potass_iodide, /datum/reagent/medicine/morphine, /datum/reagent/medicine/insulin)
bypass_protection = 1
accepts_reagent_upgrades = FALSE
/*
Borg Shaker
*/
/obj/item/reagent_containers/borghypo/borgshaker
name = "cyborg shaker"
desc = "An advanced drink synthesizer and mixer."
icon = 'icons/obj/drinks.dmi'
icon_state = "shaker"
possible_transfer_amounts = list(5,10,20)
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
accepts_reagent_upgrades = FALSE
reagent_ids = list(/datum/reagent/consumable/ethanol/beer, /datum/reagent/consumable/orangejuice, /datum/reagent/consumable/grenadine,
/datum/reagent/consumable/limejuice, /datum/reagent/consumable/tomatojuice, /datum/reagent/consumable/space_cola,
/datum/reagent/consumable/tonic, /datum/reagent/consumable/sodawater, /datum/reagent/consumable/ice,
/datum/reagent/consumable/cream, /datum/reagent/consumable/ethanol/whiskey, /datum/reagent/consumable/ethanol/vodka,
/datum/reagent/consumable/ethanol/rum, /datum/reagent/consumable/ethanol/gin, /datum/reagent/consumable/ethanol/tequila,
/datum/reagent/consumable/ethanol/vermouth, /datum/reagent/consumable/ethanol/wine, /datum/reagent/consumable/ethanol/kahlua,
/datum/reagent/consumable/ethanol/cognac, /datum/reagent/consumable/ethanol/ale, /datum/reagent/consumable/milk,
/datum/reagent/consumable/coffee, /datum/reagent/consumable/banana, /datum/reagent/consumable/lemonjuice)
/obj/item/reagent_containers/borghypo/borgshaker/attack(mob/M, mob/user)
return //Can't inject stuff with a shaker, can we? //not with that attitude
/obj/item/reagent_containers/borghypo/borgshaker/regenerate_reagents()
if(iscyborg(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
for(var/i in modes) //Lots of reagents in this one, so it's best to regenrate them all at once to keep it from being tedious.
var/valueofi = modes[i]
var/datum/reagents/RG = reagent_list[valueofi]
if(RG.total_volume < RG.maximum_volume)
R.cell.use(charge_cost)
RG.add_reagent(reagent_ids[valueofi], 5)
/obj/item/reagent_containers/borghypo/borgshaker/afterattack(obj/target, mob/user, proximity)
. = ..()
if(!proximity)
return
else if(target.is_refillable())
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
to_chat(user, "<span class='warning'>[src] is currently out of this ingredient! Please allow some time for the synthesizer to produce more.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[target] is full.</span>")
return
var/trans = R.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>")
/obj/item/reagent_containers/borghypo/borgshaker/DescribeContents()
var/empty = 1
var/datum/reagents/RS = reagent_list[mode]
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
to_chat(usr, "<span class='notice'>It currently has [R.volume] unit\s of [R.name] stored.</span>")
empty = 0
if(empty)
to_chat(usr, "<span class='warning'>It is currently empty! Please allow some time for the synthesizer to produce more.</span>")
/obj/item/reagent_containers/borghypo/borgshaker/hacked
name = "cyborg shaker"
desc = "Will mix drinks that knock them dead."
icon = 'icons/obj/drinks.dmi'
icon_state = "threemileislandglass"
possible_transfer_amounts = list(5,10,20)
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
accepts_reagent_upgrades = FALSE
reagent_ids = list(/datum/reagent/toxin/fakebeer, /datum/reagent/consumable/ethanol/fernet)
/obj/item/reagent_containers/borghypo/peace
name = "Peace Hypospray"
reagent_ids = list(/datum/reagent/peaceborg_confuse, /datum/reagent/peaceborg_tire, /datum/reagent/pax/peaceborg, /datum/reagent/medicine/insulin)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/peace/hacked
desc = "Everything's peaceful in death!"
icon_state = "borghypo_s"
reagent_ids = list(/datum/reagent/peaceborg_confuse, /datum/reagent/peaceborg_tire, /datum/reagent/pax/peaceborg,
/datum/reagent/toxin/staminatoxin,/datum/reagent/toxin/sulfonal,/datum/reagent/toxin/sodium_thiopental,
/datum/reagent/toxin/cyanide,/datum/reagent/toxin/fentanyl)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/epi
name = "Stabilizer injector"
desc = "An advanced chemical synthesizer and injection system, designed to stabilize patients."
reagent_ids = list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/insulin)
accepts_reagent_upgrades = FALSE
/*
Contains:
Borg Hypospray
Borg Shaker
Nothing to do with hydroponics in here. Sorry to dissapoint you.
*/
/*
Borg Hypospray
*/
/obj/item/reagent_containers/borghypo
name = "cyborg hypospray"
desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
icon = 'icons/obj/syringe.dmi'
item_state = "hypo"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
icon_state = "borghypo"
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = list()
var/mode = 1
var/charge_cost = 50
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
var/bypass_protection = 0 //If the hypospray can go through armor or thick material
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list(/datum/reagent/medicine/dexalin, /datum/reagent/medicine/kelotane, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/antitoxin,
/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution, /datum/reagent/medicine/insulin)
var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed.
var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values.
//Used as list for input() in shakers.
var/list/reagent_names = list()
/obj/item/reagent_containers/borghypo/Initialize()
. = ..()
for(var/R in reagent_ids)
add_reagent(R)
START_PROCESSING(SSobj, src)
/obj/item/reagent_containers/borghypo/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg
charge_tick++
if(charge_tick >= recharge_time)
regenerate_reagents()
charge_tick = 0
//update_icon()
return 1
// Use this to add more chemicals for the borghypo to produce.
/obj/item/reagent_containers/borghypo/proc/add_reagent(datum/reagent/reagent)
reagent_ids |= reagent
var/datum/reagents/RG = new(30)
RG.my_atom = src
reagent_list += RG
var/datum/reagents/R = reagent_list[reagent_list.len]
R.add_reagent(reagent, 30)
modes[reagent] = modes.len + 1
reagent_names[initial(reagent.name)] = reagent
/obj/item/reagent_containers/borghypo/proc/del_reagent(datum/reagent/reagent)
reagent_ids -= reagent
reagent_names -= initial(reagent.name)
var/datum/reagents/RG
var/datum/reagents/TRG
for(var/i in 1 to reagent_ids.len)
TRG = reagent_list[i]
if (TRG.has_reagent(reagent))
RG = TRG
break
if (RG)
reagent_list -= RG
RG.del_reagent(reagent)
modes[reagent] = modes.len - 1
/obj/item/reagent_containers/borghypo/proc/regenerate_reagents()
if(iscyborg(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
for(var/i in 1 to reagent_ids.len)
var/datum/reagents/RG = reagent_list[i]
if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full.
R.cell.use(charge_cost) //Take power from borg...
RG.add_reagent(reagent_ids[i], 5) //And fill hypo with reagent.
/obj/item/reagent_containers/borghypo/attack(mob/living/carbon/M, mob/user)
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
to_chat(user, "<span class='notice'>The injector is empty.</span>")
return
if(!istype(M))
return
if(R.total_volume && M.can_inject(user, 1, user.zone_selected,bypass_protection))
to_chat(M, "<span class='warning'>You feel a tiny prick!</span>")
to_chat(user, "<span class='notice'>You inject [M] with the injector.</span>")
var/fraction = min(amount_per_transfer_from_this/R.total_volume, 1)
R.reaction(M, INJECT, fraction)
if(M.reagents)
var/trans = R.trans_to(M, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>[trans] unit\s injected. [R.total_volume] unit\s remaining.</span>")
var/list/injected = list()
for(var/datum/reagent/RG in R.reagent_list)
injected += RG.name
log_combat(user, M, "injected", src, "(CHEMICALS: [english_list(injected)])")
/obj/item/reagent_containers/borghypo/attack_self(mob/user)
var/chosen_reagent = modes[reagent_names[input(user, "What reagent do you want to dispense?") as null|anything in reagent_names]]
if(!chosen_reagent)
return
mode = chosen_reagent
playsound(loc, 'sound/effects/pop.ogg', 50, 0)
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_ids[mode]]
to_chat(user, "<span class='notice'>[src] is now dispensing '[R.name]'.</span>")
return
/obj/item/reagent_containers/borghypo/examine(mob/user)
. = ..()
. += DescribeContents() //Because using the standardized reagents datum was just too cool for whatever fuckwit wrote this
/obj/item/reagent_containers/borghypo/proc/DescribeContents()
var/empty = 1
for(var/datum/reagents/RS in reagent_list)
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
. += "<span class='notice'>It currently has [R.volume] unit\s of [R.name] stored.</span>"
empty = 0
if(empty)
. += "<span class='warning'>It is currently empty! Allow some time for the internal syntheszier to produce more.</span>"
/obj/item/reagent_containers/borghypo/hacked
icon_state = "borghypo_s"
reagent_ids = list (/datum/reagent/toxin/acid, /datum/reagent/toxin/mutetoxin, /datum/reagent/toxin/cyanide, /datum/reagent/toxin/sodium_thiopental, /datum/reagent/toxin/heparin, /datum/reagent/toxin/lexorin)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/clown
name = "laughter injector"
desc = "Keeps the crew happy and productive!"
reagent_ids = list(/datum/reagent/consumable/laughter)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/clown/hacked
name = "laughter injector"
desc = "Keeps the crew so happy they don't work!"
reagent_ids = list(/datum/reagent/consumable/superlaughter)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/syndicate
name = "syndicate cyborg hypospray"
desc = "An experimental piece of Syndicate technology used to produce powerful restorative nanites used to very quickly restore injuries of all types. Also metabolizes potassium iodide, for radiation poisoning, and morphine, for offense."
icon_state = "borghypo_s"
charge_cost = 20
recharge_time = 2
reagent_ids = list(/datum/reagent/medicine/syndicate_nanites, /datum/reagent/medicine/potass_iodide, /datum/reagent/medicine/morphine, /datum/reagent/medicine/insulin)
bypass_protection = 1
accepts_reagent_upgrades = FALSE
/*
Borg Shaker
*/
/obj/item/reagent_containers/borghypo/borgshaker
name = "cyborg shaker"
desc = "An advanced drink synthesizer and mixer."
icon = 'icons/obj/drinks.dmi'
icon_state = "shaker"
possible_transfer_amounts = list(5,10,20)
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
accepts_reagent_upgrades = FALSE
reagent_ids = list(/datum/reagent/consumable/ethanol/beer, /datum/reagent/consumable/orangejuice, /datum/reagent/consumable/grenadine,
/datum/reagent/consumable/limejuice, /datum/reagent/consumable/tomatojuice, /datum/reagent/consumable/space_cola,
/datum/reagent/consumable/tonic, /datum/reagent/consumable/sodawater, /datum/reagent/consumable/ice,
/datum/reagent/consumable/cream, /datum/reagent/consumable/ethanol/whiskey, /datum/reagent/consumable/ethanol/vodka,
/datum/reagent/consumable/ethanol/rum, /datum/reagent/consumable/ethanol/gin, /datum/reagent/consumable/ethanol/tequila,
/datum/reagent/consumable/ethanol/vermouth, /datum/reagent/consumable/ethanol/wine, /datum/reagent/consumable/ethanol/kahlua,
/datum/reagent/consumable/ethanol/cognac, /datum/reagent/consumable/ethanol/ale, /datum/reagent/consumable/milk,
/datum/reagent/consumable/coffee, /datum/reagent/consumable/banana, /datum/reagent/consumable/lemonjuice)
/obj/item/reagent_containers/borghypo/borgshaker/attack(mob/M, mob/user)
return //Can't inject stuff with a shaker, can we? //not with that attitude
/obj/item/reagent_containers/borghypo/borgshaker/regenerate_reagents()
if(iscyborg(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
for(var/i in modes) //Lots of reagents in this one, so it's best to regenrate them all at once to keep it from being tedious.
var/valueofi = modes[i]
var/datum/reagents/RG = reagent_list[valueofi]
if(RG.total_volume < RG.maximum_volume)
R.cell.use(charge_cost)
RG.add_reagent(reagent_ids[valueofi], 5)
/obj/item/reagent_containers/borghypo/borgshaker/afterattack(obj/target, mob/user, proximity)
. = ..()
if(!proximity)
return
else if(target.is_refillable())
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
to_chat(user, "<span class='warning'>[src] is currently out of this ingredient! Please allow some time for the synthesizer to produce more.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[target] is full.</span>")
return
var/trans = R.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>")
/obj/item/reagent_containers/borghypo/borgshaker/DescribeContents()
var/empty = 1
var/datum/reagents/RS = reagent_list[mode]
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
to_chat(usr, "<span class='notice'>It currently has [R.volume] unit\s of [R.name] stored.</span>")
empty = 0
if(empty)
to_chat(usr, "<span class='warning'>It is currently empty! Please allow some time for the synthesizer to produce more.</span>")
/obj/item/reagent_containers/borghypo/borgshaker/hacked
name = "cyborg shaker"
desc = "Will mix drinks that knock them dead."
icon = 'icons/obj/drinks.dmi'
icon_state = "threemileislandglass"
possible_transfer_amounts = list(5,10,20)
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
accepts_reagent_upgrades = FALSE
reagent_ids = list(/datum/reagent/toxin/fakebeer, /datum/reagent/consumable/ethanol/fernet)
/obj/item/reagent_containers/borghypo/peace
name = "Peace Hypospray"
reagent_ids = list(/datum/reagent/peaceborg_confuse, /datum/reagent/peaceborg_tire, /datum/reagent/pax/peaceborg, /datum/reagent/medicine/insulin)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/peace/hacked
desc = "Everything's peaceful in death!"
icon_state = "borghypo_s"
reagent_ids = list(/datum/reagent/peaceborg_confuse, /datum/reagent/peaceborg_tire, /datum/reagent/pax/peaceborg,
/datum/reagent/toxin/staminatoxin,/datum/reagent/toxin/sulfonal,/datum/reagent/toxin/sodium_thiopental,
/datum/reagent/toxin/cyanide,/datum/reagent/toxin/fentanyl)
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/epi
name = "Stabilizer injector"
desc = "An advanced chemical synthesizer and injection system, designed to stabilize patients."
reagent_ids = list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/insulin)
accepts_reagent_upgrades = FALSE
@@ -1,102 +1,102 @@
/obj/item/reagent_containers/dropper
name = "dropper"
desc = "A dropper. Holds up to 5 units."
icon = 'icons/obj/chemical.dmi'
icon_state = "dropper0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1, 2, 3, 4, 5)
volume = 5
reagent_flags = TRANSPARENT
/obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity)
. = ..()
if(!proximity)
return
if(!target.reagents)
return
if(reagents.total_volume > 0)
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[target] is full.</span>")
return
if(!target.is_injectable())
to_chat(user, "<span class='warning'>You cannot directly fill [target]!</span>")
return
var/trans = 0
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
if(ismob(target))
if(ishuman(target))
var/mob/living/carbon/human/victim = target
var/obj/item/safe_thing = null
if(victim.wear_mask)
if(victim.wear_mask.flags_cover & MASKCOVERSEYES)
safe_thing = victim.wear_mask
if(victim.head)
if(victim.head.flags_cover & MASKCOVERSEYES)
safe_thing = victim.head
if(victim.glasses)
if(!safe_thing)
safe_thing = victim.glasses
if(safe_thing)
if(!safe_thing.reagents)
safe_thing.create_reagents(100)
reagents.reaction(safe_thing, TOUCH, fraction)
trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this)
target.visible_message("<span class='danger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>", \
"<span class='userdanger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>")
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution.</span>")
update_icon()
return
else if(isalien(target)) //hiss-hiss has no eyes!
to_chat(target, "<span class='danger'>[target] does not seem to have any eyes!</span>")
return
target.visible_message("<span class='danger'>[user] squirts something into [target]'s eyes!</span>", \
"<span class='userdanger'>[user] squirts something into [target]'s eyes!</span>")
reagents.reaction(target, TOUCH, fraction)
var/mob/M = target
var/R
if(reagents)
for(var/datum/reagent/A in src.reagents.reagent_list)
R += A.type + " ("
R += num2text(A.volume) + "),"
log_combat(user, M, "squirted", R)
trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution.</span>")
update_icon()
else
if(!target.is_drawable(FALSE)) //No drawing from mobs here
to_chat(user, "<span class='notice'>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
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] unit\s of the solution.</span>")
update_icon()
/obj/item/reagent_containers/dropper/update_icon()
cut_overlays()
if(reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "dropper")
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/reagent_containers/dropper/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
/obj/item/reagent_containers/dropper
name = "dropper"
desc = "A dropper. Holds up to 5 units."
icon = 'icons/obj/chemical.dmi'
icon_state = "dropper0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1, 2, 3, 4, 5)
volume = 5
reagent_flags = TRANSPARENT
/obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity)
. = ..()
if(!proximity)
return
if(!target.reagents)
return
if(reagents.total_volume > 0)
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[target] is full.</span>")
return
if(!target.is_injectable())
to_chat(user, "<span class='warning'>You cannot directly fill [target]!</span>")
return
var/trans = 0
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
if(ismob(target))
if(ishuman(target))
var/mob/living/carbon/human/victim = target
var/obj/item/safe_thing = null
if(victim.wear_mask)
if(victim.wear_mask.flags_cover & MASKCOVERSEYES)
safe_thing = victim.wear_mask
if(victim.head)
if(victim.head.flags_cover & MASKCOVERSEYES)
safe_thing = victim.head
if(victim.glasses)
if(!safe_thing)
safe_thing = victim.glasses
if(safe_thing)
if(!safe_thing.reagents)
safe_thing.create_reagents(100)
reagents.reaction(safe_thing, TOUCH, fraction)
trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this)
target.visible_message("<span class='danger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>", \
"<span class='userdanger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>")
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution.</span>")
update_icon()
return
else if(isalien(target)) //hiss-hiss has no eyes!
to_chat(target, "<span class='danger'>[target] does not seem to have any eyes!</span>")
return
target.visible_message("<span class='danger'>[user] squirts something into [target]'s eyes!</span>", \
"<span class='userdanger'>[user] squirts something into [target]'s eyes!</span>")
reagents.reaction(target, TOUCH, fraction)
var/mob/M = target
var/R
if(reagents)
for(var/datum/reagent/A in src.reagents.reagent_list)
R += A.type + " ("
R += num2text(A.volume) + "),"
log_combat(user, M, "squirted", R)
trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution.</span>")
update_icon()
else
if(!target.is_drawable(FALSE)) //No drawing from mobs here
to_chat(user, "<span class='notice'>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
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] unit\s of the solution.</span>")
update_icon()
/obj/item/reagent_containers/dropper/update_icon()
cut_overlays()
if(reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "dropper")
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/reagent_containers/dropper/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
+368 -368
View File
@@ -1,368 +1,368 @@
/obj/item/reagent_containers/glass
name = "glass"
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
volume = 50
reagent_flags = OPENCONTAINER
spillable = TRUE
resistance_flags = ACID_PROOF
container_HP = 2
/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
if(!canconsume(M, user))
return
if(!spillable)
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(istype(M))
if(user.a_intent == INTENT_HARM)
var/R
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>")
if(reagents)
for(var/datum/reagent/A in reagents.reagent_list)
R += A.type + " ("
R += num2text(A.volume) + "),"
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
reagents.reaction(M, TOUCH)
log_combat(user, M, "splashed", R)
reagents.clear_reagents()
else
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
if(!do_mob(user, M))
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>")
log_combat(user, M, "fed", reagents.log_list())
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, INGEST, fraction)
addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
. = ..()
if((!proximity) || !check_allowed_items(target,target_self=1))
return
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>")
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>")
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty and can't be refilled!</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] unit\s of the contents of [target].</span>")
else if(reagents.total_volume)
if(user.a_intent == INTENT_HARM)
user.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
"<span class='notice'>You splash the contents of [src] onto [target].</span>")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs
var/obj/item/reagent_containers/food/snacks/egg/E = I
if(reagents)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>[src] is full.</span>")
else
to_chat(user, "<span class='notice'>You break [E] in [src].</span>")
E.reagents.trans_to(src, E.reagents.total_volume)
qdel(E)
return
..()
/obj/item/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 60 units. Unable to withstand extreme pHes."
icon = 'icons/obj/chemical.dmi'
volume = 60
icon_state = "beaker"
item_state = "beaker"
materials = list(MAT_GLASS=500)
possible_transfer_amounts = list(5,10,15,20,25,30,50,60)
beaker_weakness_bitflag = PH_WEAK
/obj/item/reagent_containers/glass/beaker/Initialize()
. = ..()
update_icon()
/obj/item/reagent_containers/glass/beaker/get_part_rating()
return reagents.maximum_volume
/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
update_icon()
/obj/item/reagent_containers/glass/beaker/update_icon()
if(!cached_icon)
cached_icon = icon_state
cut_overlays()
if(reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
filling.icon_state = "[cached_icon]-10"
if(10 to 24)
filling.icon_state = "[cached_icon]10"
if(25 to 49)
filling.icon_state = "[cached_icon]25"
if(50 to 74)
filling.icon_state = "[cached_icon]50"
if(75 to 79)
filling.icon_state = "[cached_icon]75"
if(80 to 90)
filling.icon_state = "[cached_icon]80"
if(91 to INFINITY)
filling.icon_state = "[cached_icon]100"
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/reagent_containers/glass/beaker/jar
name = "honey jar"
desc = "A jar for honey. It can hold up to 60 units of sweet delight. Unable to withstand reagents of an extreme pH."
icon = 'icons/obj/chemical.dmi'
icon_state = "vapour"
/obj/item/reagent_containers/glass/beaker/large
name = "large beaker"
desc = "A large beaker. Can hold up to 120 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerlarge"
materials = list(MAT_GLASS=2500)
volume = 120
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120)
container_HP = 3
/obj/item/reagent_containers/glass/beaker/plastic
name = "x-large beaker"
desc = "An extra-large beaker. Can hold up to 180 units. Is able to resist acid and alkaline solutions, but melts at 444 K."
icon_state = "beakerwhite"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
volume = 180
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180)
/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
..()
icon_state = "beakerwhite"
/obj/item/reagent_containers/glass/beaker/meta
name = "metamaterial beaker"
desc = "A large beaker. Can hold up to 240 units, and is able to withstand all chemical situations."
icon_state = "beakergold"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
volume = 240
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,200,240)
/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/noreact
name = "cryostasis beaker"
desc = "A cryostasis beaker that allows for chemical storage without \
reactions. Can hold up to 50 units."
icon_state = "beakernoreact"
materials = list(MAT_METAL=3000)
reagent_flags = OPENCONTAINER | NO_REACT
volume = 50
amount_per_transfer_from_this = 10
container_HP = 10//shouldn't be needed
/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
//reagents.set_reacting(FALSE) was this removed in a recent pr?
/obj/item/reagent_containers/glass/beaker/bluespace
name = "bluespace beaker"
desc = "A bluespace beaker, powered by experimental bluespace technology \
and Element Cuban combined with the Compound Pete. Can hold up to \
300 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerbluespace"
materials = list(MAT_GLASS=3000)
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
container_HP = 5
/obj/item/reagent_containers/glass/beaker/cryoxadone
list_reagents = list(/datum/reagent/medicine/cryoxadone = 30)
/obj/item/reagent_containers/glass/beaker/sulphuric
list_reagents = list(/datum/reagent/toxin/acid = 50)
/obj/item/reagent_containers/glass/beaker/slime
list_reagents = list(/datum/reagent/toxin/slimejelly = 50)
/obj/item/reagent_containers/glass/beaker/large/styptic
name = "styptic reserve tank"
list_reagents = list(/datum/reagent/medicine/styptic_powder = 50)
/obj/item/reagent_containers/glass/beaker/large/silver_sulfadiazine
name = "silver sulfadiazine reserve tank"
list_reagents = list(/datum/reagent/medicine/silver_sulfadiazine = 50)
/obj/item/reagent_containers/glass/beaker/large/charcoal
name = "charcoal reserve tank"
list_reagents = list(/datum/reagent/medicine/charcoal = 50)
/obj/item/reagent_containers/glass/beaker/large/epinephrine
name = "epinephrine reserve tank"
list_reagents = list(/datum/reagent/medicine/epinephrine = 50)
/obj/item/reagent_containers/glass/beaker/synthflesh
list_reagents = list(/datum/reagent/medicine/synthflesh = 50)
/obj/item/reagent_containers/glass/bucket
name = "bucket"
desc = "It's a bucket."
icon = 'icons/obj/janitor.dmi'
icon_state = "bucket"
item_state = "bucket"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
materials = list(MAT_METAL=200)
w_class = WEIGHT_CLASS_NORMAL
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(5,10,15,20,25,30,50,70)
volume = 70
flags_inv = HIDEHAIR
slot_flags = ITEM_SLOT_HEAD
resistance_flags = NONE
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head
slot_equipment_priority = list( \
SLOT_BACK, SLOT_WEAR_ID,\
SLOT_W_UNIFORM, SLOT_WEAR_SUIT,\
SLOT_WEAR_MASK, SLOT_HEAD, SLOT_NECK,\
SLOT_SHOES, SLOT_GLOVES,\
SLOT_EARS, SLOT_GLASSES,\
SLOT_BELT, SLOT_S_STORE,\
SLOT_L_STORE, SLOT_R_STORE,\
SLOT_GENERC_DEXTROUS_STORAGE
)
container_HP = 1
/obj/item/reagent_containers/glass/bucket/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/mop))
if(reagents.total_volume < 1)
to_chat(user, "<span class='warning'>[src] is out of water!</span>")
else
reagents.trans_to(O, 5)
to_chat(user, "<span class='notice'>You wet [O] in [src].</span>")
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
else if(isprox(O))
to_chat(user, "<span class='notice'>You add [O] to [src].</span>")
qdel(O)
qdel(src)
user.put_in_hands(new /obj/item/bot_assembly/cleanbot)
else
..()
/obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot)
..()
if (slot == SLOT_HEAD)
if(reagents.total_volume)
to_chat(user, "<span class='userdanger'>[src]'s contents spill all over you!</span>")
reagents.reaction(user, TOUCH)
reagents.clear_reagents()
reagent_flags = NONE
/obj/item/reagent_containers/glass/bucket/dropped(mob/user)
. = ..()
reagent_flags = initial(reagent_flags)
/obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M)
if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head
var/index = slot_equipment_priority.Find(SLOT_HEAD)
slot_equipment_priority.Remove(SLOT_HEAD)
. = ..()
slot_equipment_priority.Insert(index, SLOT_HEAD)
return
return ..()
/obj/item/reagent_containers/glass/beaker/waterbottle
name = "bottle of water"
desc = "A bottle of water filled at an old Earth bottling facility."
icon = 'icons/obj/drinks.dmi'
icon_state = "smallbottle"
item_state = "bottle"
list_reagents = list(/datum/reagent/water = 49.5, /datum/reagent/fluorine = 0.5)//see desc, don't think about it too hard
materials = list(MAT_GLASS=0)
volume = 50
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50)
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/waterbottle/empty
list_reagents = list()
/obj/item/reagent_containers/glass/beaker/waterbottle/large
desc = "A fresh commercial-sized bottle of water."
icon_state = "largebottle"
materials = list(MAT_GLASS=0)
list_reagents = list(/datum/reagent/water = 100)
volume = 100
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
list_reagents = list()
/obj/item/reagent_containers/glass/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "bottle")
/obj/item/reagent_containers/glass
name = "glass"
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
volume = 50
reagent_flags = OPENCONTAINER
spillable = TRUE
resistance_flags = ACID_PROOF
container_HP = 2
/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
if(!canconsume(M, user))
return
if(!spillable)
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(istype(M))
if(user.a_intent == INTENT_HARM)
var/R
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>")
if(reagents)
for(var/datum/reagent/A in reagents.reagent_list)
R += A.type + " ("
R += num2text(A.volume) + "),"
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
reagents.reaction(M, TOUCH)
log_combat(user, M, "splashed", R)
reagents.clear_reagents()
else
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
if(!do_mob(user, M))
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>")
log_combat(user, M, "fed", reagents.log_list())
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, INGEST, fraction)
addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
. = ..()
if((!proximity) || !check_allowed_items(target,target_self=1))
return
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>")
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>")
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty and can't be refilled!</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] unit\s of the contents of [target].</span>")
else if(reagents.total_volume)
if(user.a_intent == INTENT_HARM)
user.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
"<span class='notice'>You splash the contents of [src] onto [target].</span>")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs
var/obj/item/reagent_containers/food/snacks/egg/E = I
if(reagents)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>[src] is full.</span>")
else
to_chat(user, "<span class='notice'>You break [E] in [src].</span>")
E.reagents.trans_to(src, E.reagents.total_volume)
qdel(E)
return
..()
/obj/item/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 60 units. Unable to withstand extreme pHes."
icon = 'icons/obj/chemical.dmi'
volume = 60
icon_state = "beaker"
item_state = "beaker"
materials = list(MAT_GLASS=500)
possible_transfer_amounts = list(5,10,15,20,25,30,50,60)
beaker_weakness_bitflag = PH_WEAK
/obj/item/reagent_containers/glass/beaker/Initialize()
. = ..()
update_icon()
/obj/item/reagent_containers/glass/beaker/get_part_rating()
return reagents.maximum_volume
/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
update_icon()
/obj/item/reagent_containers/glass/beaker/update_icon()
if(!cached_icon)
cached_icon = icon_state
cut_overlays()
if(reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
filling.icon_state = "[cached_icon]-10"
if(10 to 24)
filling.icon_state = "[cached_icon]10"
if(25 to 49)
filling.icon_state = "[cached_icon]25"
if(50 to 74)
filling.icon_state = "[cached_icon]50"
if(75 to 79)
filling.icon_state = "[cached_icon]75"
if(80 to 90)
filling.icon_state = "[cached_icon]80"
if(91 to INFINITY)
filling.icon_state = "[cached_icon]100"
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/reagent_containers/glass/beaker/jar
name = "honey jar"
desc = "A jar for honey. It can hold up to 60 units of sweet delight. Unable to withstand reagents of an extreme pH."
icon = 'icons/obj/chemical.dmi'
icon_state = "vapour"
/obj/item/reagent_containers/glass/beaker/large
name = "large beaker"
desc = "A large beaker. Can hold up to 120 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerlarge"
materials = list(MAT_GLASS=2500)
volume = 120
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120)
container_HP = 3
/obj/item/reagent_containers/glass/beaker/plastic
name = "x-large beaker"
desc = "An extra-large beaker. Can hold up to 180 units. Is able to resist acid and alkaline solutions, but melts at 444 K."
icon_state = "beakerwhite"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
volume = 180
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180)
/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
..()
icon_state = "beakerwhite"
/obj/item/reagent_containers/glass/beaker/meta
name = "metamaterial beaker"
desc = "A large beaker. Can hold up to 240 units, and is able to withstand all chemical situations."
icon_state = "beakergold"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
volume = 240
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,200,240)
/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/noreact
name = "cryostasis beaker"
desc = "A cryostasis beaker that allows for chemical storage without \
reactions. Can hold up to 50 units."
icon_state = "beakernoreact"
materials = list(MAT_METAL=3000)
reagent_flags = OPENCONTAINER | NO_REACT
volume = 50
amount_per_transfer_from_this = 10
container_HP = 10//shouldn't be needed
/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
//reagents.set_reacting(FALSE) was this removed in a recent pr?
/obj/item/reagent_containers/glass/beaker/bluespace
name = "bluespace beaker"
desc = "A bluespace beaker, powered by experimental bluespace technology \
and Element Cuban combined with the Compound Pete. Can hold up to \
300 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerbluespace"
materials = list(MAT_GLASS=3000)
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
container_HP = 5
/obj/item/reagent_containers/glass/beaker/cryoxadone
list_reagents = list(/datum/reagent/medicine/cryoxadone = 30)
/obj/item/reagent_containers/glass/beaker/sulphuric
list_reagents = list(/datum/reagent/toxin/acid = 50)
/obj/item/reagent_containers/glass/beaker/slime
list_reagents = list(/datum/reagent/toxin/slimejelly = 50)
/obj/item/reagent_containers/glass/beaker/large/styptic
name = "styptic reserve tank"
list_reagents = list(/datum/reagent/medicine/styptic_powder = 50)
/obj/item/reagent_containers/glass/beaker/large/silver_sulfadiazine
name = "silver sulfadiazine reserve tank"
list_reagents = list(/datum/reagent/medicine/silver_sulfadiazine = 50)
/obj/item/reagent_containers/glass/beaker/large/charcoal
name = "charcoal reserve tank"
list_reagents = list(/datum/reagent/medicine/charcoal = 50)
/obj/item/reagent_containers/glass/beaker/large/epinephrine
name = "epinephrine reserve tank"
list_reagents = list(/datum/reagent/medicine/epinephrine = 50)
/obj/item/reagent_containers/glass/beaker/synthflesh
list_reagents = list(/datum/reagent/medicine/synthflesh = 50)
/obj/item/reagent_containers/glass/bucket
name = "bucket"
desc = "It's a bucket."
icon = 'icons/obj/janitor.dmi'
icon_state = "bucket"
item_state = "bucket"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
materials = list(MAT_METAL=200)
w_class = WEIGHT_CLASS_NORMAL
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(5,10,15,20,25,30,50,70)
volume = 70
flags_inv = HIDEHAIR
slot_flags = ITEM_SLOT_HEAD
resistance_flags = NONE
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head
slot_equipment_priority = list( \
SLOT_BACK, SLOT_WEAR_ID,\
SLOT_W_UNIFORM, SLOT_WEAR_SUIT,\
SLOT_WEAR_MASK, SLOT_HEAD, SLOT_NECK,\
SLOT_SHOES, SLOT_GLOVES,\
SLOT_EARS, SLOT_GLASSES,\
SLOT_BELT, SLOT_S_STORE,\
SLOT_L_STORE, SLOT_R_STORE,\
SLOT_GENERC_DEXTROUS_STORAGE
)
container_HP = 1
/obj/item/reagent_containers/glass/bucket/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/mop))
if(reagents.total_volume < 1)
to_chat(user, "<span class='warning'>[src] is out of water!</span>")
else
reagents.trans_to(O, 5)
to_chat(user, "<span class='notice'>You wet [O] in [src].</span>")
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
else if(isprox(O))
to_chat(user, "<span class='notice'>You add [O] to [src].</span>")
qdel(O)
qdel(src)
user.put_in_hands(new /obj/item/bot_assembly/cleanbot)
else
..()
/obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot)
..()
if (slot == SLOT_HEAD)
if(reagents.total_volume)
to_chat(user, "<span class='userdanger'>[src]'s contents spill all over you!</span>")
reagents.reaction(user, TOUCH)
reagents.clear_reagents()
reagent_flags = NONE
/obj/item/reagent_containers/glass/bucket/dropped(mob/user)
. = ..()
reagent_flags = initial(reagent_flags)
/obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M)
if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head
var/index = slot_equipment_priority.Find(SLOT_HEAD)
slot_equipment_priority.Remove(SLOT_HEAD)
. = ..()
slot_equipment_priority.Insert(index, SLOT_HEAD)
return
return ..()
/obj/item/reagent_containers/glass/beaker/waterbottle
name = "bottle of water"
desc = "A bottle of water filled at an old Earth bottling facility."
icon = 'icons/obj/drinks.dmi'
icon_state = "smallbottle"
item_state = "bottle"
list_reagents = list(/datum/reagent/water = 49.5, /datum/reagent/fluorine = 0.5)//see desc, don't think about it too hard
materials = list(MAT_GLASS=0)
volume = 50
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50)
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
beaker_weakness_bitflag |= TEMP_WEAK
. = ..()
/obj/item/reagent_containers/glass/beaker/waterbottle/empty
list_reagents = list()
/obj/item/reagent_containers/glass/beaker/waterbottle/large
desc = "A fresh commercial-sized bottle of water."
icon_state = "largebottle"
materials = list(MAT_GLASS=0)
list_reagents = list(/datum/reagent/water = 100)
volume = 100
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
container_HP = 1
/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
list_reagents = list()
/obj/item/reagent_containers/glass/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "bottle")
File diff suppressed because it is too large Load Diff
+324 -324
View File
@@ -1,324 +1,324 @@
/obj/item/reagent_containers/spray
name = "spray bottle"
desc = "A spray bottle, with an unscrewable top."
icon = 'icons/obj/janitor.dmi'
icon_state = "cleaner"
item_state = "cleaner"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
item_flags = NOBLUDGEON
reagent_flags = OPENCONTAINER
slot_flags = ITEM_SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 7
var/stream_mode = 0 //whether we use the more focused mode
var/current_range = 3 //the range of tiles the sprayer will reach.
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
var/spray_delay = 3 //The amount of sleep() delay between each chempuff step.
var/can_fill_from_container = TRUE
amount_per_transfer_from_this = 5
volume = 250
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user)
. = ..()
if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1 && can_fill_from_container)
if(!A.reagents.total_volume)
to_chat(user, "<span class='warning'>[A] is empty.</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill
to_chat(user, "<span class='notice'>You fill \the [src] with [trans] units of the contents of \the [A].</span>")
return
if(reagents.total_volume < amount_per_transfer_from_this)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
spray(A)
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
user.changeNext_move(CLICK_CD_RANGE*2)
user.newtonian_move(get_dir(A, user))
var/turf/T = get_turf(src)
if(reagents.has_reagent(/datum/reagent/toxin/acid))
message_admins("[ADMIN_LOOKUPFLW(user)] fired sulphuric acid from \a [src] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(user)] fired sulphuric acid from \a [src] at [AREACOORD(T)].")
if(reagents.has_reagent(/datum/reagent/toxin/acid/fluacid))
message_admins("[ADMIN_LOOKUPFLW(user)] fired Fluacid from \a [src] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(user)] fired Fluacid from \a [src] at [AREACOORD(T)].")
if(reagents.has_reagent(/datum/reagent/lube))
message_admins("[ADMIN_LOOKUPFLW(user)] fired Space lube from \a [src] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(user)] fired Space lube from \a [src] at [AREACOORD(T)].")
return
/obj/item/reagent_containers/spray/proc/spray(atom/A)
var/range = CLAMP(get_dist(src, A), 1, current_range)
var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src))
D.create_reagents(amount_per_transfer_from_this)
var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed
if(stream_mode)
reagents.trans_to(D, amount_per_transfer_from_this)
puff_reagent_left = 1
else
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
D.color = mix_color_from_reagents(D.reagents.reagent_list)
var/wait_step = max(round(2+ spray_delay * INVERSE(range)), 2)
do_spray(A, wait_step, D, range, puff_reagent_left)
/obj/item/reagent_containers/spray/proc/do_spray(atom/A, wait_step, obj/effect/decal/chempuff/D, range, puff_reagent_left)
set waitfor = FALSE
var/range_left = range
for(var/i=0, i<range, i++)
range_left--
step_towards(D,A)
sleep(wait_step)
for(var/atom/T in get_turf(D))
if(T == D || T.invisibility) //we ignore the puff itself and stuff below the floor
continue
if(puff_reagent_left <= 0)
break
if(stream_mode)
if(ismob(T))
var/mob/M = T
if(!M.lying || !range_left)
D.reagents.reaction(M, VAPOR)
puff_reagent_left -= 1
else if(!range_left)
D.reagents.reaction(T, VAPOR)
else
D.reagents.reaction(T, VAPOR)
if(ismob(T))
puff_reagent_left -= 1
if(puff_reagent_left > 0 && (!stream_mode || !range_left))
D.reagents.reaction(get_turf(D), VAPOR)
puff_reagent_left -= 1
if(puff_reagent_left <= 0) // we used all the puff so we delete it.
qdel(D)
return
qdel(D)
/obj/item/reagent_containers/spray/attack_self(mob/user)
stream_mode = !stream_mode
if(stream_mode)
amount_per_transfer_from_this = stream_amount
current_range = stream_range
else
amount_per_transfer_from_this = initial(amount_per_transfer_from_this)
current_range = spray_range
to_chat(user, "<span class='notice'>You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.</span>")
/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params)
var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
return ..()
/obj/item/reagent_containers/spray/verb/empty()
set name = "Empty Spray Bottle"
set category = "Object"
set src in usr
if(usr.incapacitated())
return
if (alert(usr, "Are you sure you want to empty that?", "Empty Bottle:", "Yes", "No") != "Yes")
return
if(isturf(usr.loc) && src.loc == usr)
to_chat(usr, "<span class='notice'>You empty \the [src] onto the floor.</span>")
reagents.reaction(usr.loc)
src.reagents.clear_reagents()
//space cleaner
/obj/item/reagent_containers/spray/cleaner
name = "space cleaner"
desc = "BLAM!-brand non-foaming space cleaner!"
volume = 100
list_reagents = list(/datum/reagent/space_cleaner = 100)
amount_per_transfer_from_this = 2
stream_amount = 5
/obj/item/reagent_containers/spray/cleaner/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is putting the nozzle of \the [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!</span>")
if(do_mob(user,user,30))
if(reagents.total_volume >= amount_per_transfer_from_this)//if not empty
user.visible_message("<span class='suicide'>[user] pulls the trigger!</span>")
src.spray(user)
return BRUTELOSS
else
user.visible_message("<span class='suicide'>[user] pulls the trigger...but \the [src] is empty!</span>")
return SHAME
else
user.visible_message("<span class='suicide'>[user] decided life was worth living.</span>")
return
//Drying Agent
/obj/item/reagent_containers/spray/drying_agent
name = "drying agent spray"
desc = "A spray bottle for drying agent."
volume = 100
list_reagents = list(/datum/reagent/drying_agent = 100)
amount_per_transfer_from_this = 2
stream_amount = 5
//spray tan
/obj/item/reagent_containers/spray/spraytan
name = "spray tan"
volume = 50
desc = "Gyaro brand spray tan. Do not spray near eyes or other orifices."
list_reagents = list(/datum/reagent/spraytan = 50)
//pepperspray
/obj/item/reagent_containers/spray/pepper
name = "pepperspray"
desc = "Manufactured by UhangInc, used to blind and down an opponent quickly."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "pepperspray"
item_state = "pepperspray"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
volume = 40
stream_range = 4
spray_delay = 1
amount_per_transfer_from_this = 5
list_reagents = list(/datum/reagent/consumable/condensedcapsaicin = 40)
/obj/item/reagent_containers/spray/pepper/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins huffing \the [src]! It looks like [user.p_theyre()] getting a dirty high!</span>")
return OXYLOSS
// Fix pepperspraying yourself
/obj/item/reagent_containers/spray/pepper/afterattack(atom/A as mob|obj, mob/user)
if (A.loc == user)
return
. = ..()
//water flower
/obj/item/reagent_containers/spray/waterflower
name = "water flower"
desc = "A seemingly innocent sunflower...with a twist."
icon = 'icons/obj/hydroponics/harvest.dmi'
icon_state = "sunflower"
item_state = "sunflower"
amount_per_transfer_from_this = 1
volume = 10
list_reagents = list(/datum/reagent/water = 10)
/obj/item/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays
return
///Subtype used for the lavaland clown ruin.
/obj/item/reagent_containers/spray/waterflower/superlube
name = "clown flower"
desc = "A delightly devilish flower... you got a feeling where this is going."
icon = 'icons/obj/chemical.dmi'
icon_state = "clownflower"
volume = 30
list_reagents = list(/datum/reagent/lube/superlube = 30)
/obj/item/reagent_containers/spray/waterflower/cyborg
reagent_flags = NONE
volume = 100
list_reagents = list(/datum/reagent/water = 100)
var/generate_amount = 5
var/generate_type = /datum/reagent/water
var/last_generate = 0
var/generate_delay = 10 //deciseconds
can_fill_from_container = FALSE
/obj/item/reagent_containers/spray/waterflower/cyborg/hacked
name = "nova flower"
desc = "This doesn't look safe at all..."
list_reagents = list(/datum/reagent/clf3 = 3)
volume = 3
generate_type = /datum/reagent/clf3
generate_amount = 1
generate_delay = 40 //deciseconds
/obj/item/reagent_containers/spray/waterflower/cyborg/Initialize()
. = ..()
START_PROCESSING(SSfastprocess, src)
/obj/item/reagent_containers/spray/waterflower/cyborg/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/item/reagent_containers/spray/waterflower/cyborg/process()
if(world.time < last_generate + generate_delay)
return
last_generate = world.time
generate_reagents()
/obj/item/reagent_containers/spray/waterflower/cyborg/empty()
to_chat(usr, "<span class='warning'>You can not empty this!</span>")
return
/obj/item/reagent_containers/spray/waterflower/cyborg/proc/generate_reagents()
reagents.add_reagent(generate_type, generate_amount)
//chemsprayer
/obj/item/reagent_containers/spray/chemsprayer
name = "chem sprayer"
desc = "A utility used to spray large amounts of reagents in a given area."
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "chemsprayer"
item_state = "chemsprayer"
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
throwforce = 0
w_class = WEIGHT_CLASS_NORMAL
stream_mode = 1
current_range = 7
spray_range = 4
stream_range = 7
amount_per_transfer_from_this = 10
volume = 600
/obj/item/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user)
// Make it so the bioterror spray doesn't spray yourself when you click your inventory items
if (A.loc == user)
return
. = ..()
/obj/item/reagent_containers/spray/chemsprayer/spray(atom/A)
var/direction = get_dir(src, A)
var/turf/T = get_turf(A)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
for(var/i=1, i<=3, i++) // intialize sprays
if(reagents.total_volume < 1)
return
..(the_targets[i])
/obj/item/reagent_containers/spray/chemsprayer/bioterror
list_reagents = list(/datum/reagent/toxin/sodium_thiopental = 100, /datum/reagent/toxin/coniine = 100, /datum/reagent/toxin/venom = 100, /datum/reagent/consumable/condensedcapsaicin = 100, /datum/reagent/toxin/initropidril = 100, /datum/reagent/toxin/polonium = 100)
// Plant-B-Gone
/obj/item/reagent_containers/spray/plantbgone // -- Skie
name = "Plant-B-Gone"
desc = "Kills those pesky weeds!"
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "plantbgone"
item_state = "plantbgone"
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
volume = 100
list_reagents = list(/datum/reagent/toxin/plantbgone = 100)
/obj/item/reagent_containers/spray
name = "spray bottle"
desc = "A spray bottle, with an unscrewable top."
icon = 'icons/obj/janitor.dmi'
icon_state = "cleaner"
item_state = "cleaner"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
item_flags = NOBLUDGEON
reagent_flags = OPENCONTAINER
slot_flags = ITEM_SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 7
var/stream_mode = 0 //whether we use the more focused mode
var/current_range = 3 //the range of tiles the sprayer will reach.
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
var/spray_delay = 3 //The amount of sleep() delay between each chempuff step.
var/can_fill_from_container = TRUE
amount_per_transfer_from_this = 5
volume = 250
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user)
. = ..()
if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1 && can_fill_from_container)
if(!A.reagents.total_volume)
to_chat(user, "<span class='warning'>[A] is empty.</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill
to_chat(user, "<span class='notice'>You fill \the [src] with [trans] units of the contents of \the [A].</span>")
return
if(reagents.total_volume < amount_per_transfer_from_this)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
spray(A)
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
user.changeNext_move(CLICK_CD_RANGE*2)
user.newtonian_move(get_dir(A, user))
var/turf/T = get_turf(src)
if(reagents.has_reagent(/datum/reagent/toxin/acid))
message_admins("[ADMIN_LOOKUPFLW(user)] fired sulphuric acid from \a [src] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(user)] fired sulphuric acid from \a [src] at [AREACOORD(T)].")
if(reagents.has_reagent(/datum/reagent/toxin/acid/fluacid))
message_admins("[ADMIN_LOOKUPFLW(user)] fired Fluacid from \a [src] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(user)] fired Fluacid from \a [src] at [AREACOORD(T)].")
if(reagents.has_reagent(/datum/reagent/lube))
message_admins("[ADMIN_LOOKUPFLW(user)] fired Space lube from \a [src] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(user)] fired Space lube from \a [src] at [AREACOORD(T)].")
return
/obj/item/reagent_containers/spray/proc/spray(atom/A)
var/range = CLAMP(get_dist(src, A), 1, current_range)
var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src))
D.create_reagents(amount_per_transfer_from_this)
var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed
if(stream_mode)
reagents.trans_to(D, amount_per_transfer_from_this)
puff_reagent_left = 1
else
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
D.color = mix_color_from_reagents(D.reagents.reagent_list)
var/wait_step = max(round(2+ spray_delay * INVERSE(range)), 2)
do_spray(A, wait_step, D, range, puff_reagent_left)
/obj/item/reagent_containers/spray/proc/do_spray(atom/A, wait_step, obj/effect/decal/chempuff/D, range, puff_reagent_left)
set waitfor = FALSE
var/range_left = range
for(var/i=0, i<range, i++)
range_left--
step_towards(D,A)
sleep(wait_step)
for(var/atom/T in get_turf(D))
if(T == D || T.invisibility) //we ignore the puff itself and stuff below the floor
continue
if(puff_reagent_left <= 0)
break
if(stream_mode)
if(ismob(T))
var/mob/M = T
if(!M.lying || !range_left)
D.reagents.reaction(M, VAPOR)
puff_reagent_left -= 1
else if(!range_left)
D.reagents.reaction(T, VAPOR)
else
D.reagents.reaction(T, VAPOR)
if(ismob(T))
puff_reagent_left -= 1
if(puff_reagent_left > 0 && (!stream_mode || !range_left))
D.reagents.reaction(get_turf(D), VAPOR)
puff_reagent_left -= 1
if(puff_reagent_left <= 0) // we used all the puff so we delete it.
qdel(D)
return
qdel(D)
/obj/item/reagent_containers/spray/attack_self(mob/user)
stream_mode = !stream_mode
if(stream_mode)
amount_per_transfer_from_this = stream_amount
current_range = stream_range
else
amount_per_transfer_from_this = initial(amount_per_transfer_from_this)
current_range = spray_range
to_chat(user, "<span class='notice'>You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.</span>")
/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params)
var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
return ..()
/obj/item/reagent_containers/spray/verb/empty()
set name = "Empty Spray Bottle"
set category = "Object"
set src in usr
if(usr.incapacitated())
return
if (alert(usr, "Are you sure you want to empty that?", "Empty Bottle:", "Yes", "No") != "Yes")
return
if(isturf(usr.loc) && src.loc == usr)
to_chat(usr, "<span class='notice'>You empty \the [src] onto the floor.</span>")
reagents.reaction(usr.loc)
src.reagents.clear_reagents()
//space cleaner
/obj/item/reagent_containers/spray/cleaner
name = "space cleaner"
desc = "BLAM!-brand non-foaming space cleaner!"
volume = 100
list_reagents = list(/datum/reagent/space_cleaner = 100)
amount_per_transfer_from_this = 2
stream_amount = 5
/obj/item/reagent_containers/spray/cleaner/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is putting the nozzle of \the [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!</span>")
if(do_mob(user,user,30))
if(reagents.total_volume >= amount_per_transfer_from_this)//if not empty
user.visible_message("<span class='suicide'>[user] pulls the trigger!</span>")
src.spray(user)
return BRUTELOSS
else
user.visible_message("<span class='suicide'>[user] pulls the trigger...but \the [src] is empty!</span>")
return SHAME
else
user.visible_message("<span class='suicide'>[user] decided life was worth living.</span>")
return
//Drying Agent
/obj/item/reagent_containers/spray/drying_agent
name = "drying agent spray"
desc = "A spray bottle for drying agent."
volume = 100
list_reagents = list(/datum/reagent/drying_agent = 100)
amount_per_transfer_from_this = 2
stream_amount = 5
//spray tan
/obj/item/reagent_containers/spray/spraytan
name = "spray tan"
volume = 50
desc = "Gyaro brand spray tan. Do not spray near eyes or other orifices."
list_reagents = list(/datum/reagent/spraytan = 50)
//pepperspray
/obj/item/reagent_containers/spray/pepper
name = "pepperspray"
desc = "Manufactured by UhangInc, used to blind and down an opponent quickly."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "pepperspray"
item_state = "pepperspray"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
volume = 40
stream_range = 4
spray_delay = 1
amount_per_transfer_from_this = 5
list_reagents = list(/datum/reagent/consumable/condensedcapsaicin = 40)
/obj/item/reagent_containers/spray/pepper/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins huffing \the [src]! It looks like [user.p_theyre()] getting a dirty high!</span>")
return OXYLOSS
// Fix pepperspraying yourself
/obj/item/reagent_containers/spray/pepper/afterattack(atom/A as mob|obj, mob/user)
if (A.loc == user)
return
. = ..()
//water flower
/obj/item/reagent_containers/spray/waterflower
name = "water flower"
desc = "A seemingly innocent sunflower...with a twist."
icon = 'icons/obj/hydroponics/harvest.dmi'
icon_state = "sunflower"
item_state = "sunflower"
amount_per_transfer_from_this = 1
volume = 10
list_reagents = list(/datum/reagent/water = 10)
/obj/item/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays
return
///Subtype used for the lavaland clown ruin.
/obj/item/reagent_containers/spray/waterflower/superlube
name = "clown flower"
desc = "A delightly devilish flower... you got a feeling where this is going."
icon = 'icons/obj/chemical.dmi'
icon_state = "clownflower"
volume = 30
list_reagents = list(/datum/reagent/lube/superlube = 30)
/obj/item/reagent_containers/spray/waterflower/cyborg
reagent_flags = NONE
volume = 100
list_reagents = list(/datum/reagent/water = 100)
var/generate_amount = 5
var/generate_type = /datum/reagent/water
var/last_generate = 0
var/generate_delay = 10 //deciseconds
can_fill_from_container = FALSE
/obj/item/reagent_containers/spray/waterflower/cyborg/hacked
name = "nova flower"
desc = "This doesn't look safe at all..."
list_reagents = list(/datum/reagent/clf3 = 3)
volume = 3
generate_type = /datum/reagent/clf3
generate_amount = 1
generate_delay = 40 //deciseconds
/obj/item/reagent_containers/spray/waterflower/cyborg/Initialize()
. = ..()
START_PROCESSING(SSfastprocess, src)
/obj/item/reagent_containers/spray/waterflower/cyborg/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/item/reagent_containers/spray/waterflower/cyborg/process()
if(world.time < last_generate + generate_delay)
return
last_generate = world.time
generate_reagents()
/obj/item/reagent_containers/spray/waterflower/cyborg/empty()
to_chat(usr, "<span class='warning'>You can not empty this!</span>")
return
/obj/item/reagent_containers/spray/waterflower/cyborg/proc/generate_reagents()
reagents.add_reagent(generate_type, generate_amount)
//chemsprayer
/obj/item/reagent_containers/spray/chemsprayer
name = "chem sprayer"
desc = "A utility used to spray large amounts of reagents in a given area."
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "chemsprayer"
item_state = "chemsprayer"
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
throwforce = 0
w_class = WEIGHT_CLASS_NORMAL
stream_mode = 1
current_range = 7
spray_range = 4
stream_range = 7
amount_per_transfer_from_this = 10
volume = 600
/obj/item/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user)
// Make it so the bioterror spray doesn't spray yourself when you click your inventory items
if (A.loc == user)
return
. = ..()
/obj/item/reagent_containers/spray/chemsprayer/spray(atom/A)
var/direction = get_dir(src, A)
var/turf/T = get_turf(A)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
for(var/i=1, i<=3, i++) // intialize sprays
if(reagents.total_volume < 1)
return
..(the_targets[i])
/obj/item/reagent_containers/spray/chemsprayer/bioterror
list_reagents = list(/datum/reagent/toxin/sodium_thiopental = 100, /datum/reagent/toxin/coniine = 100, /datum/reagent/toxin/venom = 100, /datum/reagent/consumable/condensedcapsaicin = 100, /datum/reagent/toxin/initropidril = 100, /datum/reagent/toxin/polonium = 100)
// Plant-B-Gone
/obj/item/reagent_containers/spray/plantbgone // -- Skie
name = "Plant-B-Gone"
desc = "Kills those pesky weeds!"
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "plantbgone"
item_state = "plantbgone"
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
volume = 100
list_reagents = list(/datum/reagent/toxin/plantbgone = 100)
@@ -1,351 +1,351 @@
/obj/item/reagent_containers/syringe
name = "syringe"
desc = "A syringe that can hold up to 15 units."
icon = 'icons/obj/syringe.dmi'
item_state = "syringe_0"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
icon_state = "0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 15
var/mode = SYRINGE_DRAW
var/busy = FALSE // needed for delayed drawing of blood
var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun
materials = list(MAT_METAL=10, MAT_GLASS=20)
reagent_flags = TRANSPARENT
/obj/item/reagent_containers/syringe/Initialize()
. = ..()
if(list_reagents) //syringe starts in inject mode if its already got something inside
mode = SYRINGE_INJECT
update_icon()
/obj/item/reagent_containers/syringe/on_reagent_change(changetype)
update_icon()
/obj/item/reagent_containers/syringe/pickup(mob/user)
..()
update_icon()
/obj/item/reagent_containers/syringe/dropped(mob/user)
..()
update_icon()
/obj/item/reagent_containers/syringe/attack_self(mob/user)
mode = !mode
update_icon()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/reagent_containers/syringe/attack_hand()
. = ..()
update_icon()
/obj/item/reagent_containers/syringe/attack_paw(mob/user)
return attack_hand(user)
/obj/item/reagent_containers/syringe/attackby(obj/item/I, mob/user, params)
return
/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user , proximity)
. = ..()
if(busy)
return
if(!proximity)
return
if(!target.reagents)
return
var/mob/living/L
if(isliving(target))
L = target
if(!L.can_inject(user, 1))
return
// chance of monkey retaliation
if(ismonkey(target) && prob(MONKEY_SYRINGE_RETALIATION_PROB))
var/mob/living/carbon/monkey/M
M = target
M.retaliate(user)
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>The syringe is full.</span>")
return
if(L) //living mob
var/drawn_amount = reagents.maximum_volume - reagents.total_volume
if(target != user)
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, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,user,1)))
busy = FALSE
return
if(reagents.total_volume >= reagents.maximum_volume)
return
busy = FALSE
if(L.transfer_blood_to(src, drawn_amount))
user.visible_message("[user] takes a blood sample from [L].")
else
to_chat(user, "<span class='warning'>You are unable to draw any blood from [L]!</span>")
else //if not mob
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty!</span>")
return
if(!target.is_drawable())
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target]!</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.</span>")
if (round(reagents.total_volume, 0.1) >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
// Always log attemped injections for admins
var/contained = reagents.log_list()
log_combat(user, target, "attempted to inject", src, addition="which had [contained]")
if(!reagents.total_volume)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return
if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles
to_chat(user, "<span class='warning'>You cannot directly fill [target]!</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[target] is full.</span>")
return
if(L) //living mob
if(!L.can_inject(user, TRUE))
return
if(L != user)
L.visible_message("<span class='danger'>[user] is trying to inject [L]!</span>", \
"<span class='userdanger'>[user] is trying to inject [L]!</span>")
if(!do_mob(user, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,user,1)))
return
if(!reagents.total_volume)
return
if(L.reagents.total_volume >= L.reagents.maximum_volume)
return
L.visible_message("<span class='danger'>[user] injects [L] with the syringe!", \
"<span class='userdanger'>[user] injects [L] with the syringe!</span>")
if(L != user)
log_combat(user, L, "injected", src, addition="which had [contained]")
else
L.log_message("injected themselves ([contained]) with [src.name]", LOG_ATTACK, color="orange")
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
reagents.reaction(L, INJECT, fraction)
reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.</span>")
if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
/obj/item/reagent_containers/syringe/update_icon()
cut_overlays()
var/rounded_vol
if(reagents && reagents.total_volume)
rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 1, 15)
var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]")
filling_overlay.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling_overlay)
else
rounded_vol = 0
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(ismob(loc))
var/mob/M = loc
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "inject"
add_overlay(injoverlay)
M.update_inv_hands()
/obj/item/reagent_containers/syringe/epinephrine
name = "syringe (epinephrine)"
desc = "Contains epinephrine - used to stabilize patients."
list_reagents = list(/datum/reagent/medicine/epinephrine = 15)
/obj/item/reagent_containers/syringe/charcoal
name = "syringe (charcoal)"
desc = "Contains charcoal."
list_reagents = list(/datum/reagent/medicine/charcoal = 15)
/obj/item/reagent_containers/syringe/antiviral
name = "syringe (spaceacillin)"
desc = "Contains antiviral agents."
list_reagents = list(/datum/reagent/medicine/spaceacillin = 15)
/obj/item/reagent_containers/syringe/bioterror
name = "bioterror syringe"
desc = "Contains several paralyzing reagents."
list_reagents = list(/datum/reagent/consumable/ethanol/neurotoxin = 5, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/toxin/sodium_thiopental = 5)
/obj/item/reagent_containers/syringe/stimulants
name = "Stimpack"
desc = "Contains stimulants."
amount_per_transfer_from_this = 50
volume = 50
list_reagents = list(/datum/reagent/medicine/stimulants = 50)
/obj/item/reagent_containers/syringe/calomel
name = "syringe (calomel)"
desc = "Contains calomel."
list_reagents = list(/datum/reagent/medicine/calomel = 15)
/obj/item/reagent_containers/syringe/plasma
name = "syringe (plasma)"
desc = "Contains plasma."
list_reagents = list(/datum/reagent/toxin/plasma = 15)
/obj/item/reagent_containers/syringe/lethal
name = "lethal injection syringe"
desc = "A syringe used for lethal injections. It can hold up to 50 units."
amount_per_transfer_from_this = 50
volume = 50
/obj/item/reagent_containers/syringe/lethal/choral
list_reagents = list(/datum/reagent/toxin/chloralhydrate = 50)
/obj/item/reagent_containers/syringe/lethal/execution
list_reagents = list(/datum/reagent/toxin/amatoxin = 15, /datum/reagent/toxin/formaldehyde = 15, /datum/reagent/toxin/cyanide = 10, /datum/reagent/toxin/acid/fluacid = 10) //Citadel edit, changing out plasma from lethals
/obj/item/reagent_containers/syringe/mulligan
name = "Mulligan"
desc = "A syringe used to completely change the users identity."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list(/datum/reagent/mulligan = 1)
/obj/item/reagent_containers/syringe/gluttony
name = "Gluttony's Blessing"
desc = "A syringe recovered from a dread place. It probably isn't wise to use."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list(/datum/reagent/gluttonytoxin = 1)
/obj/item/reagent_containers/syringe/bluespace
name = "bluespace syringe"
desc = "An advanced syringe that can hold 60 units of chemicals."
amount_per_transfer_from_this = 20
volume = 60
/obj/item/reagent_containers/syringe/noreact
name = "cryo syringe"
desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units."
volume = 20
reagent_flags = TRANSPARENT | NO_REACT
/obj/item/reagent_containers/syringe/piercing
name = "piercing syringe"
desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units."
volume = 10
proj_piercing = 1
/obj/item/reagent_containers/syringe/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
/obj/item/reagent_containers/syringe/dart
name = "medicinal smartdart"
desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented."
volume = 20
amount_per_transfer_from_this = 20
icon_state = "empty"
item_state = "syringe_empty"
var/emptrig = FALSE
/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity)
if(busy)
return
if(!proximity)
return
if(!target.reagents)
return
var/mob/living/L
if(isliving(target))
L = target
if(!L.can_inject(user, 1))
return
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>The dart is full!</span>")
return
if(L) //living mob
to_chat(user, "<span class='warning'>You can't draw blood using a dart!</span>")
return
else //if not mob
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty!</span>")
return
if(!target.is_drawable())
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target]!</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.</span>")
if (round(reagents.total_volume,1) >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
src.visible_message("<span class='danger'>The smartdart gives a frustrated boop! It's fully saturated; You need to shoot someone with it!</span>")
/obj/item/reagent_containers/syringe/dart/attack_self(mob/user)
return
/obj/item/reagent_containers/syringe/dart/update_icon()
cut_overlays()
var/rounded_vol
rounded_vol = "empty"
if(reagents && reagents.total_volume)
if(volume/round(reagents.total_volume, 1) == 1)
rounded_vol="full"
mode = SYRINGE_INJECT
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(ismob(loc))
var/mob/M = loc
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "ready"
add_overlay(injoverlay)
M.update_inv_hands()
/obj/item/reagent_containers/syringe/dart/emp_act(severity)
emptrig = TRUE
..()
/obj/item/reagent_containers/syringe/dart/bluespace
name = "bluespace smartdart"
desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam."
amount_per_transfer_from_this = 50
volume = 50
/obj/item/reagent_containers/syringe
name = "syringe"
desc = "A syringe that can hold up to 15 units."
icon = 'icons/obj/syringe.dmi'
item_state = "syringe_0"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
icon_state = "0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 15
var/mode = SYRINGE_DRAW
var/busy = FALSE // needed for delayed drawing of blood
var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun
materials = list(MAT_METAL=10, MAT_GLASS=20)
reagent_flags = TRANSPARENT
/obj/item/reagent_containers/syringe/Initialize()
. = ..()
if(list_reagents) //syringe starts in inject mode if its already got something inside
mode = SYRINGE_INJECT
update_icon()
/obj/item/reagent_containers/syringe/on_reagent_change(changetype)
update_icon()
/obj/item/reagent_containers/syringe/pickup(mob/user)
..()
update_icon()
/obj/item/reagent_containers/syringe/dropped(mob/user)
..()
update_icon()
/obj/item/reagent_containers/syringe/attack_self(mob/user)
mode = !mode
update_icon()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/reagent_containers/syringe/attack_hand()
. = ..()
update_icon()
/obj/item/reagent_containers/syringe/attack_paw(mob/user)
return attack_hand(user)
/obj/item/reagent_containers/syringe/attackby(obj/item/I, mob/user, params)
return
/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user , proximity)
. = ..()
if(busy)
return
if(!proximity)
return
if(!target.reagents)
return
var/mob/living/L
if(isliving(target))
L = target
if(!L.can_inject(user, 1))
return
// chance of monkey retaliation
if(ismonkey(target) && prob(MONKEY_SYRINGE_RETALIATION_PROB))
var/mob/living/carbon/monkey/M
M = target
M.retaliate(user)
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>The syringe is full.</span>")
return
if(L) //living mob
var/drawn_amount = reagents.maximum_volume - reagents.total_volume
if(target != user)
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, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,user,1)))
busy = FALSE
return
if(reagents.total_volume >= reagents.maximum_volume)
return
busy = FALSE
if(L.transfer_blood_to(src, drawn_amount))
user.visible_message("[user] takes a blood sample from [L].")
else
to_chat(user, "<span class='warning'>You are unable to draw any blood from [L]!</span>")
else //if not mob
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty!</span>")
return
if(!target.is_drawable())
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target]!</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.</span>")
if (round(reagents.total_volume, 0.1) >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
// Always log attemped injections for admins
var/contained = reagents.log_list()
log_combat(user, target, "attempted to inject", src, addition="which had [contained]")
if(!reagents.total_volume)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return
if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles
to_chat(user, "<span class='warning'>You cannot directly fill [target]!</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='notice'>[target] is full.</span>")
return
if(L) //living mob
if(!L.can_inject(user, TRUE))
return
if(L != user)
L.visible_message("<span class='danger'>[user] is trying to inject [L]!</span>", \
"<span class='userdanger'>[user] is trying to inject [L]!</span>")
if(!do_mob(user, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,user,1)))
return
if(!reagents.total_volume)
return
if(L.reagents.total_volume >= L.reagents.maximum_volume)
return
L.visible_message("<span class='danger'>[user] injects [L] with the syringe!", \
"<span class='userdanger'>[user] injects [L] with the syringe!</span>")
if(L != user)
log_combat(user, L, "injected", src, addition="which had [contained]")
else
L.log_message("injected themselves ([contained]) with [src.name]", LOG_ATTACK, color="orange")
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
reagents.reaction(L, INJECT, fraction)
reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.</span>")
if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
/obj/item/reagent_containers/syringe/update_icon()
cut_overlays()
var/rounded_vol
if(reagents && reagents.total_volume)
rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 1, 15)
var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]")
filling_overlay.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling_overlay)
else
rounded_vol = 0
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(ismob(loc))
var/mob/M = loc
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "inject"
add_overlay(injoverlay)
M.update_inv_hands()
/obj/item/reagent_containers/syringe/epinephrine
name = "syringe (epinephrine)"
desc = "Contains epinephrine - used to stabilize patients."
list_reagents = list(/datum/reagent/medicine/epinephrine = 15)
/obj/item/reagent_containers/syringe/charcoal
name = "syringe (charcoal)"
desc = "Contains charcoal."
list_reagents = list(/datum/reagent/medicine/charcoal = 15)
/obj/item/reagent_containers/syringe/antiviral
name = "syringe (spaceacillin)"
desc = "Contains antiviral agents."
list_reagents = list(/datum/reagent/medicine/spaceacillin = 15)
/obj/item/reagent_containers/syringe/bioterror
name = "bioterror syringe"
desc = "Contains several paralyzing reagents."
list_reagents = list(/datum/reagent/consumable/ethanol/neurotoxin = 5, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/toxin/sodium_thiopental = 5)
/obj/item/reagent_containers/syringe/stimulants
name = "Stimpack"
desc = "Contains stimulants."
amount_per_transfer_from_this = 50
volume = 50
list_reagents = list(/datum/reagent/medicine/stimulants = 50)
/obj/item/reagent_containers/syringe/calomel
name = "syringe (calomel)"
desc = "Contains calomel."
list_reagents = list(/datum/reagent/medicine/calomel = 15)
/obj/item/reagent_containers/syringe/plasma
name = "syringe (plasma)"
desc = "Contains plasma."
list_reagents = list(/datum/reagent/toxin/plasma = 15)
/obj/item/reagent_containers/syringe/lethal
name = "lethal injection syringe"
desc = "A syringe used for lethal injections. It can hold up to 50 units."
amount_per_transfer_from_this = 50
volume = 50
/obj/item/reagent_containers/syringe/lethal/choral
list_reagents = list(/datum/reagent/toxin/chloralhydrate = 50)
/obj/item/reagent_containers/syringe/lethal/execution
list_reagents = list(/datum/reagent/toxin/amatoxin = 15, /datum/reagent/toxin/formaldehyde = 15, /datum/reagent/toxin/cyanide = 10, /datum/reagent/toxin/acid/fluacid = 10) //Citadel edit, changing out plasma from lethals
/obj/item/reagent_containers/syringe/mulligan
name = "Mulligan"
desc = "A syringe used to completely change the users identity."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list(/datum/reagent/mulligan = 1)
/obj/item/reagent_containers/syringe/gluttony
name = "Gluttony's Blessing"
desc = "A syringe recovered from a dread place. It probably isn't wise to use."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list(/datum/reagent/gluttonytoxin = 1)
/obj/item/reagent_containers/syringe/bluespace
name = "bluespace syringe"
desc = "An advanced syringe that can hold 60 units of chemicals."
amount_per_transfer_from_this = 20
volume = 60
/obj/item/reagent_containers/syringe/noreact
name = "cryo syringe"
desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units."
volume = 20
reagent_flags = TRANSPARENT | NO_REACT
/obj/item/reagent_containers/syringe/piercing
name = "piercing syringe"
desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units."
volume = 10
proj_piercing = 1
/obj/item/reagent_containers/syringe/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
/obj/item/reagent_containers/syringe/dart
name = "medicinal smartdart"
desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented."
volume = 20
amount_per_transfer_from_this = 20
icon_state = "empty"
item_state = "syringe_empty"
var/emptrig = FALSE
/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity)
if(busy)
return
if(!proximity)
return
if(!target.reagents)
return
var/mob/living/L
if(isliving(target))
L = target
if(!L.can_inject(user, 1))
return
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>The dart is full!</span>")
return
if(L) //living mob
to_chat(user, "<span class='warning'>You can't draw blood using a dart!</span>")
return
else //if not mob
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty!</span>")
return
if(!target.is_drawable())
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target]!</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.</span>")
if (round(reagents.total_volume,1) >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
src.visible_message("<span class='danger'>The smartdart gives a frustrated boop! It's fully saturated; You need to shoot someone with it!</span>")
/obj/item/reagent_containers/syringe/dart/attack_self(mob/user)
return
/obj/item/reagent_containers/syringe/dart/update_icon()
cut_overlays()
var/rounded_vol
rounded_vol = "empty"
if(reagents && reagents.total_volume)
if(volume/round(reagents.total_volume, 1) == 1)
rounded_vol="full"
mode = SYRINGE_INJECT
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(ismob(loc))
var/mob/M = loc
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "ready"
add_overlay(injoverlay)
M.update_inv_hands()
/obj/item/reagent_containers/syringe/dart/emp_act(severity)
emptrig = TRUE
..()
/obj/item/reagent_containers/syringe/dart/bluespace
name = "bluespace smartdart"
desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam."
amount_per_transfer_from_this = 50
volume = 50
+252 -252
View File
@@ -1,253 +1,253 @@
/obj/structure/reagent_dispensers
name = "Dispenser"
desc = "..."
icon = 'icons/obj/objects.dmi'
icon_state = "water"
density = TRUE
anchored = FALSE
pressure_resistance = 2*ONE_ATMOSPHERE
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = /datum/reagent/water //The ID of the reagent that the dispenser uses
/obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(. && obj_integrity > 0)
if(tank_volume && (damage_flag == "bullet" || damage_flag == "laser"))
boom()
/obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params)
if(W.is_refillable())
return 0 //so we can refill them via their afterattack.
else
return ..()
/obj/structure/reagent_dispensers/Initialize()
create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE)
reagents.add_reagent(reagent_id, tank_volume)
. = ..()
/obj/structure/reagent_dispensers/proc/boom()
visible_message("<span class='danger'>\The [src] ruptures!</span>")
chem_splash(loc, 5, list(reagents))
qdel(src)
/obj/structure/reagent_dispensers/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(!disassembled)
boom()
else
qdel(src)
///////////////
//Water Tanks//
///////////////
/obj/structure/reagent_dispensers/watertank
name = "water tank"
desc = "A water tank."
icon_state = "water"
/obj/structure/reagent_dispensers/watertank/high
name = "high-capacity water tank"
desc = "A highly pressurized water tank made to hold gargantuan amounts of water."
icon_state = "water_high" //I was gonna clean my room...
tank_volume = 100000
/obj/structure/reagent_dispensers/foamtank
name = "firefighting foam tank"
desc = "A tank full of firefighting foam."
icon_state = "foam"
reagent_id = /datum/reagent/firefighting_foam
tank_volume = 500
/obj/structure/reagent_dispensers/water_cooler
name = "liquid cooler"
desc = "A machine that dispenses liquid to drink."
icon = 'icons/obj/vending.dmi'
icon_state = "water_cooler"
anchored = TRUE
tank_volume = 500
var/paper_cups = 25 //Paper cups left from the cooler
/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
. = ..()
if (paper_cups > 1)
. += "There are [paper_cups] paper cups left."
else if (paper_cups == 1)
. += "There is one paper cup left."
else
. += "There are no paper cups left."
/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!paper_cups)
to_chat(user, "<span class='warning'>There aren't any cups left!</span>")
return
user.visible_message("<span class='notice'>[user] takes a cup from [src].</span>", "<span class='notice'>You take a paper cup from [src].</span>")
var/obj/item/reagent_containers/food/drinks/sillycup/S = new(get_turf(src))
user.put_in_hands(S)
paper_cups--
//////////////
//Fuel Tanks//
//////////////
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank full of industrial welding fuel. Do not consume."
icon_state = "fuel"
reagent_id = /datum/reagent/fuel
/obj/structure/reagent_dispensers/fueltank/high //Unused - Good for ghost roles
name = "high-capacity fuel tank"
desc = "A now illegal tank, full of highly pressurized industrial welding fuel. Do not consume or have a open flame close to this tank."
icon_state = "fuel_high"
tank_volume = 3000
/obj/structure/reagent_dispensers/fueltank/boom()
explosion(get_turf(src), 0, 1, 5, flame_range = 5)
qdel(src)
/obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B)
boom()
/obj/structure/reagent_dispensers/fueltank/ex_act()
boom()
/obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume)
boom()
/obj/structure/reagent_dispensers/fueltank/tesla_act()
..() //extend the zap
boom()
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P)
..()
if(!QDELETED(src)) //wasn't deleted by the projectile's effects.
if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE)))
var/boom_message = "[ADMIN_LOOKUPFLW(P.firer)] triggered a fueltank explosion via projectile."
GLOB.bombers += boom_message
message_admins(boom_message)
P.firer.log_message("triggered a fueltank explosion via projectile.", LOG_ATTACK)
boom()
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/weldingtool))
if(!reagents.has_reagent(/datum/reagent/fuel))
to_chat(user, "<span class='warning'>[src] is out of fuel!</span>")
return
var/obj/item/weldingtool/W = I
if(!W.welding)
if(W.reagents.has_reagent(/datum/reagent/fuel, W.max_fuel))
to_chat(user, "<span class='warning'>Your [W.name] is already full!</span>")
return
reagents.trans_to(W, W.max_fuel)
user.visible_message("<span class='notice'>[user] refills [user.p_their()] [W.name].</span>", "<span class='notice'>You refill [W].</span>")
playsound(src, 'sound/effects/refill.ogg', 50, 1)
W.update_icon()
else
var/turf/T = get_turf(src)
user.visible_message("<span class='warning'>[user] catastrophically fails at refilling [user.p_their()] [W.name]!</span>", "<span class='userdanger'>That was stupid of you.</span>")
var/message_admins = "[ADMIN_LOOKUPFLW(user)] triggered a fueltank explosion via welding tool at [ADMIN_VERBOSEJMP(T)]."
GLOB.bombers += message_admins
message_admins(message_admins)
user.log_message("triggered a fueltank explosion via welding tool.", LOG_ATTACK)
boom()
return
return ..()
///////////////////
//Misc Dispenders//
///////////////////
/obj/structure/reagent_dispensers/peppertank
name = "pepper spray refiller"
desc = "Contains condensed capsaicin for use in law \"enforcement.\""
icon_state = "pepper"
anchored = TRUE
density = FALSE
reagent_id = /datum/reagent/consumable/condensedcapsaicin
/obj/structure/reagent_dispensers/peppertank/Initialize()
. = ..()
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
/obj/structure/reagent_dispensers/virusfood
name = "virus food dispenser"
desc = "A dispenser of low-potency virus mutagenic."
icon_state = "virus_food"
anchored = TRUE
density = FALSE
reagent_id = /datum/reagent/toxin/mutagen/mutagenvirusfood
/obj/structure/reagent_dispensers/cooking_oil
name = "vat of cooking oil"
desc = "A huge metal vat with a tap on the front. Filled with cooking oil for use in frying food."
icon_state = "vat"
anchored = TRUE
reagent_id = /datum/reagent/consumable/cooking_oil
////////
//Kegs//
////////
/obj/structure/reagent_dispensers/beerkeg
name = "beer keg"
desc = "Beer is liquid bread, it's good for you..."
icon_state = "beer"
reagent_id = /datum/reagent/consumable/ethanol/beer
/obj/structure/reagent_dispensers/beerkeg/blob_act(obj/structure/blob/B)
explosion(src.loc,0,3,5,7,10)
if(!QDELETED(src))
qdel(src)
/obj/structure/reagent_dispensers/keg
name = "keg"
desc = "A keg."
icon = 'modular_citadel/icons/obj/objects.dmi'
icon_state = "keg"
/obj/structure/reagent_dispensers/keg/mead
name = "keg of mead"
desc = "A keg of mead."
icon_state = "orangekeg"
reagent_id = /datum/reagent/consumable/ethanol/mead
/obj/structure/reagent_dispensers/keg/aphro
name = "keg of aphrodisiac"
desc = "A keg of aphrodisiac."
icon_state = "pinkkeg"
reagent_id = /datum/reagent/drug/aphrodisiac
tank_volume = 150
/obj/structure/reagent_dispensers/keg/aphro/strong
name = "keg of strong aphrodisiac"
desc = "A keg of strong and addictive aphrodisiac."
reagent_id = /datum/reagent/drug/aphrodisiacplus
tank_volume = 120
/obj/structure/reagent_dispensers/keg/milk
name = "keg of milk"
desc = "It's not quite what you were hoping for."
icon_state = "whitekeg"
reagent_id = /datum/reagent/consumable/milk
/obj/structure/reagent_dispensers/keg/semen
name = "keg of semen"
desc = "Dear lord, where did this even come from?"
icon_state = "whitekeg"
reagent_id = /datum/reagent/consumable/semen
/obj/structure/reagent_dispensers/keg/gargle
name = "keg of pan galactic gargleblaster"
desc = "A keg of... wow that's a long name."
icon_state = "bluekeg"
reagent_id = /datum/reagent/consumable/ethanol/gargle_blaster
/obj/structure/reagent_dispensers
name = "Dispenser"
desc = "..."
icon = 'icons/obj/objects.dmi'
icon_state = "water"
density = TRUE
anchored = FALSE
pressure_resistance = 2*ONE_ATMOSPHERE
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = /datum/reagent/water //The ID of the reagent that the dispenser uses
/obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(. && obj_integrity > 0)
if(tank_volume && (damage_flag == "bullet" || damage_flag == "laser"))
boom()
/obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params)
if(W.is_refillable())
return 0 //so we can refill them via their afterattack.
else
return ..()
/obj/structure/reagent_dispensers/Initialize()
create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE)
reagents.add_reagent(reagent_id, tank_volume)
. = ..()
/obj/structure/reagent_dispensers/proc/boom()
visible_message("<span class='danger'>\The [src] ruptures!</span>")
chem_splash(loc, 5, list(reagents))
qdel(src)
/obj/structure/reagent_dispensers/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(!disassembled)
boom()
else
qdel(src)
///////////////
//Water Tanks//
///////////////
/obj/structure/reagent_dispensers/watertank
name = "water tank"
desc = "A water tank."
icon_state = "water"
/obj/structure/reagent_dispensers/watertank/high
name = "high-capacity water tank"
desc = "A highly pressurized water tank made to hold gargantuan amounts of water."
icon_state = "water_high" //I was gonna clean my room...
tank_volume = 100000
/obj/structure/reagent_dispensers/foamtank
name = "firefighting foam tank"
desc = "A tank full of firefighting foam."
icon_state = "foam"
reagent_id = /datum/reagent/firefighting_foam
tank_volume = 500
/obj/structure/reagent_dispensers/water_cooler
name = "liquid cooler"
desc = "A machine that dispenses liquid to drink."
icon = 'icons/obj/vending.dmi'
icon_state = "water_cooler"
anchored = TRUE
tank_volume = 500
var/paper_cups = 25 //Paper cups left from the cooler
/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
. = ..()
if (paper_cups > 1)
. += "There are [paper_cups] paper cups left."
else if (paper_cups == 1)
. += "There is one paper cup left."
else
. += "There are no paper cups left."
/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!paper_cups)
to_chat(user, "<span class='warning'>There aren't any cups left!</span>")
return
user.visible_message("<span class='notice'>[user] takes a cup from [src].</span>", "<span class='notice'>You take a paper cup from [src].</span>")
var/obj/item/reagent_containers/food/drinks/sillycup/S = new(get_turf(src))
user.put_in_hands(S)
paper_cups--
//////////////
//Fuel Tanks//
//////////////
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank full of industrial welding fuel. Do not consume."
icon_state = "fuel"
reagent_id = /datum/reagent/fuel
/obj/structure/reagent_dispensers/fueltank/high //Unused - Good for ghost roles
name = "high-capacity fuel tank"
desc = "A now illegal tank, full of highly pressurized industrial welding fuel. Do not consume or have a open flame close to this tank."
icon_state = "fuel_high"
tank_volume = 3000
/obj/structure/reagent_dispensers/fueltank/boom()
explosion(get_turf(src), 0, 1, 5, flame_range = 5)
qdel(src)
/obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B)
boom()
/obj/structure/reagent_dispensers/fueltank/ex_act()
boom()
/obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume)
boom()
/obj/structure/reagent_dispensers/fueltank/tesla_act()
..() //extend the zap
boom()
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P)
..()
if(!QDELETED(src)) //wasn't deleted by the projectile's effects.
if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE)))
var/boom_message = "[ADMIN_LOOKUPFLW(P.firer)] triggered a fueltank explosion via projectile."
GLOB.bombers += boom_message
message_admins(boom_message)
P.firer.log_message("triggered a fueltank explosion via projectile.", LOG_ATTACK)
boom()
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/weldingtool))
if(!reagents.has_reagent(/datum/reagent/fuel))
to_chat(user, "<span class='warning'>[src] is out of fuel!</span>")
return
var/obj/item/weldingtool/W = I
if(!W.welding)
if(W.reagents.has_reagent(/datum/reagent/fuel, W.max_fuel))
to_chat(user, "<span class='warning'>Your [W.name] is already full!</span>")
return
reagents.trans_to(W, W.max_fuel)
user.visible_message("<span class='notice'>[user] refills [user.p_their()] [W.name].</span>", "<span class='notice'>You refill [W].</span>")
playsound(src, 'sound/effects/refill.ogg', 50, 1)
W.update_icon()
else
var/turf/T = get_turf(src)
user.visible_message("<span class='warning'>[user] catastrophically fails at refilling [user.p_their()] [W.name]!</span>", "<span class='userdanger'>That was stupid of you.</span>")
var/message_admins = "[ADMIN_LOOKUPFLW(user)] triggered a fueltank explosion via welding tool at [ADMIN_VERBOSEJMP(T)]."
GLOB.bombers += message_admins
message_admins(message_admins)
user.log_message("triggered a fueltank explosion via welding tool.", LOG_ATTACK)
boom()
return
return ..()
///////////////////
//Misc Dispenders//
///////////////////
/obj/structure/reagent_dispensers/peppertank
name = "pepper spray refiller"
desc = "Contains condensed capsaicin for use in law \"enforcement.\""
icon_state = "pepper"
anchored = TRUE
density = FALSE
reagent_id = /datum/reagent/consumable/condensedcapsaicin
/obj/structure/reagent_dispensers/peppertank/Initialize()
. = ..()
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
/obj/structure/reagent_dispensers/virusfood
name = "virus food dispenser"
desc = "A dispenser of low-potency virus mutagenic."
icon_state = "virus_food"
anchored = TRUE
density = FALSE
reagent_id = /datum/reagent/consumable/virus_food
/obj/structure/reagent_dispensers/cooking_oil
name = "vat of cooking oil"
desc = "A huge metal vat with a tap on the front. Filled with cooking oil for use in frying food."
icon_state = "vat"
anchored = TRUE
reagent_id = /datum/reagent/consumable/cooking_oil
////////
//Kegs//
////////
/obj/structure/reagent_dispensers/beerkeg
name = "beer keg"
desc = "Beer is liquid bread, it's good for you..."
icon_state = "beer"
reagent_id = /datum/reagent/consumable/ethanol/beer
/obj/structure/reagent_dispensers/beerkeg/blob_act(obj/structure/blob/B)
explosion(src.loc,0,3,5,7,10)
if(!QDELETED(src))
qdel(src)
/obj/structure/reagent_dispensers/keg
name = "keg"
desc = "A keg."
icon = 'modular_citadel/icons/obj/objects.dmi'
icon_state = "keg"
/obj/structure/reagent_dispensers/keg/mead
name = "keg of mead"
desc = "A keg of mead."
icon_state = "orangekeg"
reagent_id = /datum/reagent/consumable/ethanol/mead
/obj/structure/reagent_dispensers/keg/aphro
name = "keg of aphrodisiac"
desc = "A keg of aphrodisiac."
icon_state = "pinkkeg"
reagent_id = /datum/reagent/drug/aphrodisiac
tank_volume = 150
/obj/structure/reagent_dispensers/keg/aphro/strong
name = "keg of strong aphrodisiac"
desc = "A keg of strong and addictive aphrodisiac."
reagent_id = /datum/reagent/drug/aphrodisiacplus
tank_volume = 120
/obj/structure/reagent_dispensers/keg/milk
name = "keg of milk"
desc = "It's not quite what you were hoping for."
icon_state = "whitekeg"
reagent_id = /datum/reagent/consumable/milk
/obj/structure/reagent_dispensers/keg/semen
name = "keg of semen"
desc = "Dear lord, where did this even come from?"
icon_state = "whitekeg"
reagent_id = /datum/reagent/consumable/semen
/obj/structure/reagent_dispensers/keg/gargle
name = "keg of pan galactic gargleblaster"
desc = "A keg of... wow that's a long name."
icon_state = "bluekeg"
reagent_id = /datum/reagent/consumable/ethanol/gargle_blaster
tank_volume = 100