diff --git a/code/game/dna.dm b/code/game/dna.dm
index e6650118e31..f3e79618e99 100644
--- a/code/game/dna.dm
+++ b/code/game/dna.dm
@@ -340,6 +340,7 @@
var/locked = 0
var/open = 0
anchored = 1
+ interact_offline = 1
use_power = 1
idle_power_usage = 50
active_power_usage = 300
@@ -371,6 +372,29 @@
for(var/obj/item/weapon/stock_parts/micro_laser/P in component_parts)
damage_coeff = P.rating
+/obj/machinery/dna_scannernew/update_icon()
+
+ //no power or maintenance
+ if(stat & (NOPOWER|BROKEN))
+ icon_state = initial(icon_state)+ (open ? "_open" : "") + "_unpowered"
+ return
+
+ if((stat & MAINT) || panel_open)
+ icon_state = initial(icon_state)+ (open ? "_open" : "") + "_maintenance"
+ return
+
+ //running and someone in there
+ if(occupant)
+ icon_state = initial(icon_state)+ "_occupied"
+ return
+
+ //running
+ icon_state = initial(icon_state)+ (open ? "_open" : "")
+
+/obj/machinery/dna_scannernew/power_change()
+ ..()
+ update_icon()
+
/obj/machinery/dna_scannernew/proc/toggle_open(mob/user=usr)
if(!user)
return
@@ -414,7 +438,7 @@
C.loc = src
C.stop_pulling()
break
- icon_state = initial(icon_state) + (occupant ? "_occupied" : "")
+ update_icon()
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
if(occupant)
@@ -451,7 +475,7 @@
occupant.client.eye = occupant
occupant.client.perspective = MOB_PERSPECTIVE
occupant = null
- icon_state = "[initial(icon_state)]_open"
+ update_icon()
return 1
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
@@ -462,7 +486,8 @@
/obj/machinery/dna_scannernew/attackby(obj/item/weapon/grab/G, mob/user)
- if(!occupant && default_deconstruction_screwdriver(user, "[initial(icon_state)]_open", "[initial(icon_state)]", G))
+ if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, G))//sent icon_state is irrelevant...
+ update_icon()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed
return
if(exchange_parts(user, G))
@@ -486,6 +511,8 @@
qdel(G)
/obj/machinery/dna_scannernew/attack_hand(mob/user)
+ if(..())
+ return
toggle_open(user)
add_fingerprint(user)
@@ -578,7 +605,7 @@
var/occupant_status = "
Subject Status:
"
var/scanner_status
var/temp_html
- if(connected)
+ if(connected && connected.is_operational())
if(connected.occupant) //set occupant_status message
viable_occupant = connected.occupant
if(check_dna_integrity(viable_occupant) && (!(NOCLONE in viable_occupant.mutations) || (connected.scan_level == 3))) //occupent is viable for dna modification
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 7e5801c56fe..71275ae4f4b 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -11,8 +11,9 @@
icon_state = "sleeper-open"
density = 0
anchored = 1
- var/efficiency
+ interact_offline = 1
state_open = 1
+ var/efficiency
var/initial_bin_rating = 1
var/min_health = 25
var/list/injection_chems = list() //list of injectable chems except inaprovaline, coz inaprovaline is always avalible
@@ -132,11 +133,17 @@
open_machine()
/obj/machinery/sleeper/attack_hand(mob/user)
- if(stat & (BROKEN|NOPOWER))
+ if(..())
+ return
+
+ //powerless interaction
+ if(!is_operational())
+ user.unset_machine()//essential to prevent infinite loops of opening/closing the machine
if(state_open)
close_machine()
else
open_machine()
+
else
sleeperUI(user)
@@ -233,6 +240,8 @@
..(target)
/obj/machinery/sleeper/proc/inject_chem(mob/user, chem)
+ if(!is_operational())
+ return
if(occupant && occupant.reagents)
if(chem in injection_chems + "inaprovaline")
if(occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index f9c26d959bd..087f1e9d419 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -112,7 +112,7 @@
/obj/machinery/clonepod/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/machinery/clonepod/attack_hand(mob/user as mob)
- if ((isnull(src.occupant)) || (stat & NOPOWER))
+ if (isnull(src.occupant) || !is_operational())
return
if ((!isnull(src.occupant)) && (src.occupant.stat != 2))
var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100)))
@@ -205,7 +205,7 @@
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
- if(stat & NOPOWER) //Autoeject if power is lost
+ if(!is_operational()) //Autoeject if power is lost
if (src.occupant)
src.locked = 0
src.go_out()
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 6fbba86fd4d..5d49b12a1e5 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -54,12 +54,12 @@
// Try to find a scanner in that direction
scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
- // If found, then we break, and return the scanner
- if (!isnull(scannerf))
- break
+ // If found and operational, return the scanner
+ if (!isnull(scannerf) && scannerf.is_operational())
+ return scannerf
// If no scanner was found, it will return null
- return scannerf
+ return null
/obj/machinery/computer/cloning/proc/findcloner()
var/obj/machinery/clonepod/podf = null
@@ -68,10 +68,10 @@
podf = locate(/obj/machinery/clonepod, get_step(src, dir))
- if (!isnull(podf))
- break
+ if (!isnull(podf) && podf.is_operational())
+ return podf
- return podf
+ return null
/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
@@ -233,25 +233,25 @@
if("stopautoprocess")
autoprocess = 0
- else if ((href_list["scan"]) && (!isnull(src.scanner)))
+ else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
scantemp = ""
loading = 1
src.updateUsrDialog()
spawn(20)
- src.scan_mob(src.scanner.occupant)
+ src.scan_mob(scanner.occupant)
loading = 0
src.updateUsrDialog()
//No locking an open scanner.
- else if ((href_list["lock"]) && (!isnull(src.scanner)))
- if ((!src.scanner.locked) && (src.scanner.occupant))
- src.scanner.locked = 1
+ else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational())
+ if ((!scanner.locked) && (scanner.occupant))
+ scanner.locked = 1
else
- src.scanner.locked = 0
+ scanner.locked = 0
else if(href_list["view_rec"])
src.active_record = find_record("id", href_list["view_rec"], records)
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index e5acc1ea5af..4ea9ea6993d 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -4,6 +4,7 @@
icon_state = "cell-off"
density = 1
anchored = 1.0
+ interact_offline = 1
layer = 4
var/on = 0
@@ -45,7 +46,7 @@
/obj/machinery/atmospherics/unary/cryo_cell/process()
..()
- if(!node)
+ if(!node || !is_operational())
return
if(!on)
updateDialog()
@@ -97,11 +98,17 @@
user << "Seems empty."
/obj/machinery/atmospherics/unary/cryo_cell/attack_hand(mob/user)
- if(stat & (NOPOWER|BROKEN))
- if(state_open == 1)
+ if(..())
+ return
+
+ //powerless interaction
+ if(!is_operational())
+ user.unset_machine()//essential to prevent infinite loops of opening/closing the machine
+ if(state_open)
close_machine()
else
open_machine()
+
else
ui_interact(user)
@@ -258,7 +265,7 @@
if(state_open)
icon_state = "cell-open"
return
- if(on)
+ if(on && is_operational())
if(occupant)
icon_state = "cell-occupied"
else
@@ -266,6 +273,9 @@
else
icon_state = "cell-off"
+/obj/machinery/atmospherics/unary/cryo_cell/power_change()
+ ..()
+ update_icon()
/obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant()
if(air_contents.total_moles() < 10)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 44be02fadac..c7e540dcc4b 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -84,6 +84,8 @@ Class Procs:
process() 'game/machinery/machine.dm'
Called by the 'master_controller' once per game tick for each machine that is listed in the 'machines' list.
+ is_operational()
+ Returns 0 if the machine is unpowered, broken or undergoing maintenance, 1 if not
Compiled by Aygar
*/
@@ -209,6 +211,11 @@ Class Procs:
add_fingerprint(usr)
return 0
+/obj/machinery/proc/is_operational()
+ return !(stat & (NOPOWER|BROKEN|MAINT))
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
/mob/proc/canUseTopic() //TODO: once finished, place these procs on the respective mob files
return
diff --git a/icons/obj/Cryogenic2.dmi b/icons/obj/Cryogenic2.dmi
index 80adbbf28aa..1c921a64673 100644
Binary files a/icons/obj/Cryogenic2.dmi and b/icons/obj/Cryogenic2.dmi differ