mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
774 lines
29 KiB
Plaintext
774 lines
29 KiB
Plaintext
/obj/item/reagent_containers/cup
|
|
name = "open container"
|
|
abstract_type = /obj/item/reagent_containers/cup
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
|
|
volume = 50
|
|
initial_reagent_flags = OPENCONTAINER | DUNKABLE
|
|
resistance_flags = ACID_PROOF
|
|
icon_state = "bottle"
|
|
lefthand_file = 'icons/mob/inhands/items/drinks_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/items/drinks_righthand.dmi'
|
|
reagent_container_liquid_sound = SFX_DEFAULT_LIQUID_SLOSH
|
|
|
|
/// Like Edible's food type, what kind of drink is this?
|
|
var/drink_type = NONE
|
|
/// The last time we have checked for taste.
|
|
var/last_check_time
|
|
/// How much we drink at once, shot glasses drink more.
|
|
var/gulp_size = 5
|
|
/// Whether the 'bottle' is made of glass or not so that milk cartons dont shatter when someone gets hit by it.
|
|
var/isGlass = FALSE
|
|
/// What kind of chem transfer method does this cup use. Defaults to INGEST
|
|
var/reagent_consumption_method = INGEST
|
|
/// What sound does our consumption play on consuming from the container?
|
|
var/consumption_sound = 'sound/items/drink.ogg'
|
|
/// Whether to allow heating up the contents with a source of flame.
|
|
var/heatable = TRUE
|
|
/// Can we put a lid on this container?
|
|
var/can_lid = FALSE
|
|
/// Does this container have a lid on right now?
|
|
var/has_lid = FALSE
|
|
/// Assembly attached to our lid
|
|
var/obj/item/assembly_holder/lid_assembly = null
|
|
/// Power cell duct-taped to the side of the beaker
|
|
var/obj/item/stock_parts/power_store/cell/attached_cell = null
|
|
/// Have we added wiring to the cell?
|
|
var/cell_wired = FALSE
|
|
/// Visual y-offset for the assembly on our lid
|
|
var/assembly_pixel_y = 0
|
|
/// If TRUE, after we finish drinking, we try to drink again after do_after
|
|
var/loop_drink = FALSE
|
|
|
|
/obj/item/reagent_containers/cup/Initialize(mapload, vol)
|
|
. = ..()
|
|
if(heatable)
|
|
AddElement(/datum/element/reagents_item_heatable)
|
|
|
|
/obj/item/reagent_containers/cup/Destroy(force)
|
|
QDEL_NULL(lid_assembly)
|
|
QDEL_NULL(attached_cell)
|
|
return ..()
|
|
|
|
/obj/item/reagent_containers/cup/examine(mob/user)
|
|
. = ..()
|
|
if(drink_type)
|
|
var/list/types = bitfield_to_list(drink_type, FOOD_FLAGS)
|
|
. += span_notice("The label says it contains [LOWER_TEXT(english_list(types))] ingredients.")
|
|
if(can_lid)
|
|
if(has_lid)
|
|
. += span_notice("Its sealed with a bright orange rubber lid[!isnull(lid_assembly) ? "with an assembly attached ontop of it" : ""].")
|
|
else
|
|
. += span_notice("It can be sealed with a lid using [EXAMINE_HINT("Alt-Click")].")
|
|
|
|
/**
|
|
* Checks if the mob actually liked drinking this cup.
|
|
*
|
|
* This is a bunch of copypaste from the edible component, consider reworking this to use it!
|
|
*/
|
|
/obj/item/reagent_containers/cup/proc/checkLiked(fraction, mob/eater)
|
|
if(last_check_time + 5 SECONDS > world.time)
|
|
return FALSE
|
|
if(!ishuman(eater))
|
|
return FALSE
|
|
var/mob/living/carbon/human/gourmand = eater
|
|
//Bruh this breakfast thing is cringe and shouldve been handled separately from food-types, remove this in the future (Actually, just kill foodtypes in general)
|
|
if((drink_type & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST)
|
|
gourmand.add_mood_event("breakfast", /datum/mood_event/breakfast)
|
|
last_check_time = world.time
|
|
|
|
var/food_taste_reaction = gourmand.get_food_taste_reaction(src, drink_type)
|
|
switch(food_taste_reaction)
|
|
if(FOOD_TOXIC)
|
|
to_chat(gourmand,span_warning("What the hell was that thing?!"))
|
|
gourmand.adjust_disgust(25 + 30 * fraction)
|
|
gourmand.add_mood_event("toxic_food", /datum/mood_event/disgusting_food)
|
|
if(FOOD_DISLIKED)
|
|
to_chat(gourmand,span_notice("That didn't taste very good..."))
|
|
gourmand.adjust_disgust(11 + 15 * fraction)
|
|
gourmand.add_mood_event("gross_food", /datum/mood_event/gross_food)
|
|
if(FOOD_LIKED)
|
|
to_chat(gourmand,span_notice("I love this taste!"))
|
|
gourmand.adjust_disgust(-5 + -2.5 * fraction)
|
|
gourmand.add_mood_event("fav_food", /datum/mood_event/favorite_food)
|
|
|
|
/obj/item/reagent_containers/cup/proc/try_drink(mob/living/target_mob, mob/living/user)
|
|
if(!canconsume(target_mob, user))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
if(target_mob != user)
|
|
if(DOING_INTERACTION_WITH_TARGET(user, target_mob))
|
|
return ITEM_INTERACT_BLOCKING
|
|
target_mob.visible_message(
|
|
span_danger("[user] attempts to feed [target_mob] something from [src]."),
|
|
span_userdanger("[user] attempts to feed you something from [src]."),
|
|
)
|
|
if(!do_after(user, 3 SECONDS, target_mob))
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(!reagents || !reagents.total_volume)
|
|
return ITEM_INTERACT_BLOCKING // The drink might be empty after the delay, such as by spam-feeding
|
|
target_mob.visible_message(
|
|
span_danger("[user] feeds [target_mob] something from [src]."),
|
|
span_userdanger("[user] feeds you something from [src]."),
|
|
)
|
|
if(target_mob.is_blind())
|
|
to_chat(target_mob, span_notice("You feel someone feed you something."))
|
|
log_combat(user, target_mob, "fed", reagents.get_reagent_log_string())
|
|
|
|
else
|
|
if(loop_drink)
|
|
if(DOING_INTERACTION_WITH_TARGET(user, user))
|
|
return ITEM_INTERACT_BLOCKING
|
|
user.visible_message(
|
|
span_notice("[user] attempts to drink from [src]."),
|
|
ignored_mobs = list(user),
|
|
)
|
|
to_chat(user, span_notice("You attempt to drink from [src]."))
|
|
if(!do_after(user, 1.25 SECONDS, user))
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(!reagents || !reagents.total_volume)
|
|
return ITEM_INTERACT_BLOCKING
|
|
user.visible_message(
|
|
span_notice("[user] drinks from [src]."),
|
|
ignored_mobs = list(user),
|
|
)
|
|
to_chat(user, span_notice("You swallow a gulp of [src]."))
|
|
|
|
SEND_SIGNAL(src, COMSIG_GLASS_DRANK, target_mob, user)
|
|
SEND_SIGNAL(target_mob, COMSIG_GLASS_DRANK, src, user) // SKYRAT EDIT ADDITION - Hemophages can't casually drink what's not going to regenerate their blood
|
|
var/fraction = min(gulp_size / reagents.total_volume, 1)
|
|
reagents.trans_to(target_mob, gulp_size, transferred_by = user, methods = reagent_consumption_method)
|
|
var/atom/movable/screen/hunger/hunger_bar = user.hud_used?.screen_objects[HUD_MOB_HUNGER]
|
|
if (istype(hunger_bar))
|
|
hunger_bar.update_hunger_bar()
|
|
checkLiked(fraction, target_mob)
|
|
playsound(target_mob, consumption_sound, rand(10, 50), TRUE)
|
|
var/list/datum/disease/diseases_to_add
|
|
for(var/datum/disease/malady as anything in target_mob.get_static_viruses())
|
|
if(malady.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS)
|
|
LAZYADD(diseases_to_add, malady)
|
|
if(LAZYLEN(diseases_to_add))
|
|
AddComponent(/datum/component/infective, diseases_to_add)
|
|
if(loop_drink)
|
|
return try_drink(target_mob, user) | ITEM_INTERACT_SUCCESS
|
|
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/reagent_containers/cup/interact_with_atom(atom/target, mob/living/user, list/modifiers)
|
|
. = ..()
|
|
if(. & ITEM_INTERACT_ANY_BLOCKER)
|
|
return .
|
|
if(!is_open_container())
|
|
return NONE
|
|
|
|
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
|
|
return try_refill(target, user)
|
|
|
|
if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
|
|
return try_drain(target, user)
|
|
|
|
if(isliving(target))
|
|
return try_drink(target, user)
|
|
|
|
return NONE
|
|
|
|
/obj/item/reagent_containers/cup/interact_with_atom_secondary(atom/target, mob/living/user, list/modifiers)
|
|
. = ..()
|
|
if(. & ITEM_INTERACT_ANY_BLOCKER)
|
|
return .
|
|
if(!is_open_container())
|
|
return NONE
|
|
|
|
if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
|
|
return try_drain(target, user)
|
|
|
|
return NONE
|
|
|
|
/obj/item/reagent_containers/cup/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
|
if(has_lid && istype(tool, /obj/item/assembly_holder))
|
|
if (lid_assembly)
|
|
to_chat(user, span_warning("[src]'s lid already has an assembly attached to it!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
if (attach_assembly(tool, user))
|
|
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
if (lid_assembly && istype(tool, /obj/item/stock_parts/power_store/cell))
|
|
if (attached_cell)
|
|
to_chat(user, span_warning("[src] already has \a [attached_cell] attached to it!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
if (isnull(locate(/obj/item/assembly/igniter) in lid_assembly))
|
|
to_chat(user, span_warning("[lid_assembly] doesn't have an igniter to connect [src] to!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
if (!user.transferItemToLoc(tool, src))
|
|
to_chat(user, span_warning("[tool] is stuck to your hand!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
to_chat(user, span_notice("You attach [tool] underneath [src]'s lid."))
|
|
add_fingerprint(user)
|
|
log_bomber(user, "attached [tool.name] to", src)
|
|
attached_cell = tool
|
|
attached_cell.pixel_y = 0
|
|
attached_cell.pixel_z = -4
|
|
update_appearance()
|
|
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
if (attached_cell && istype(tool, /obj/item/stack/cable_coil))
|
|
if (cell_wired)
|
|
to_chat(user, span_warning("[attached_cell] is already wired to [lid_assembly]!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
var/obj/item/stack/cable_coil/cable = tool
|
|
if (!cable.use(5))
|
|
to_chat(user, span_warning("You need at least 5 cable pieces to wire [attached_cell]!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
to_chat(user, span_notice("You wire [attached_cell] to [lid_assembly]."))
|
|
add_fingerprint(user)
|
|
cell_wired = TRUE
|
|
update_appearance()
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
if(!is_open_container())
|
|
return NONE
|
|
|
|
if(istype(tool, /obj/item/food/egg)) //breaking eggs
|
|
if(reagents.holder_full())
|
|
to_chat(user, span_notice("[src] is full."))
|
|
return ITEM_INTERACT_BLOCKING
|
|
to_chat(user, span_notice("You break [tool] in [src]."))
|
|
tool.reagents.trans_to(src, tool.reagents.total_volume, transferred_by = user)
|
|
qdel(tool)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
return NONE
|
|
|
|
/*
|
|
* On accidental consumption, make sure the container is partially glass, and continue to the reagent_container proc
|
|
*/
|
|
/obj/item/reagent_containers/cup/on_accidental_consumption(mob/living/carbon/M, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE)
|
|
if(isGlass && !custom_materials)
|
|
set_custom_materials(list(SSmaterials.get_material(/datum/material/glass) = 5))//sets it to glass so, later on, it gets picked up by the glass catch (hope it doesn't 'break' things lol)
|
|
return ..()
|
|
|
|
/// Callback for [datum/component/takes_reagent_appearance] to inherent style footypes
|
|
/obj/item/reagent_containers/cup/proc/on_cup_change(datum/glass_style/has_foodtype/style)
|
|
if(!istype(style))
|
|
return
|
|
drink_type = style.drink_type
|
|
|
|
/// Callback for [datum/component/takes_reagent_appearance] to reset to no foodtypes
|
|
/obj/item/reagent_containers/cup/proc/on_cup_reset()
|
|
drink_type = NONE
|
|
|
|
/obj/item/reagent_containers/cup/update_overlays()
|
|
. = ..()
|
|
if (has_lid)
|
|
. += mutable_appearance(icon, "[icon_state]_lid")
|
|
if (lid_assembly)
|
|
. += lid_assembly
|
|
if (attached_cell)
|
|
. += attached_cell
|
|
if (cell_wired)
|
|
. += mutable_appearance('icons/obj/machines/cell_charger.dmi', "ccharger-[attached_cell.connector_type]-on")
|
|
|
|
// For player convinience, assume that the lids are rubber and can be pierced with a syringe
|
|
/obj/item/reagent_containers/cup/is_refillable()
|
|
return ..() && !has_lid
|
|
|
|
/obj/item/reagent_containers/cup/is_drainable()
|
|
return ..() && !has_lid
|
|
|
|
/obj/item/reagent_containers/cup/is_dunkable()
|
|
return ..() && !has_lid
|
|
|
|
/obj/item/reagent_containers/cup/attack_self(mob/user)
|
|
if (!lid_assembly)
|
|
return ..()
|
|
lid_assembly.attack_self(user)
|
|
return TRUE
|
|
|
|
/obj/item/reagent_containers/cup/click_alt(mob/user)
|
|
if (!can_lid)
|
|
return NONE
|
|
|
|
if (cell_wired)
|
|
balloon_alert(user, "cut the wiring first!")
|
|
return CLICK_ACTION_BLOCKING
|
|
|
|
if (attached_cell)
|
|
var/obj/item/our_cell = attached_cell
|
|
// Exited() automatically clears it
|
|
our_cell.forceMove(drop_location())
|
|
user.put_in_hands(our_cell)
|
|
balloon_alert(user, "cell detached")
|
|
update_appearance()
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
if (lid_assembly)
|
|
var/obj/item/our_assembly = lid_assembly
|
|
our_assembly.forceMove(drop_location())
|
|
user.put_in_hands(our_assembly)
|
|
balloon_alert(user, "assembly detached")
|
|
update_appearance()
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
has_lid = !has_lid
|
|
update_appearance()
|
|
balloon_alert(user, "lid [has_lid ? "sealed" : "unsealed"]")
|
|
if (has_lid)
|
|
add_container_flags(SEALED_CONTAINER)
|
|
else
|
|
reset_container_flags()
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
/obj/item/reagent_containers/cup/wirecutter_act(mob/living/user, obj/item/tool)
|
|
if (user.combat_mode || !cell_wired)
|
|
return NONE
|
|
|
|
new /obj/item/stack/cable_coil(drop_location(), 5)
|
|
cell_wired = FALSE
|
|
update_appearance()
|
|
balloon_alert(user, "wiring cut")
|
|
tool.play_tool_sound(src, 50)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/reagent_containers/cup/proc/attach_assembly(obj/item/assembly_holder/assembly, mob/living/user)
|
|
if (!user.transferItemToLoc(assembly, src))
|
|
to_chat(user, span_warning("[assembly] is stuck to your hand!"))
|
|
return FALSE
|
|
|
|
to_chat(user, span_notice("You attach [assembly] to [src]'s lid."))
|
|
add_fingerprint(user)
|
|
lid_assembly = assembly
|
|
lid_assembly.master = src
|
|
lid_assembly.pixel_y = 0
|
|
lid_assembly.pixel_z = assembly_pixel_y
|
|
lid_assembly.on_attach()
|
|
RegisterSignal(src, COMSIG_IGNITER_ACTIVATE, PROC_REF(on_igniter_activate))
|
|
log_bomber(user, "attached [lid_assembly.name] to", src)
|
|
update_appearance()
|
|
return TRUE
|
|
|
|
/obj/item/reagent_containers/cup/Exited(atom/movable/gone, direction)
|
|
. = ..()
|
|
if (gone == lid_assembly)
|
|
lid_assembly = null
|
|
UnregisterSignal(src, COMSIG_IGNITER_ACTIVATE)
|
|
update_appearance()
|
|
else if (gone == attached_cell)
|
|
attached_cell = null
|
|
cell_wired = FALSE
|
|
update_appearance()
|
|
|
|
/obj/item/reagent_containers/cup/proc/on_igniter_activate(datum/source, obj/item/assembly/igniter/igniter)
|
|
SIGNAL_HANDLER
|
|
// We've got an attached cell wired up, so we'll try to spend all of its current first
|
|
if (attached_cell && cell_wired)
|
|
var/power_spent = attached_cell.use(attached_cell.charge())
|
|
// Power cell was rigged
|
|
if (QDELETED(src))
|
|
return
|
|
|
|
// We'll be nerfing plasma and welding fuel as they're very easy to get and make for boring bombs
|
|
if (power_spent > 0 && (reagents.spark_act(power_spent, SPARK_ACT_ENCLOSED | SPARK_ACT_WEAKEN_COMMON) & SPARK_ACT_DESTRUCTIVE))
|
|
qdel(src)
|
|
return
|
|
|
|
// Igniters heat, condensers chill
|
|
var/igniter_temp = igniter.get_temperature()
|
|
if (igniter_temp > 0)
|
|
reagents.expose_temperature(igniter_temp)
|
|
|
|
/obj/item/reagent_containers/cup/beaker
|
|
name = "beaker"
|
|
desc = "A beaker. It can hold up to 50 units."
|
|
icon = 'icons/obj/medical/chemical.dmi'
|
|
icon_state = "beaker"
|
|
inhand_icon_state = "beaker"
|
|
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
|
worn_icon_state = "beaker"
|
|
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*5)
|
|
fill_icon_thresholds = list(0, 1, 20, 40, 60, 80, 100)
|
|
pickup_sound = 'sound/items/handling/beaker_pickup.ogg'
|
|
drop_sound = 'sound/items/handling/beaker_place.ogg'
|
|
sound_vary = TRUE
|
|
can_lid = TRUE
|
|
assembly_pixel_y = 4
|
|
|
|
/obj/item/reagent_containers/cup/beaker/Initialize(mapload)
|
|
. = ..()
|
|
update_appearance()
|
|
|
|
/obj/item/reagent_containers/cup/beaker/get_part_rating()
|
|
return reagents.maximum_volume
|
|
|
|
/obj/item/reagent_containers/cup/beaker/jar
|
|
name = "honey jar"
|
|
desc = "A jar for honey. It can hold up to 50 units of sweet delight."
|
|
icon = 'icons/obj/medical/chemical.dmi'
|
|
icon_state = "vapour"
|
|
can_lid = FALSE
|
|
|
|
/obj/item/reagent_containers/cup/beaker/large
|
|
name = "large beaker"
|
|
desc = "A large beaker. Can hold up to 100 units."
|
|
icon_state = "beakerlarge"
|
|
custom_materials = list(/datum/material/glass= SHEET_MATERIAL_AMOUNT*1.25)
|
|
volume = 100
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
|
|
fill_icon_thresholds = list(0, 1, 20, 40, 60, 80, 100)
|
|
assembly_pixel_y = 8
|
|
|
|
/obj/item/reagent_containers/cup/beaker/plastic
|
|
name = "x-large beaker"
|
|
desc = "An extra-large beaker. Can hold up to 120 units."
|
|
icon_state = "beakerwhite"
|
|
inhand_icon_state = "beaker_white"
|
|
custom_materials = list(/datum/material/glass=SHEET_MATERIAL_AMOUNT*1.25, /datum/material/plastic=SHEET_MATERIAL_AMOUNT * 1.5)
|
|
volume = 120
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5,10,15,20,25,30,60,120)
|
|
fill_icon_thresholds = list(0, 1, 10, 20, 40, 60, 80, 100)
|
|
assembly_pixel_y = 8
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta
|
|
name = "metamaterial beaker"
|
|
desc = "A large beaker. Can hold up to 180 units."
|
|
icon_state = "beakergold"
|
|
inhand_icon_state = "beaker_gold"
|
|
custom_materials = list(/datum/material/glass=SHEET_MATERIAL_AMOUNT*1.25, /datum/material/plastic=SHEET_MATERIAL_AMOUNT * 1.5, /datum/material/gold=HALF_SHEET_MATERIAL_AMOUNT, /datum/material/titanium=HALF_SHEET_MATERIAL_AMOUNT)
|
|
volume = 180
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5,10,15,20,25,30,60,120,180)
|
|
fill_icon_thresholds = list(0, 1, 10, 25, 35, 50, 60, 80, 100)
|
|
assembly_pixel_y = 10
|
|
|
|
/obj/item/reagent_containers/cup/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"
|
|
inhand_icon_state = "beaker_cryo"
|
|
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 1.5)
|
|
initial_reagent_flags = OPENCONTAINER | NO_REACT
|
|
volume = 50
|
|
amount_per_transfer_from_this = 10
|
|
can_lid = FALSE
|
|
|
|
/obj/item/reagent_containers/cup/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."
|
|
icon_state = "beakerbluespace"
|
|
inhand_icon_state = "beaker_bluespace"
|
|
custom_materials = list(/datum/material/glass =SHEET_MATERIAL_AMOUNT * 2.5, /datum/material/plasma =SHEET_MATERIAL_AMOUNT * 1.5, /datum/material/diamond =HALF_SHEET_MATERIAL_AMOUNT, /datum/material/bluespace =HALF_SHEET_MATERIAL_AMOUNT)
|
|
volume = 300
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
|
|
can_lid = FALSE
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/omnizine
|
|
list_reagents = list(/datum/reagent/medicine/omnizine = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/sal_acid
|
|
list_reagents = list(/datum/reagent/medicine/sal_acid = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/oxandrolone
|
|
list_reagents = list(/datum/reagent/medicine/oxandrolone = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/pen_acid
|
|
list_reagents = list(/datum/reagent/medicine/pen_acid = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/atropine
|
|
list_reagents = list(/datum/reagent/medicine/atropine = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/salbutamol
|
|
list_reagents = list(/datum/reagent/medicine/salbutamol = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/meta/rezadone
|
|
list_reagents = list(/datum/reagent/medicine/rezadone = 180)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/cryoxadone
|
|
list_reagents = list(/datum/reagent/medicine/cryoxadone = 30)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/sulfuric
|
|
list_reagents = list(/datum/reagent/toxin/acid = 50)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/slime
|
|
list_reagents = list(/datum/reagent/toxin/slimejelly = 50)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/large/libital
|
|
name = "libital reserve tank (diluted)"
|
|
list_reagents = list(/datum/reagent/medicine/c2/libital = 10,/datum/reagent/medicine/granibitaluri = 40)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/large/aiuri
|
|
name = "aiuri reserve tank (diluted)"
|
|
list_reagents = list(/datum/reagent/medicine/c2/aiuri = 10, /datum/reagent/medicine/granibitaluri = 40)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/large/multiver
|
|
name = "multiver reserve tank (diluted)"
|
|
list_reagents = list(/datum/reagent/medicine/c2/multiver = 10, /datum/reagent/medicine/granibitaluri = 40)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/large/epinephrine
|
|
name = "epinephrine reserve tank (diluted)"
|
|
list_reagents = list(/datum/reagent/medicine/epinephrine = 50)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/synthflesh
|
|
list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 50)
|
|
|
|
/obj/item/reagent_containers/cup/beaker/synthflesh/named
|
|
name = "synthflesh beaker"
|
|
|
|
/obj/item/reagent_containers/cup/bucket
|
|
name = "bucket"
|
|
desc = "It's a bucket. You can squeeze a mop's contents into it by using right-click." //SKYRAT EDIT CHANGE - ORIGINAL: desc = "It's a bucket."
|
|
icon = 'icons/obj/service/janitor.dmi'
|
|
worn_icon = 'icons/mob/clothing/head/utility.dmi'
|
|
icon_state = "bucket"
|
|
inhand_icon_state = "bucket"
|
|
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
|
|
fill_icon_state = "bucket"
|
|
fill_icon_thresholds = list(50, 90)
|
|
custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 2)
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
amount_per_transfer_from_this = 20
|
|
possible_transfer_amounts = list(5,10,15,20,25,30,50,100) //SKYRAT EDIT CHANGE
|
|
volume = 100 //SKYRAT EDIT CHANGE
|
|
flags_inv = HIDEHAIR
|
|
slot_flags = ITEM_SLOT_HEAD
|
|
resistance_flags = NONE
|
|
armor_type = /datum/armor/cup_bucket
|
|
slot_equipment_priority = list( \
|
|
ITEM_SLOT_BACK, ITEM_SLOT_ID,\
|
|
ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING,\
|
|
ITEM_SLOT_MASK, ITEM_SLOT_HEAD, ITEM_SLOT_NECK,\
|
|
ITEM_SLOT_FEET, ITEM_SLOT_GLOVES,\
|
|
ITEM_SLOT_EARS, ITEM_SLOT_EYES,\
|
|
ITEM_SLOT_BELT, ITEM_SLOT_SUITSTORE,\
|
|
ITEM_SLOT_LPOCKET, ITEM_SLOT_RPOCKET,\
|
|
ITEM_SLOT_DEX_STORAGE
|
|
)
|
|
|
|
/obj/item/reagent_containers/cup/bucket/Initialize(mapload)
|
|
. = ..()
|
|
AddElement(/datum/element/cuffable_item)
|
|
|
|
/datum/armor/cup_bucket
|
|
melee = 10
|
|
fire = 75
|
|
acid = 50
|
|
|
|
/obj/item/reagent_containers/cup/bucket/wooden
|
|
name = "wooden bucket"
|
|
icon_state = "woodbucket"
|
|
inhand_icon_state = "woodbucket"
|
|
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 3)
|
|
resistance_flags = FLAMMABLE
|
|
armor_type = /datum/armor/bucket_wooden
|
|
|
|
/datum/armor/bucket_wooden
|
|
melee = 10
|
|
acid = 50
|
|
|
|
/obj/item/reagent_containers/cup/bucket/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
|
if(istype(tool, /obj/item/mop))
|
|
if(reagents.total_volume < 1)
|
|
user.balloon_alert(user, "empty!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
reagents.trans_to(tool, 5, transferred_by = user)
|
|
user.balloon_alert(user, "doused [tool]")
|
|
playsound(src, 'sound/effects/slosh.ogg', 25, TRUE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
if(isprox(tool)) //This works with wooden buckets for now. Somewhat unintended, but maybe someone will add sprites for it soon(TM)
|
|
to_chat(user, span_notice("You add [tool] to [src]."))
|
|
qdel(tool)
|
|
var/obj/item/bot_assembly/cleanbot/new_cleanbot_ass = new(null, src)
|
|
user.put_in_hands(new_cleanbot_ass)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
return ..()
|
|
|
|
// BUBBER EDIT ADDITION BEGIN - LIQUIDS
|
|
/obj/item/reagent_containers/cup/bucket/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers)
|
|
if(istype(tool, /obj/item/mop))
|
|
if(tool.reagents.total_volume == 0)
|
|
user.balloon_alert(user, "mop is dry!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(reagents.total_volume == reagents.maximum_volume)
|
|
user.balloon_alert(user, "container is full!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
tool.reagents.remove_all(tool.reagents.total_volume * SQUEEZING_DISPERSAL_RATIO)
|
|
tool.reagents.trans_to(src, tool.reagents.total_volume, transferred_by = user)
|
|
user.balloon_alert(user, "mop squeezed")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
. = ..()
|
|
// BUBBER EDIT ADDITION END - LIQUIDS
|
|
|
|
/obj/item/reagent_containers/cup/bucket/equipped(mob/user, slot)
|
|
. = ..()
|
|
if (slot & ITEM_SLOT_HEAD)
|
|
if(reagents.total_volume)
|
|
to_chat(user, span_userdanger("[src]'s contents spill all over you!"))
|
|
reagents.expose(user, TOUCH)
|
|
reagents.clear_reagents()
|
|
update_container_flags(NONE)
|
|
|
|
/obj/item/reagent_containers/cup/bucket/dropped(mob/user)
|
|
. = ..()
|
|
reset_container_flags()
|
|
|
|
/obj/item/reagent_containers/cup/bucket/equip_to_best_slot(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(ITEM_SLOT_HEAD)
|
|
slot_equipment_priority.Remove(ITEM_SLOT_HEAD)
|
|
. = ..()
|
|
slot_equipment_priority.Insert(index, ITEM_SLOT_HEAD)
|
|
return
|
|
return ..()
|
|
|
|
/obj/item/pestle
|
|
name = "pestle"
|
|
desc = "An ancient, simple tool used in conjunction with a mortar to grind or juice items."
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
icon = 'icons/obj/medical/chemical.dmi'
|
|
icon_state = "pestle"
|
|
force = 7
|
|
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT)
|
|
|
|
/obj/item/reagent_containers/cup/mortar
|
|
name = "mortar"
|
|
desc = "A specially formed bowl of ancient design. It is possible to crush or juice items placed in it using a pestle; however the process, unlike modern methods, is slow and physically exhausting."
|
|
desc_controls = "Alt click to eject the item."
|
|
icon_state = "mortar"
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50, 100)
|
|
volume = 100
|
|
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 3)
|
|
resistance_flags = FLAMMABLE
|
|
initial_reagent_flags = OPENCONTAINER
|
|
var/obj/item/grinded
|
|
|
|
/obj/item/reagent_containers/cup/mortar/click_alt(mob/user)
|
|
if(!grinded)
|
|
return CLICK_ACTION_BLOCKING
|
|
grinded.forceMove(drop_location())
|
|
grinded = null
|
|
balloon_alert(user, "ejected")
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
/obj/item/reagent_containers/cup/mortar/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
|
. = ..()
|
|
if(. & ITEM_INTERACT_ANY_BLOCKER)
|
|
return .
|
|
if(istype(tool, /obj/item/pestle))
|
|
if(!grinded)
|
|
to_chat(user, span_warning("There is nothing to grind!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(user.get_stamina_loss() > 50)
|
|
to_chat(user, span_warning("You are too tired to work!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
var/list/choose_options = list(
|
|
"Grind" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_grind"),
|
|
"Juice" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_juice")
|
|
)
|
|
var/picked_option = show_radial_menu(user, src, choose_options, radius = 38, require_near = TRUE)
|
|
if(!grinded || !in_range(src, user) || !user.is_holding(tool) || !picked_option)
|
|
return ITEM_INTERACT_BLOCKING
|
|
to_chat(user, span_notice("You start grinding..."))
|
|
if(!do_after(user, 2.5 SECONDS, target = src))
|
|
return ITEM_INTERACT_BLOCKING
|
|
user.adjust_stamina_loss(40)
|
|
switch(picked_option)
|
|
if("Juice")
|
|
return juice_item(grinded, user) ? ITEM_INTERACT_BLOCKING : ITEM_INTERACT_SUCCESS
|
|
if("Grind")
|
|
return grind_item(grinded, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING
|
|
to_chat(user, span_notice("You try to grind the mortar itself instead of [grinded]. You failed."))
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(grinded)
|
|
to_chat(user, span_warning("There is something inside already!"))
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(!tool.blend_requirements(src, user))
|
|
return ITEM_INTERACT_BLOCKING
|
|
if((length(tool.grind_results()) || tool.reagents?.total_volume) && user.transferItemToLoc(tool, src))
|
|
grinded = tool
|
|
return ITEM_INTERACT_SUCCESS
|
|
return NONE
|
|
|
|
/obj/item/reagent_containers/cup/mortar/blended(obj/item/blended_item, grinded)
|
|
src.grinded = null
|
|
|
|
return ..()
|
|
|
|
/obj/item/reagent_containers/cup/mortar/proc/grind_item(obj/item/item, mob/living/carbon/human/user)
|
|
if(item.flags_1 & HOLOGRAM_1)
|
|
to_chat(user, span_notice("You try to grind [item], but it fades away!"))
|
|
qdel(item)
|
|
return
|
|
|
|
if(!item.grind(reagents, user))
|
|
if(isstack(item))
|
|
to_chat(user, span_notice("[src] attempts to grind as many pieces of [item] as possible."))
|
|
else
|
|
to_chat(user, span_danger("You fail to grind [item]."))
|
|
return
|
|
|
|
to_chat(user, span_notice("You grind [item] into a nice powder."))
|
|
|
|
/obj/item/reagent_containers/cup/mortar/proc/juice_item(obj/item/item, mob/living/carbon/human/user)
|
|
if(item.flags_1 & HOLOGRAM_1)
|
|
to_chat(user, span_notice("You try to juice [item], but it fades away!"))
|
|
qdel(item)
|
|
return
|
|
|
|
if(!item.juice(reagents, user))
|
|
to_chat(user, span_notice("You fail to juice [item]."))
|
|
return
|
|
|
|
to_chat(user, span_notice("You juice [item] into a fine liquid."))
|
|
|
|
//Coffeepots: for reference, a standard cup is 30u, to allow 20u for sugar/sweetener/milk/creamer
|
|
/obj/item/reagent_containers/cup/coffeepot
|
|
name = "coffeepot"
|
|
desc = "A large pot for dispensing that ambrosia of corporate life known to mortals only as coffee. Contains 4 standard cups."
|
|
volume = 120
|
|
icon_state = "coffeepot"
|
|
fill_icon_state = "coffeepot"
|
|
fill_icon_thresholds = list(0, 1, 30, 60, 100)
|
|
|
|
/obj/item/reagent_containers/cup/coffeepot/bluespace
|
|
name = "bluespace coffeepot"
|
|
desc = "The most advanced coffeepot the eggheads could cook up: sleek design; graduated lines; connection to a pocket dimension for coffee containment; yep, it's got it all. Contains 8 standard cups."
|
|
volume = 240
|
|
icon_state = "coffeepot_bluespace"
|
|
fill_icon_thresholds = null
|
|
|
|
///Test tubes created by chem master and pandemic and placed in racks
|
|
/obj/item/reagent_containers/cup/tube
|
|
name = "tube"
|
|
desc = "A small test tube."
|
|
icon_state = "test_tube"
|
|
fill_icon_state = "tube"
|
|
inhand_icon_state = "atoxinbottle"
|
|
worn_icon_state = "beaker"
|
|
possible_transfer_amounts = list(5, 10, 15, 30)
|
|
volume = 30
|
|
fill_icon_thresholds = list(0, 1, 20, 40, 60, 80, 100)
|
|
can_lid = TRUE
|
|
|
|
/obj/item/reagent_containers/cup/tube/attach_assembly(obj/item/assembly_holder/assembly, mob/living/user)
|
|
to_chat(user, span_warning("[src]'s lid is too small to fit [assembly]!"))
|
|
return FALSE
|