* Prevent being able to open/close sleepers, cryo tubes and DNA scanners when in various conditions (weaken, ...) and by non-humans/non-silicons.

* Fixes possibles infinite loops runtime (#5527)

* Added icon updating on power changes/maintenance to Cryo Tubes and DNA Scanners
* Unpowered DNA Scanners can no longer be used if the associated computer is powered

* Cryo cells and sleepers won't work when powerless anymore

* Added an "is_operational" proc to machinery instead of duplicating the same check over and over.
* Cloning pods and DNA Scanners used by cloning computers won't work if powerless/broken/maintenance anymore.

Added an unpowered sprite for DNA Scanners, courtesy of Nienhaus
This commit is contained in:
Menshin
2014-11-01 21:52:54 +01:00
parent 8f9d22b7a8
commit 73e642762f
7 changed files with 78 additions and 25 deletions
+31 -4
View File
@@ -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 = "<div class='line'><div class='statusLabel'>Subject Status:</div><div class='statusValue'>"
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
+11 -2
View File
@@ -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)
+2 -2
View File
@@ -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()
+13 -13
View File
@@ -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)
+14 -4
View File
@@ -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)
+7
View File
@@ -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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 53 KiB