mirror of
https://github.com/Aurorastation/Aurora-Old.git
synced 2026-08-25 21:56:15 +01:00
This changelist allows people to click and drag nearby people into medical machinery. This does not affect the ability to grab and click. This is an enhancement.
358 lines
12 KiB
Plaintext
358 lines
12 KiB
Plaintext
#define HEAT_CAPACITY_HUMAN 100 //249840 J/K, for a 72 kg person.
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell
|
|
name = "cryo cell"
|
|
icon = 'icons/obj/cryogenics.dmi'
|
|
icon_state = "cell-off"
|
|
density = 1
|
|
anchored = 1.0
|
|
layer = 2.8
|
|
interact_offline = 1
|
|
|
|
var/on = 0
|
|
use_power = 1
|
|
idle_power_usage = 20
|
|
active_power_usage = 200
|
|
|
|
var/temperature_archived
|
|
var/mob/living/carbon/occupant = null
|
|
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
|
|
|
var/current_heat_capacity = 50
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/New()
|
|
..()
|
|
initialize_directions = dir
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/initialize()
|
|
if(node) return
|
|
var/node_connect = dir
|
|
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
|
|
if(target.initialize_directions & get_dir(target,src))
|
|
node = target
|
|
break
|
|
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
|
|
if(!allowed_to_add_this_person_to_a_medical_machine(O,user,src,occupant))
|
|
return
|
|
var/mob/living/L = O
|
|
if(put_mob(L))
|
|
if(L == user)
|
|
visible_message("[user] climbs into the cryo cell.", 3)
|
|
else
|
|
visible_message("[user] puts [L.name] into the cryo cell.", 3)
|
|
if(user.pulling == L)
|
|
user.pulling = null
|
|
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/process()
|
|
..()
|
|
if(!node)
|
|
return
|
|
if(!on)
|
|
updateUsrDialog()
|
|
return
|
|
|
|
if(occupant)
|
|
if(occupant.stat != 2)
|
|
process_occupant()
|
|
|
|
if(air_contents)
|
|
temperature_archived = air_contents.temperature
|
|
heat_gas_contents()
|
|
expel_gas()
|
|
|
|
if(abs(temperature_archived-air_contents.temperature) > 1)
|
|
network.update = 1
|
|
|
|
updateUsrDialog()
|
|
return 1
|
|
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/allow_drop()
|
|
return 0
|
|
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob)
|
|
if(user.stat)
|
|
return
|
|
go_out()
|
|
return
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/attack_hand(mob/user)
|
|
ui_interact(user)
|
|
|
|
/**
|
|
* The ui_interact proc is used to open and update Nano UIs
|
|
* If ui_interact is not used then the UI will not update correctly
|
|
* ui_interact is currently defined for /atom/movable (which is inherited by /obj and /mob)
|
|
*
|
|
* @param user /mob The mob who is interacting with this ui
|
|
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
|
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
|
*
|
|
* @return nothing
|
|
*/
|
|
/obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
|
|
|
if(user == occupant || user.stat)
|
|
return
|
|
|
|
// this is the data which will be sent to the ui
|
|
var/data[0]
|
|
data["isOperating"] = on
|
|
data["hasOccupant"] = occupant ? 1 : 0
|
|
|
|
var/occupantData[0]
|
|
if (occupant)
|
|
occupantData["name"] = occupant.name
|
|
occupantData["stat"] = occupant.stat
|
|
occupantData["health"] = occupant.health
|
|
occupantData["maxHealth"] = occupant.maxHealth
|
|
occupantData["minHealth"] = config.health_threshold_dead
|
|
occupantData["bruteLoss"] = occupant.getBruteLoss()
|
|
occupantData["oxyLoss"] = occupant.getOxyLoss()
|
|
occupantData["toxLoss"] = occupant.getToxLoss()
|
|
occupantData["fireLoss"] = occupant.getFireLoss()
|
|
occupantData["bodyTemperature"] = occupant.bodytemperature
|
|
data["occupant"] = occupantData;
|
|
|
|
data["cellTemperature"] = round(air_contents.temperature)
|
|
data["cellTemperatureStatus"] = "good"
|
|
if(air_contents.temperature > T0C) // if greater than 273.15 kelvin (0 celcius)
|
|
data["cellTemperatureStatus"] = "bad"
|
|
else if(air_contents.temperature > 225)
|
|
data["cellTemperatureStatus"] = "average"
|
|
|
|
data["isBeakerLoaded"] = beaker ? 1 : 0
|
|
/* // Removing beaker contents list from front-end, replacing with a total remaining volume
|
|
var beakerContents[0]
|
|
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
|
|
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
|
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
|
data["beakerContents"] = beakerContents
|
|
*/
|
|
data["beakerLabel"] = null
|
|
data["beakerVolume"] = 0
|
|
if(beaker)
|
|
data["beakerLabel"] = beaker.label_text ? beaker.label_text : null
|
|
if (beaker.reagents && beaker.reagents.reagent_list.len)
|
|
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
|
data["beakerVolume"] += R.volume
|
|
|
|
// update the ui if it exists, returns null if no ui is passed/found
|
|
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
if (!ui)
|
|
// the ui does not exist, so we'll create a new() one
|
|
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
|
ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 410)
|
|
// when the ui is first opened this is the data it will use
|
|
ui.set_initial_data(data)
|
|
// open the new ui window
|
|
ui.open()
|
|
// auto update every Master Controller tick
|
|
ui.set_auto_update(1)
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/Topic(href, href_list)
|
|
if(usr == occupant)
|
|
return 0 // don't update UIs attached to this object
|
|
|
|
if(..())
|
|
return 0 // don't update UIs attached to this object
|
|
|
|
if(href_list["switchOn"])
|
|
on = 1
|
|
update_icon()
|
|
|
|
if(href_list["switchOff"])
|
|
on = 0
|
|
update_icon()
|
|
|
|
if(href_list["ejectBeaker"])
|
|
if(beaker)
|
|
beaker.loc = get_step(loc, SOUTH)
|
|
beaker = null
|
|
|
|
if(href_list["ejectOccupant"])
|
|
if(!occupant || isslime(usr) || ispAI(usr))
|
|
return 0 // don't update UIs attached to this object
|
|
go_out()
|
|
|
|
add_fingerprint(usr)
|
|
return 1 // update UIs attached to this object
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
|
|
if(istype(G, /obj/item/weapon/reagent_containers/glass))
|
|
if(beaker)
|
|
user << "\red A beaker is already loaded into the machine."
|
|
return
|
|
|
|
beaker = G
|
|
user.drop_item()
|
|
G.loc = src
|
|
user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!")
|
|
else if(istype(G, /obj/item/weapon/grab))
|
|
if(!ismob(G:affecting))
|
|
return
|
|
for(var/mob/living/carbon/slime/M in range(1,G:affecting))
|
|
if(M.Victim == G:affecting)
|
|
usr << "[G:affecting:name] will not fit into the cryo because they have a slime latched onto their head."
|
|
return
|
|
var/mob/M = G:affecting
|
|
if(put_mob(M))
|
|
del(G)
|
|
updateUsrDialog()
|
|
return
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/update_icon()
|
|
if(on)
|
|
if(occupant)
|
|
icon_state = "cell-occupied"
|
|
return
|
|
icon_state = "cell-on"
|
|
return
|
|
icon_state = "cell-off"
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant()
|
|
if(air_contents.total_moles < 10)
|
|
return
|
|
if(occupant)
|
|
if(occupant.stat == 2)
|
|
return
|
|
occupant.bodytemperature += 2*(air_contents.temperature - occupant.bodytemperature)*current_heat_capacity/(current_heat_capacity + air_contents.heat_capacity())
|
|
occupant.bodytemperature = max(occupant.bodytemperature, air_contents.temperature) // this is so ugly i'm sorry for doing it i'll fix it later i promise
|
|
occupant.stat = 1
|
|
if(occupant.bodytemperature < T0C)
|
|
occupant.sleeping = max(5, (1/occupant.bodytemperature)*2000)
|
|
occupant.Paralyse(max(5, (1/occupant.bodytemperature)*3000))
|
|
if(air_contents.gas["oxygen"] > 2)
|
|
if(occupant.getOxyLoss()) occupant.adjustOxyLoss(-1)
|
|
else
|
|
occupant.adjustOxyLoss(-1)
|
|
//severe damage should heal waaay slower without proper chemicals
|
|
if(occupant.bodytemperature < 225)
|
|
if (occupant.getToxLoss())
|
|
occupant.adjustToxLoss(max(-1, -20/occupant.getToxLoss()))
|
|
var/heal_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0
|
|
var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0
|
|
occupant.heal_organ_damage(heal_brute,heal_fire)
|
|
var/has_cryo = occupant.reagents.get_reagent_amount("cryoxadone") >= 1
|
|
var/has_clonexa = occupant.reagents.get_reagent_amount("clonexadone") >= 1
|
|
var/has_cryo_medicine = has_cryo || has_clonexa
|
|
if(beaker && !has_cryo_medicine)
|
|
beaker.reagents.trans_to(occupant, 1, 10)
|
|
beaker.reagents.reaction(occupant)
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents()
|
|
if(air_contents.total_moles < 1)
|
|
return
|
|
var/air_heat_capacity = air_contents.heat_capacity()
|
|
var/combined_heat_capacity = current_heat_capacity + air_heat_capacity
|
|
if(combined_heat_capacity > 0)
|
|
var/combined_energy = T20C*current_heat_capacity + air_heat_capacity*air_contents.temperature
|
|
air_contents.temperature = combined_energy/combined_heat_capacity
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/proc/expel_gas()
|
|
if(air_contents.total_moles < 1)
|
|
return
|
|
// var/datum/gas_mixture/expel_gas = new
|
|
// var/remove_amount = air_contents.total_moles()/50
|
|
// expel_gas = air_contents.remove(remove_amount)
|
|
|
|
// Just have the gas disappear to nowhere.
|
|
//expel_gas.temperature = T20C // Lets expel hot gas and see if that helps people not die as they are removed
|
|
//loc.assume_air(expel_gas)
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/proc/go_out()
|
|
if(!( occupant ))
|
|
return
|
|
//for(var/obj/O in src)
|
|
// O.loc = loc
|
|
if (occupant.client)
|
|
occupant.client.eye = occupant.client.mob
|
|
occupant.client.perspective = MOB_PERSPECTIVE
|
|
occupant.loc = get_step(loc, SOUTH) //this doesn't account for walls or anything, but i don't forsee that being a problem.
|
|
if (occupant.bodytemperature < 261 && occupant.bodytemperature >= 70) //Patch by Aranclanos to stop people from taking burn damage after being ejected
|
|
occupant.bodytemperature = 261 // Changed to 70 from 140 by Zuhayr due to reoccurance of bug.
|
|
// occupant.metabslow = 0
|
|
occupant = null
|
|
current_heat_capacity = initial(current_heat_capacity)
|
|
update_use_power(1)
|
|
update_icon()
|
|
return
|
|
/obj/machinery/atmospherics/unary/cryo_cell/proc/put_mob(mob/living/carbon/M as mob)
|
|
if (stat & (NOPOWER|BROKEN))
|
|
usr << "\red The cryo cell is not functioning."
|
|
return
|
|
if (!istype(M))
|
|
usr << "\red <B>The cryo cell cannot handle such a lifeform!</B>"
|
|
return
|
|
if (occupant)
|
|
usr << "\red <B>The cryo cell is already occupied!</B>"
|
|
return
|
|
if (M.abiotic())
|
|
usr << "\red Subject may not have abiotic items on."
|
|
return
|
|
if(!node)
|
|
usr << "\red The cell is not correctly connected to its pipe network!"
|
|
return
|
|
if (M.client)
|
|
M.client.perspective = EYE_PERSPECTIVE
|
|
M.client.eye = src
|
|
M.stop_pulling()
|
|
M.loc = src
|
|
if(M.health > -100 && (M.health < 0 || M.sleeping))
|
|
M << "\blue <b>You feel a cold liquid surround you. Your skin starts to freeze up.</b>"
|
|
occupant = M
|
|
current_heat_capacity = HEAT_CAPACITY_HUMAN
|
|
update_use_power(2)
|
|
// M.metabslow = 1
|
|
M.ExtinguishMob()
|
|
add_fingerprint(usr)
|
|
update_icon()
|
|
return 1
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/verb/move_eject()
|
|
set name = "Eject occupant"
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
if(usr == occupant)//If the user is inside the tube...
|
|
if (usr.stat == 2)//and he's not dead....
|
|
return
|
|
usr << "\blue Release sequence activated. This will take two minutes."
|
|
sleep(1200)
|
|
if(!src || !usr || !occupant || (occupant != usr)) //Check if someone's released/replaced/bombed him already
|
|
return
|
|
go_out()//and release him from the eternal prison.
|
|
else
|
|
if (usr.stat != 0)
|
|
return
|
|
go_out()
|
|
add_fingerprint(usr)
|
|
return
|
|
|
|
/obj/machinery/atmospherics/unary/cryo_cell/verb/move_inside()
|
|
set name = "Move Inside"
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
for(var/mob/living/carbon/slime/M in range(1,usr))
|
|
if(M.Victim == usr)
|
|
usr << "You're too busy getting your life sucked out of you."
|
|
return
|
|
if (usr.stat != 0)
|
|
return
|
|
put_mob(usr)
|
|
return
|
|
|
|
|
|
|
|
/datum/data/function/proc/reset()
|
|
return
|
|
|
|
/datum/data/function/proc/r_input(href, href_list, mob/user as mob)
|
|
return
|
|
|
|
/datum/data/function/proc/display()
|
|
return
|