diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
index 00db42bad50..3795d43bb76 100644
--- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
@@ -551,7 +551,7 @@
/obj/item/circuitboard/machine/smartfridge/apply_default_parts(obj/machinery/smartfridge/smartfridge)
build_path = smartfridge.base_build_path
- if(!fridges_name_paths.Find(build_path, fridges_name_paths))
+ if(!fridges_name_paths.Find(build_path))
name = "[initial(smartfridge.name)]" //if it's a unique type, give it a unique name.
is_special_type = TRUE
return ..()
diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm
index dfe3987dfe2..3976908a5cd 100644
--- a/code/modules/food_and_drinks/machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/machinery/smartfridge.dm
@@ -17,8 +17,8 @@
var/base_build_path = /obj/machinery/smartfridge
/// Maximum number of items that can be loaded into the machine
var/max_n_of_items = 1500
- /// If the AI is allowed to retrieve items within the machine
- var/allow_ai_retrieve = FALSE
+ /// The overlay for this fridge when it is filled with stuff
+ var/contents_icon_state = "plant"
/// List of items that the machine starts with upon spawn
var/list/initial_contents
/// If the machine shows an approximate number of its contents on its sprite
@@ -33,7 +33,7 @@
create_reagents(100, NO_REACT)
air_update_turf(TRUE, TRUE)
register_context()
- if(mapload && !istype(src, /obj/machinery/smartfridge/drying_rack))
+ if(mapload)
welded_down = TRUE
if(islist(initial_contents))
@@ -49,83 +49,115 @@
. = ..()
move_update_air(old_loc)
-/obj/machinery/smartfridge/can_be_unfasten_wrench(mob/user, silent)
- if(welded_down)
- to_chat(user, span_warning("[src] is welded to the floor!"))
- return FAILED_UNFASTEN
- return ..()
-
-/obj/machinery/smartfridge/set_anchored(anchorvalue)
- . = ..()
- if(!anchored && welded_down) //make sure they're keep in sync in case it was forcibly unanchored by badmins or by a megafauna.
- welded_down = FALSE
- can_atmos_pass = anchorvalue ? ATMOS_PASS_NO : ATMOS_PASS_YES
- air_update_turf(TRUE, anchorvalue)
-
/obj/machinery/smartfridge/welder_act(mob/living/user, obj/item/tool)
- ..()
- if(istype(src, /obj/machinery/smartfridge/drying_rack))
- return FALSE
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
+
if(welded_down)
if(!tool.tool_start_check(user, amount=2))
- return TRUE
+ return
+
user.visible_message(
span_notice("[user.name] starts to cut the [name] free from the floor."),
span_notice("You start to cut [src] free from the floor..."),
span_hear("You hear welding."),
)
+
if(!tool.use_tool(src, user, delay=100, volume=100))
- return FALSE
+ return
+
welded_down = FALSE
to_chat(user, span_notice("You cut [src] free from the floor."))
- return TRUE
+ return
+
if(!anchored)
- to_chat(user, span_warning("[src] needs to be wrenched to the floor!"))
- return TRUE
+ balloon_alert(user, "wrench it first!")
+ return
+
if(!tool.tool_start_check(user, amount=2))
- return TRUE
+ return
+
user.visible_message(
span_notice("[user.name] starts to weld the [name] to the floor."),
span_notice("You start to weld [src] to the floor..."),
span_hear("You hear welding."),
)
- if(!tool.use_tool(src, user, delay=100, volume=100))
- balloon_alert(user, "cancelled!")
- return FALSE
+
+ if(!tool.use_tool(src, user, delay = 100, volume = 100))
+ return
+
welded_down = TRUE
to_chat(user, span_notice("You weld [src] to the floor."))
- return TRUE
/obj/machinery/smartfridge/welder_act_secondary(mob/living/user, obj/item/tool)
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
+
+ if(!(machine_stat & BROKEN))
+ balloon_alert(user, "no repair needed!")
+ return
+
+ if(!tool.tool_start_check(user, amount=1))
+ return
+
+ user.visible_message(
+ span_notice("[user] is repairing [src]."),
+ span_notice("You begin repairing [src]..."),
+ span_hear("You hear welding."),
+ )
+
+ if(tool.use_tool(src, user, delay = 40, volume = 50))
+ if(!(machine_stat & BROKEN))
+ return
+ to_chat(user, span_notice("You repair [src]"))
+ atom_integrity = max_integrity
+ set_machine_stat(machine_stat & ~BROKEN)
+ update_icon()
+
+/obj/machinery/smartfridge/screwdriver_act(mob/living/user, obj/item/tool)
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
+
+ if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool))
+ if(panel_open)
+ add_overlay("[initial(icon_state)]-panel")
+ else
+ cut_overlay("[initial(icon_state)]-panel")
+ SStgui.update_uis(src)
+
+/obj/machinery/smartfridge/can_be_unfasten_wrench(mob/user, silent)
+ if(welded_down)
+ balloon_alert(user, "unweld first!")
+ return FAILED_UNFASTEN
+ return ..()
+
+/obj/machinery/smartfridge/set_anchored(anchorvalue)
. = ..()
- if(istype(src, /obj/machinery/smartfridge/drying_rack))
- return FALSE
- if(machine_stat & BROKEN)
- if(!tool.tool_start_check(user, amount=1))
- return FALSE
- user.visible_message(
- span_notice("[user] is repairing [src]."),
- span_notice("You begin repairing [src]..."),
- span_hear("You hear welding."),
- )
- if(tool.use_tool(src, user, delay=40, volume=50))
- if(!(machine_stat & BROKEN))
- return FALSE
- balloon_alert(user, "repaired")
- atom_integrity = max_integrity
- set_machine_stat(machine_stat & ~BROKEN)
- update_icon()
- return TRUE
+ if(!anchored && welded_down) //make sure they're keep in sync in case it was forcibly unanchored by badmins or by a megafauna.
+ welded_down = FALSE
+ can_atmos_pass = anchorvalue ? ATMOS_PASS_NO : ATMOS_PASS_YES
+ air_update_turf(TRUE, anchorvalue)
+
+/obj/machinery/smartfridge/wrench_act(mob/living/user, obj/item/tool)
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
+
+ if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN)
+ power_change()
+
+/obj/machinery/smartfridge/crowbar_act(mob/living/user, obj/item/tool)
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
+
+ if(default_pry_open(tool, close_after_pry = TRUE))
+ return
+
+ if(welded_down)
+ balloon_alert(user, "unweld first!")
else
- balloon_alert(user, "no repair needed!")
- return FALSE
+ default_deconstruction_crowbar(tool)
/obj/machinery/smartfridge/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(isnull(held_item))
return NONE
var/tool_tip_set = FALSE
- if(held_item.tool_behaviour == TOOL_WELDER && !istype(src, /obj/machinery/smartfridge/drying_rack))
+ if(held_item.tool_behaviour == TOOL_WELDER)
if(welded_down)
context[SCREENTIP_CONTEXT_LMB] = "Unweld"
tool_tip_set = TRUE
@@ -136,6 +168,19 @@
context[SCREENTIP_CONTEXT_RMB] = "Repair"
tool_tip_set = TRUE
+ else if(held_item.tool_behaviour == TOOL_SCREWDRIVER)
+ context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "close" : "open"] panel"
+ tool_tip_set = TRUE
+
+ else if(held_item.tool_behaviour == TOOL_CROWBAR)
+ if(panel_open)
+ context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
+ tool_tip_set = TRUE
+
+ else if(held_item.tool_behaviour == TOOL_WRENCH)
+ context[SCREENTIP_CONTEXT_LMB] = "[anchored ? "Un" : ""]anchore"
+ tool_tip_set = TRUE
+
return tool_tip_set ? CONTEXTUAL_SCREENTIP_SET : NONE
/obj/machinery/smartfridge/RefreshParts()
@@ -149,19 +194,26 @@
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: This unit can hold a maximum of [max_n_of_items] items.")
+ . += structure_examine()
+
+/// Returns details related to the fridge structure
+/obj/machinery/smartfridge/proc/structure_examine()
+ . = ""
+
if(welded_down)
- . += span_info("It's moored firmly to the floor. You can unsecure its moorings with a welder.")
- else if(anchored)
- . += span_info("It's currently anchored to the floor. You can secure its moorings with a welder, or remove it with a wrench.")
+ . += span_info("It's moorings are firmly [EXAMINE_HINT("welded")] to the floor.")
+ else
+ . += span_info("It's moorings are loose and can be [EXAMINE_HINT("welded")] down.")
+
+ if(anchored)
+ . += span_info("It is [EXAMINE_HINT("wrenched")] down on the floor.")
else
- . += span_info("It's not anchored to the floor. You can secure it in place with a wrench.")
+ . += span_info("It could be [EXAMINE_HINT("wrenched")] down.")
/obj/machinery/smartfridge/update_appearance(updates=ALL)
. = ..()
- if(machine_stat & BROKEN)
- set_light(0)
- return
- set_light(powered() ? MINIMUM_USEFUL_LIGHT_RANGE : 0)
+
+ set_light((!(machine_stat & BROKEN) && powered()) ? MINIMUM_USEFUL_LIGHT_RANGE : 0)
/obj/machinery/smartfridge/update_icon_state()
icon_state = "[initial(icon_state)]"
@@ -171,49 +223,33 @@
icon_state += "-off"
return ..()
+/// Returns the number of items visible in the fridge. Faster than subtracting 2 lists
+/obj/machinery/smartfridge/proc/visible_items()
+ var/component_part_count = 0
+ for(var/datum/stock_part/datum_part in component_parts)
+ component_part_count -= 1
+ return contents.len - component_part_count
+
/obj/machinery/smartfridge/update_overlays()
. = ..()
- var/list/shown_contents = contents - component_parts
- if(visible_contents && shown_contents.len > 0)
- var/contents_icon_state = "[initial(icon_state)]"
- switch(base_build_path)
- if(/obj/machinery/smartfridge/extract)
- contents_icon_state += "-slime"
- if(/obj/machinery/smartfridge/food)
- contents_icon_state += "-food"
- if(/obj/machinery/smartfridge/drinks)
- contents_icon_state += "-drink"
- if(/obj/machinery/smartfridge/organ)
- contents_icon_state += "-organ"
- if(/obj/machinery/smartfridge/petri)
- contents_icon_state += "-petri"
- if(/obj/machinery/smartfridge/chemistry)
- contents_icon_state += "-chem"
- if(/obj/machinery/smartfridge/chemistry/virology)
- contents_icon_state += "-viro"
- else
- contents_icon_state += "-plant"
- switch(shown_contents.len)
+ var/shown_contents_length = visible_items()
+ if(visible_contents && shown_contents_length)
+ var/content_level = "[initial(icon_state)]-[contents_icon_state]"
+ switch(shown_contents_length)
if(1 to 25)
- contents_icon_state += "-1"
+ content_level += "-1"
if(26 to 50)
- contents_icon_state += "-2"
+ content_level += "-2"
if(31 to INFINITY)
- contents_icon_state += "-3"
- . += mutable_appearance(icon, contents_icon_state)
+ content_level += "-3"
+ . += mutable_appearance(icon, content_level)
. += mutable_appearance(icon, "[initial(icon_state)]-glass[(machine_stat & BROKEN) ? "-broken" : ""]")
if(!machine_stat && has_emissive)
. += emissive_appearance(icon, "[initial(icon_state)]-light-mask", src, alpha = src.alpha)
-/obj/machinery/smartfridge/wrench_act(mob/living/user, obj/item/tool)
- . = ..()
- if(default_unfasten_wrench(user, tool))
- power_change()
- return TOOL_ACT_TOOLTYPE_SUCCESS
-
/obj/machinery/smartfridge/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
@@ -225,101 +261,94 @@
playsound(src, SFX_SHATTER, 50, TRUE)
return ..()
-/*******************
-* Item Adding
-********************/
-
-/obj/machinery/smartfridge/attackby(obj/item/O, mob/living/user, params)
- if(default_deconstruction_screwdriver(user, icon_state, icon_state, O))
- if(panel_open)
- add_overlay("[initial(icon_state)]-panel")
- else
- cut_overlay("[initial(icon_state)]-panel")
- SStgui.update_uis(src)
- return
-
- if(default_pry_open(O, close_after_pry = TRUE))
- return
-
- if(!welded_down && default_deconstruction_crowbar(O))
- SStgui.update_uis(src)
- return
-
+/obj/machinery/smartfridge/attackby(obj/item/weapon, mob/living/user, params)
if(!machine_stat)
- var/list/shown_contents = contents - component_parts
- if(shown_contents.len >= max_n_of_items)
- to_chat(user, span_warning("\The [src] is full!"))
+ var/shown_contents_length = visible_items()
+ if(shown_contents_length >= max_n_of_items)
+ balloon_alert(user, "no space!")
return FALSE
- if(accept_check(O))
- load(O)
- user.visible_message(span_notice("[user] adds \the [O] to \the [src]."), span_notice("You add \the [O] to \the [src]."))
+ if(!(weapon.item_flags & ABSTRACT) && \
+ !(weapon.flags_1 & HOLOGRAM_1) && \
+ accept_check(weapon) \
+ )
+ load(weapon)
+ user.visible_message(span_notice("[user] adds \the [weapon] to \the [src]."), span_notice("You add \the [weapon] to \the [src]."))
SStgui.update_uis(src)
if(visible_contents)
update_appearance()
return TRUE
- if(istype(O, /obj/item/storage/bag))
- var/obj/item/storage/P = O
+ if(istype(weapon, /obj/item/storage/bag))
+ var/obj/item/storage/bag = weapon
var/loaded = 0
- for(var/obj/G in P.contents)
- if(shown_contents.len >= max_n_of_items)
+ for(var/obj/item/object in bag.contents)
+ if(shown_contents_length >= max_n_of_items)
break
- if(accept_check(G))
- load(G)
+ if(!(object.item_flags & ABSTRACT) && \
+ !(object.flags_1 & HOLOGRAM_1) && \
+ accept_check(object) \
+ )
+ load(object)
loaded++
SStgui.update_uis(src)
if(loaded)
- if(shown_contents.len >= max_n_of_items)
- user.visible_message(span_notice("[user] loads \the [src] with \the [O]."), \
- span_notice("You fill \the [src] with \the [O]."))
+ if(shown_contents_length >= max_n_of_items)
+ user.visible_message(span_notice("[user] loads \the [src] with \the [weapon]."), \
+ span_notice("You fill \the [src] with \the [weapon]."))
else
- user.visible_message(span_notice("[user] loads \the [src] with \the [O]."), \
- span_notice("You load \the [src] with \the [O]."))
- if(O.contents.len > 0)
+ user.visible_message(span_notice("[user] loads \the [src] with \the [weapon]."), \
+ span_notice("You load \the [src] with \the [weapon]."))
+ if(weapon.contents.len)
to_chat(user, span_warning("Some items are refused."))
if (visible_contents)
update_appearance()
return TRUE
else
- to_chat(user, span_warning("There is nothing in [O] to put in [src]!"))
+ to_chat(user, span_warning("There is nothing in [weapon] to put in [src]!"))
return FALSE
if(!user.combat_mode)
- to_chat(user, span_warning("\The [src] smartly refuses [O]."))
- SStgui.update_uis(src)
+ to_chat(user, span_warning("\The [src] smartly refuses [weapon]."))
return FALSE
+
else
return ..()
-/obj/machinery/smartfridge/proc/accept_check(obj/item/O)
- if(istype(O, /obj/item/food/grown/) || istype(O, /obj/item/seeds/) || istype(O, /obj/item/grown/) || istype(O, /obj/item/graft/))
- return TRUE
- return FALSE
-
-/obj/machinery/smartfridge/proc/load(obj/item/O)
- if(ismob(O.loc))
- var/mob/M = O.loc
- if(!M.transferItemToLoc(O, src))
- to_chat(usr, span_warning("\the [O] is stuck to your hand, you cannot put it in \the [src]!"))
+/**
+ * Can this item be accepted by the smart fridge
+ * Arguments
+ * * [weapon][obj/item] - the item to accept
+ */
+/obj/machinery/smartfridge/proc/accept_check(obj/item/weapon)
+ var/static/list/accepted_items = list(
+ /obj/item/food/grown,
+ /obj/item/seeds,
+ /obj/item/grown,
+ /obj/item/graft,
+ )
+ return is_type_in_list(weapon, accepted_items)
+
+/**
+ * Loads the item into the smart fridge
+ * Arguments
+ * * [weapon][obj/item] - the item to load. If the item is being held by a mo it will transfer it from hand else directly force move
+ */
+/obj/machinery/smartfridge/proc/load(obj/item/weapon)
+ if(ismob(weapon.loc))
+ var/mob/owner = weapon.loc
+ if(!owner.transferItemToLoc(weapon, src))
+ to_chat(usr, span_warning("\the [weapon] is stuck to your hand, you cannot put it in \the [src]!"))
return FALSE
- else
- return TRUE
+ return TRUE
else
- if(O.loc.atom_storage)
- return O.loc.atom_storage.attempt_remove(O, src)
+ if(weapon.loc.atom_storage)
+ return weapon.loc.atom_storage.attempt_remove(weapon, src, silent = TRUE)
else
- O.forceMove(src)
+ weapon.forceMove(src)
return TRUE
-///Really simple proc, just moves the object "O" into the hands of mob "M" if able, done so I could modify the proc a little for the organ fridge
-/obj/machinery/smartfridge/proc/dispense(obj/item/O, mob/M)
- if(!M.put_in_hands(O))
- O.forceMove(drop_location())
- adjust_item_drop_location(O)
- use_power(active_power_usage)
-
/obj/machinery/smartfridge/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -331,18 +360,18 @@
. = list()
var/listofitems = list()
- for (var/I in src)
+ for (var/item in src)
// We do not vend our own components.
- if(I in component_parts)
+ if(item in component_parts)
continue
- var/atom/movable/O = I
- if (!QDELETED(O))
- var/md5name = md5(O.name) // This needs to happen because of a bug in a TGUI component, https://github.com/ractivejs/ractive/issues/744
+ var/atom/movable/atom = item
+ if (!QDELETED(atom))
+ var/md5name = md5(atom.name) // This needs to happen because of a bug in a TGUI component, https://github.com/ractivejs/ractive/issues/744
if (listofitems[md5name]) // which is fixed in a version we cannot use due to ie8 incompatibility
listofitems[md5name]["amount"]++ // The good news is, #30519 made smartfridge UIs non-auto-updating
else
- listofitems[md5name] = list("name" = O.name, "type" = O.type, "amount" = 1)
+ listofitems[md5name] = list("name" = atom.name, "amount" = 1)
sort_list(listofitems)
.["contents"] = listofitems
@@ -353,27 +382,28 @@
. = ..()
SStgui.update_uis(src)
-/obj/machinery/smartfridge/ui_act(action, params)
+/obj/machinery/smartfridge/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
. = ..()
- if(.)
+ if(. || !ui.user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
+
+ . = TRUE
+ var/mob/living_mob = ui.user
+
switch(action)
if("Release")
var/desired = 0
- if(!allow_ai_retrieve && isAI(usr))
- to_chat(usr, span_warning("[src] does not seem to be configured to respect your authority!"))
+ if(isAI(living_mob))
+ to_chat(living_mob, span_warning("[src] does not respect your authority!"))
return
if (params["amount"])
desired = text2num(params["amount"])
else
- desired = tgui_input_number(usr, "How many items would you like to take out?", "Release", max_value = 50)
+ desired = tgui_input_number(living_mob, "How many items would you like to take out?", "Release", max_value = 50)
if(!desired)
- return FALSE
-
- if(QDELETED(src) || QDELETED(usr) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH)) // Sanity checkin' in case stupid stuff happens while we wait for input()
- return FALSE
+ return
for(var/obj/item/dispensed_item in src)
if(desired <= 0)
@@ -384,12 +414,16 @@
if(format_text(dispensed_item.name) == format_text(params["name"]))
if(dispensed_item in component_parts)
CRASH("Attempted removal of [dispensed_item] component_part from smartfridge via smartfridge interface.")
- dispense(dispensed_item, usr)
+ //dispense the item
+ if(!living_mob.put_in_hands(dispensed_item))
+ dispensed_item.forceMove(drop_location())
+ adjust_item_drop_location(dispensed_item)
+ use_power(active_power_usage)
desired--
if (visible_contents)
update_appearance()
- return TRUE
+ return
return FALSE
@@ -408,48 +442,72 @@
idle_power_usage = 0
has_emissive = FALSE
can_atmos_pass = ATMOS_PASS_YES
+ /// Is the rack currently drying stuff
var/drying = FALSE
-/obj/machinery/smartfridge/drying_rack/on_deconstruction()
- new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)
+/obj/machinery/smartfridge/drying_rack/Initialize(mapload)
+ . = ..()
- //remove all component parts inherited from smartfridge cause they were not required in crafting
- var/obj/item/circuitboard/machine/smartfridge/board = locate() in component_parts
- component_parts -= board
- qdel(board)
- component_parts.Cut()
+ //you can't weld down wood
+ welded_down = FALSE
- return ..()
+ //so we don't drop any of the parent smart fridge parts upon deconstruction
+ clear_components()
+/// We cleared out the components in initialize so we can optimize this
+/obj/machinery/smartfridge/drying_rack/visible_items()
+ return contents.len
+
+/obj/machinery/smartfridge/drying_rack/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
+ if(isnull(held_item))
+ return NONE
+
+ var/tool_tip_set = FALSE
+ if(held_item.tool_behaviour == TOOL_CROWBAR)
+ context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
+ tool_tip_set = TRUE
+ else if(held_item.tool_behaviour == TOOL_WRENCH)
+ context[SCREENTIP_CONTEXT_LMB] = "[anchored ? "Un" : ""]anchore"
+ tool_tip_set = TRUE
+
+ return tool_tip_set ? CONTEXTUAL_SCREENTIP_SET : NONE
+
+/obj/machinery/smartfridge/drying_rack/structure_examine()
+ . = ""
+ if(anchored)
+ . += span_info("It's currently anchored to the floor. It can be [EXAMINE_HINT("wrenched")] loose.")
+ else
+ . += span_info("It's not anchored to the floor. It can be [EXAMINE_HINT("wrenched")] down.")
+ . += span_info("The whole rack can be [EXAMINE_HINT("pried")] apart.")
+/obj/machinery/smartfridge/drying_rack/welder_act(mob/living/user, obj/item/tool)
+/obj/machinery/smartfridge/drying_rack/welder_act_secondary(mob/living/user, obj/item/tool)
/obj/machinery/smartfridge/drying_rack/default_deconstruction_screwdriver()
/obj/machinery/smartfridge/drying_rack/exchange_parts()
-/obj/machinery/smartfridge/drying_rack/spawn_frame()
+/obj/machinery/smartfridge/drying_rack/on_deconstruction()
+ new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)
+/obj/machinery/smartfridge/drying_rack/crowbar_act(mob/living/user, obj/item/tool)
+ . = TOOL_ACT_TOOLTYPE_SUCCESS
-/obj/machinery/smartfridge/drying_rack/default_deconstruction_crowbar(obj/item/crowbar/C, ignore_panel = 1)
- ..()
+ default_deconstruction_crowbar(tool, ignore_panel = TRUE)
/obj/machinery/smartfridge/drying_rack/ui_data(mob/user)
. = ..()
.["isdryer"] = TRUE
- .["verb"] = "Take"
.["drying"] = drying
-
/obj/machinery/smartfridge/drying_rack/ui_act(action, params)
. = ..()
if(.)
update_appearance() // This is to handle a case where the last item is taken out manually instead of through drying pop-out
return
+
switch(action)
if("Dry")
toggle_drying(FALSE)
return TRUE
- return FALSE
/obj/machinery/smartfridge/drying_rack/powered()
- if(!anchored)
- return FALSE
- return ..()
+ return !anchored ? FALSE : ..()
/obj/machinery/smartfridge/drying_rack/power_change()
. = ..()
@@ -464,12 +522,10 @@
. = ..()
if(drying)
. += "drying_rack_drying"
- var/list/shown_contents = contents - component_parts
- if(shown_contents.len)
+ if(contents.len)
. += "drying_rack_filled"
/obj/machinery/smartfridge/drying_rack/process()
- ..()
if(drying)
for(var/obj/item/item_iterator in src)
if(!accept_check(item_iterator))
@@ -481,10 +537,13 @@
use_power(active_power_usage)
/obj/machinery/smartfridge/drying_rack/accept_check(obj/item/O)
- if(HAS_TRAIT(O, TRAIT_DRYABLE)) //set on dryable element
- return TRUE
- return FALSE
+ return HAS_TRAIT(O, TRAIT_DRYABLE)
+/**
+ * Toggles drying on or off
+ * Arguments
+ * * forceoff - if TRUE will force the dryer off always
+ */
/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff)
if(drying || forceoff)
drying = FALSE
@@ -503,7 +562,6 @@
return
atmos_spawn_air("[TURF_TEMPERATURE(1000)]")
-
// ----------------------------
// Bar drink smartfridge
// ----------------------------
@@ -511,12 +569,19 @@
name = "drink showcase"
desc = "A refrigerated storage unit for tasty tasty alcohol."
base_build_path = /obj/machinery/smartfridge/drinks
+ contents_icon_state = "drink"
-/obj/machinery/smartfridge/drinks/accept_check(obj/item/O)
- if(!is_reagent_container(O) || (O.item_flags & ABSTRACT) || istype(O,/obj/item/reagent_containers/cup/bowl) || !O.reagents || !O.reagents.reagent_list.len)
+/obj/machinery/smartfridge/drinks/accept_check(obj/item/weapon)
+ //not an item or valid container
+ if(!is_reagent_container(weapon))
return FALSE
- if(istype(O, /obj/item/reagent_containers/cup) || istype(O, /obj/item/reagent_containers/cup/glass) || istype(O, /obj/item/reagent_containers/condiment))
- return TRUE
+
+ //an bowl or something that has no reagents
+ if(istype(weapon,/obj/item/reagent_containers/cup/bowl) || !length(weapon.reagents?.reagent_list))
+ return FALSE
+
+ //list of items acceptable
+ return (istype(weapon, /obj/item/reagent_containers/cup) || istype(weapon, /obj/item/reagent_containers/condiment))
// ----------------------------
// Food smartfridge
@@ -524,11 +589,10 @@
/obj/machinery/smartfridge/food
desc = "A refrigerated storage unit for food."
base_build_path = /obj/machinery/smartfridge/food
+ contents_icon_state = "food"
-/obj/machinery/smartfridge/food/accept_check(obj/item/O)
- if(IS_EDIBLE(O) || (istype(O,/obj/item/reagent_containers/cup/bowl) && O.reagents && O.reagents.reagent_list.len))
- return TRUE
- return FALSE
+/obj/machinery/smartfridge/food/accept_check(obj/item/weapon)
+ return (IS_EDIBLE(weapon) || (istype(weapon,/obj/item/reagent_containers/cup/bowl) && length(weapon.reagents?.reagent_list)))
// -------------------------------------
// Xenobiology Slime-Extract Smartfridge
@@ -537,13 +601,10 @@
name = "smart slime extract storage"
desc = "A refrigerated storage unit for slime extracts."
base_build_path = /obj/machinery/smartfridge/extract
+ contents_icon_state = "slime"
-/obj/machinery/smartfridge/extract/accept_check(obj/item/O)
- if(istype(O, /obj/item/slime_extract))
- return TRUE
- if(istype(O, /obj/item/slime_scanner))
- return TRUE
- return FALSE
+/obj/machinery/smartfridge/extract/accept_check(obj/item/weapon)
+ return (istype(weapon, /obj/item/slime_extract) || istype(weapon, /obj/item/slime_scanner))
/obj/machinery/smartfridge/extract/preloaded
initial_contents = list(/obj/item/slime_scanner = 2)
@@ -555,11 +616,10 @@
name = "smart petri dish storage"
desc = "A refrigerated storage unit for petri dishes."
base_build_path = /obj/machinery/smartfridge/petri
+ contents_icon_state = "petri"
-/obj/machinery/smartfridge/petri/accept_check(obj/item/O)
- if(istype(O, /obj/item/petri_dish))
- return TRUE
- return FALSE
+/obj/machinery/smartfridge/petri/accept_check(obj/item/weapon)
+ return istype(weapon, /obj/item/petri_dish)
/obj/machinery/smartfridge/petri/preloaded
initial_contents = list(/obj/item/petri_dish = 5)
@@ -572,20 +632,22 @@
desc = "A refrigerated storage unit for organ storage."
max_n_of_items = 20 //vastly lower to prevent processing too long
base_build_path = /obj/machinery/smartfridge/organ
+ contents_icon_state = "organ"
+ /// The rate at which this fridge will repair damaged organs
var/repair_rate = 0
/obj/machinery/smartfridge/organ/accept_check(obj/item/O)
- if(isorgan(O) || isbodypart(O))
- return TRUE
- return FALSE
+ return (isorgan(O) || isbodypart(O))
/obj/machinery/smartfridge/organ/load(obj/item/O)
. = ..()
if(!.) //if the item loads, clear can_decompose
return
+
if(isorgan(O))
var/obj/item/organ/organ = O
organ.organ_flags |= ORGAN_FROZEN
+
if(isbodypart(O))
var/obj/item/bodypart/bodypart = O
for(var/obj/item/organ/stored in bodypart.contents)
@@ -606,9 +668,11 @@
/obj/machinery/smartfridge/organ/Exited(atom/movable/gone, direction)
. = ..()
+
if(isorgan(gone))
var/obj/item/organ/O = gone
O.organ_flags &= ~ORGAN_FROZEN
+
if(isbodypart(gone))
var/obj/item/bodypart/bodypart = gone
for(var/obj/item/organ/stored in bodypart.contents)
@@ -621,8 +685,31 @@
name = "smart chemical storage"
desc = "A refrigerated storage unit for medicine storage."
base_build_path = /obj/machinery/smartfridge/chemistry
+ contents_icon_state = "chem"
+
+/obj/machinery/smartfridge/chemistry/accept_check(obj/item/weapon)
+ // not an item or reagent container
+ if(!is_reagent_container(weapon))
+ return FALSE
+
+ // empty pill prank ok
+ if(istype(weapon, /obj/item/reagent_containers/pill))
+ return TRUE
+
+ //check each pill in the pill bottle
+ if(istype(weapon, /obj/item/storage/pill_bottle))
+ if(weapon.contents.len)
+ for(var/obj/item/target_item in weapon)
+ if(!accept_check(target_item))
+ return FALSE
+ return TRUE
+ return FALSE
-/obj/machinery/smartfridge/chemistry/accept_check(obj/item/O)
+ // other empty containers not accepted
+ if(!length(weapon.reagents?.reagent_list))
+ return FALSE
+
+ // the long list of other containers that can be accepted
var/static/list/chemfridge_typecache = typecacheof(list(
/obj/item/reagent_containers/syringe,
/obj/item/reagent_containers/cup/tube,
@@ -633,23 +720,7 @@
/obj/item/reagent_containers/cup/vial, //SKYRAT EDIT ADDITION - HYPOSPRAYS
/obj/item/reagent_containers/chem_pack
))
-
- if(istype(O, /obj/item/storage/pill_bottle))
- if(O.contents.len)
- for(var/obj/item/I in O)
- if(!accept_check(I))
- return FALSE
- return TRUE
- return FALSE
- if(!is_reagent_container(O) || (O.item_flags & ABSTRACT))
- return FALSE
- if(istype(O, /obj/item/reagent_containers/pill)) // empty pill prank ok
- return TRUE
- if(!O.reagents || !O.reagents.reagent_list.len) // other empty containers not accepted
- return FALSE
- if(is_type_in_typecache(O, chemfridge_typecache))
- return TRUE
- return FALSE
+ return is_type_in_typecache(weapon, chemfridge_typecache)
/obj/machinery/smartfridge/chemistry/preloaded
initial_contents = list(
@@ -665,6 +736,7 @@
name = "smart virus storage"
desc = "A refrigerated storage unit for volatile sample storage."
base_build_path = /obj/machinery/smartfridge/chemistry/virology
+ contents_icon_state = "viro"
/obj/machinery/smartfridge/chemistry/virology/preloaded
initial_contents = list(
@@ -691,8 +763,5 @@
visible_contents = FALSE
base_build_path = /obj/machinery/smartfridge/disks
-/obj/machinery/smartfridge/disks/accept_check(obj/item/O)
- if(istype(O, /obj/item/disk/))
- return TRUE
- else
- return FALSE
+/obj/machinery/smartfridge/disks/accept_check(obj/item/weapon)
+ return istype(weapon, /obj/item/disk)
diff --git a/tgui/packages/tgui/interfaces/SmartVend.js b/tgui/packages/tgui/interfaces/SmartVend.tsx
similarity index 81%
rename from tgui/packages/tgui/interfaces/SmartVend.js
rename to tgui/packages/tgui/interfaces/SmartVend.tsx
index 9ca12a87b7d..54470b18a35 100644
--- a/tgui/packages/tgui/interfaces/SmartVend.js
+++ b/tgui/packages/tgui/interfaces/SmartVend.tsx
@@ -1,10 +1,23 @@
-import { map } from 'common/collections';
+import { BooleanLike } from 'common/react';
import { useBackend } from '../backend';
import { Button, NoticeBox, Section, Table } from '../components';
import { Window } from '../layouts';
+type Item = {
+ name: string;
+ amount: number;
+};
+
+type Data = {
+ contents: Item[];
+ name: string;
+ isdryer: BooleanLike;
+ drying: BooleanLike;
+};
+
export const SmartVend = (props, context) => {
- const { act, data } = useBackend(context);
+ const { act, data } = useBackend(context);
+ const { contents = [] } = data;
return (
@@ -19,18 +32,18 @@ export const SmartVend = (props, context) => {
)
}>
- {(data.contents.length === 0 && (
+ {contents.length === 0 ? (
Unfortunately, this {data.name} is empty.
- )) || (
+ ) : (
Item
- {data.verb ? data.verb : 'Dispense'}
+ {data.isdryer ? 'Take' : 'Dispense'}
- {map((value, key) => (
+ {Object.values(contents).map((value, key) => (
{value.name}
@@ -58,7 +71,7 @@ export const SmartVend = (props, context) => {
/>
- ))(data.contents)}
+ ))}
)}