diff --git a/code/datums/crew_objective.dm b/code/datums/crew_objective.dm
index 60625c3b3edeb..a8ab0bc0d4e3d 100644
--- a/code/datums/crew_objective.dm
+++ b/code/datums/crew_objective.dm
@@ -620,7 +620,7 @@ ABSTRACT_TYPE(/datum/objective/crew/miner)
var/list/materials = list()
if(isnull(check_result))
for_by_tcl(S, /obj/machinery/ore_cloud_storage_container)
- if(S.broken)
+ if(S.is_disabled())
continue
var/list/ores = S.ores
for(var/ore in ores)
diff --git a/code/obj/item/device/pda2/smallprogs.dm b/code/obj/item/device/pda2/smallprogs.dm
index 1330b5fddb6d0..8eb9f3c029f1c 100644
--- a/code/obj/item/device/pda2/smallprogs.dm
+++ b/code/obj/item/device/pda2/smallprogs.dm
@@ -1737,7 +1737,7 @@ Using electronic "Detomatix" SELF-DESTRUCT program is perhaps less simple!
for_by_tcl(S, /obj/machinery/ore_cloud_storage_container)
. += "Location: [get_area(S)]
"
- if(S.broken)
+ if(S.is_disabled())
.= "No response from Rockbox™ Ore Cloud Storage Container!
"
continue
if (!length(S.ores))
diff --git a/code/obj/machinery.dm b/code/obj/machinery.dm
index 15827643a084d..0d57e02d016ed 100644
--- a/code/obj/machinery.dm
+++ b/code/obj/machinery.dm
@@ -332,6 +332,15 @@
qdel(pulse2)
return
+/obj/machinery/proc/is_broken()
+ return (src.status & BROKEN)
+
+/obj/machinery/proc/has_no_power()
+ return (src.status & NOPOWER)
+
+/obj/machinery/proc/is_disabled()
+ return src.is_broken() || src.has_no_power()
+
/obj/machinery/sec_lock
name = "Security Pad"
icon = 'icons/obj/stationobjs.dmi'
diff --git a/code/obj/machinery/manufacturer.dm b/code/obj/machinery/manufacturer.dm
index 909fc742bc335..857f07b119c29 100644
--- a/code/obj/machinery/manufacturer.dm
+++ b/code/obj/machinery/manufacturer.dm
@@ -563,7 +563,7 @@ TYPEINFO(/obj/machinery/manufacturer)
dat+= src.temp
dat += "
Ores Available for Purchase:
"
for_by_tcl(S, /obj/machinery/ore_cloud_storage_container)
- if(S.broken)
+ if(S.is_disabled())
continue
dat += "[S.name] at [get_area(S)]:
"
var/list/ores = S.ores
@@ -843,7 +843,7 @@ TYPEINFO(/obj/machinery/manufacturer)
var/price = OCD.price
var/taxes = round(max(rockbox_globals.rockbox_client_fee_min,abs(price*rockbox_globals.rockbox_client_fee_pct/100)),0.01) //transaction taxes for the station budget
- if(storage?.broken)
+ if(storage?.is_disabled())
return
if(!scan)
diff --git a/code/obj/mining_cloud_storage.dm b/code/obj/mining_cloud_storage.dm
index 407918ddacdbb..fa507fdef1967 100644
--- a/code/obj/mining_cloud_storage.dm
+++ b/code/obj/mining_cloud_storage.dm
@@ -6,6 +6,8 @@
var/list/stats = list()
var/amount_sold = 0
+#define ROCKBOX_MAX_HEALTH 100
+
/obj/machinery/ore_cloud_storage_container
name = "Rockbox™ Ore Cloud Storage Container"
desc = "This thing stores ore in \"the cloud\" for the station to use. Best not to think about it too hard."
@@ -15,12 +17,13 @@
anchored = ANCHORED
event_handler_flags = USE_FLUID_ENTER | NO_MOUSEDROP_QOL
+ var/sound_destroyed = 'sound/impact_sounds/Machinery_Break_1.ogg'
var/list/datum/ore_cloud_data/ores = list()
var/default_price = 20
var/autosell = TRUE
- var/health = 100
- var/broken = FALSE
+ var/health = ROCKBOX_MAX_HEALTH
+
var/sound/sound_load = sound('sound/items/Deconstruct.ogg')
var/output_target = null
@@ -34,6 +37,7 @@
STOP_TRACKING
mouse_drop(over_object, src_location, over_location)
+
if(!isliving(usr) || isintangible(usr))
boutput(usr, SPAN_ALERT("Only tangible, living mobs are able to set the output target for [src]."))
return
@@ -46,6 +50,10 @@
boutput(usr, SPAN_ALERT("You are too far away from the target!"))
return
+ if (src.is_broken())
+ boutput(usr, SPAN_ALERT("Cannot set output target as [src] seems broken and inoperable!"))
+ return
+
if (istype(over_object,/obj/storage/crate/))
var/obj/storage/crate/C = over_object
if (C.locked || C.welded)
@@ -91,6 +99,10 @@
boutput(user, SPAN_ALERT("You are too far away!"))
return
+ if (src.is_broken())
+ boutput(user, SPAN_ALERT("The quick-load system will not work since the [src] seems broken and inoperable!"))
+ return
+
if(!src.accept_loading(user, TRUE))
boutput(user,SPAN_ALERT("The storage container's quick-load system rejects you!"))
return
@@ -163,15 +175,31 @@
boutput(user, SPAN_NOTICE("You finish stuffing [O] into [src]!"))
return
+ proc/write_message_broken(mob/user)
+ boutput(user, SPAN_ALERT("Cannot deposit ores into [src] since it seems to be broken and inoperable!"))
+
attackby(obj/item/W, mob/user)
+ var/broken = src.is_broken()
+
if (istype(W, /obj/item/ore_scoop))
+ if (broken)
+ src.write_message_broken(user)
+ return
+
var/obj/item/ore_scoop/scoop = W
if (!scoop?.satchel)
boutput(user, SPAN_ALERT("No ore satchel to unload from [W]."))
return
W = scoop.satchel
- if (istype(W, /obj/item/raw_material/) && src.accept_loading(user))
+ if (istype(W, /obj/item/raw_material/))
+ if (broken)
+ src.write_message_broken(user)
+ return
+
+ if (!src.accept_loading(user))
+ return
+
var/obj/item/raw_material/R = W
if(R.material?.getName() != R.initial_material_name)
boutput(user, SPAN_ALERT("[src] rejects the anomalous ore."))
@@ -179,6 +207,10 @@
user.visible_message(SPAN_NOTICE("[user] loads [W] into the [src]."), SPAN_NOTICE("You load [W] into the [src]."))
src.load_item(W,user)
else if (istype(W, /obj/item/satchel/mining))
+ if (broken)
+ src.write_message_broken(user)
+ return
+
var/obj/item/satchel/mining/satchel = W
user.visible_message(SPAN_NOTICE("[user] starts dumping [satchel] into [src]."), SPAN_NOTICE("You start dumping [satchel] into [src]."))
var/amtload = 0
@@ -194,16 +226,28 @@
boutput(user, SPAN_NOTICE("[amtload] materials loaded from [satchel]!"))
else
boutput(user, SPAN_ALERT("[satchel] is empty!"))
- else
- src.health = max(src.health-W.force,0)
- src.check_health()
+ else if (!broken)
+ if (W.hitsound)
+ playsound(src.loc, W.hitsound, 50, 1)
+ if (W.force)
+ src.health = max(src.health - randfloat(W.force/1.5, W.force),0)
+
+ attack_particle(user,src)
+ hit_twitch(src)
+ src.check_health()
+
+ if (src.health < ROCKBOX_MAX_HEALTH / 1.5)
+ if (prob(66))
+ elecflash(src.loc, 1, 4, 0)
..()
proc/check_health()
- if(!src.health && !broken)
- src.broken = TRUE
+ if(!src.health && !(src.is_broken()))
+ src.status |= BROKEN
src.visible_message(SPAN_ALERT("[src] breaks!"))
src.icon_state = "ore_storage_unit-broken"
+ robogibs(src.loc)
+ playsound(src.loc, src.sound_destroyed, 50, 2)
proc/load_item(var/obj/item/raw_material/R,var/mob/living/user)
if (!R)
@@ -219,7 +263,7 @@
proc/accept_loading(var/mob/user,var/allow_silicon = FALSE)
if (!user)
return 0
- if (src.status & BROKEN || src.status & NOPOWER)
+ if (src.is_disabled())
return 0
if (!istype(user, /mob/living/))
return 0
@@ -329,7 +373,17 @@
return src.loc
+ get_desc(dist, mob/user)
+ . = ..()
+
+ if (src.is_broken())
+ . += SPAN_ALERT("It looks broken and inoperable.")
+
ui_interact(mob/user, datum/tgui/ui)
+ if (src.is_broken())
+ boutput(user, SPAN_ALERT("The [src] seems to be broken and inoperable!"))
+ return
+
ui = tgui_process.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "Rockbox")
@@ -358,6 +412,7 @@
. = ..()
if(.)
return
+
switch(action)
if("dispense-ore")
eject_ores(params["ore"], null, params["take"])
@@ -379,3 +434,4 @@
update_ore_price(ore, price)
. = TRUE
+#undef ROCKBOX_MAX_HEALTH