Files
CHOMPStation2/code/game/machinery/atmoalter/canister.dm
2015-07-18 23:56:10 +03:00

434 lines
13 KiB
Plaintext

/obj/machinery/portable_atmospherics/canister
name = "canister"
icon = 'icons/obj/atmos.dmi'
icon_state = "yellow"
density = 1
var/health = 100.0
flags = CONDUCT
var/valve_open = 0
var/release_pressure = ONE_ATMOSPHERE
var/release_flow_rate = ATMOS_DEFAULT_VOLUME_PUMP //in L/s
var/canister_color = "yellow"
var/can_label = 1
start_pressure = 45 * ONE_ATMOSPHERE
pressure_resistance = 7 * ONE_ATMOSPHERE
var/temperature_resistance = 1000 + T0C
volume = 1000
use_power = 0
var/release_log = ""
var/update_flag = 0
/obj/machinery/portable_atmospherics/canister/drain_power()
return -1
/obj/machinery/portable_atmospherics/canister/sleeping_agent
name = "Canister: \[N2O\]"
icon_state = "redws"
canister_color = "redws"
can_label = 0
/obj/machinery/portable_atmospherics/canister/nitrogen
name = "Canister: \[N2\]"
icon_state = "red"
canister_color = "red"
can_label = 0
/obj/machinery/portable_atmospherics/canister/oxygen
name = "Canister: \[O2\]"
icon_state = "blue"
canister_color = "blue"
can_label = 0
/obj/machinery/portable_atmospherics/canister/oxygen/prechilled
name = "Canister: \[O2 (Cryo)\]"
/obj/machinery/portable_atmospherics/canister/phoron
name = "Canister \[Phoron\]"
icon_state = "orange"
canister_color = "orange"
can_label = 0
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
name = "Canister \[CO2\]"
icon_state = "black"
canister_color = "black"
can_label = 0
/obj/machinery/portable_atmospherics/canister/air
name = "Canister \[Air\]"
icon_state = "grey"
canister_color = "grey"
can_label = 0
/obj/machinery/portable_atmospherics/canister/air/airlock
start_pressure = 3 * ONE_ATMOSPHERE
/obj/machinery/portable_atmospherics/canister/empty/
start_pressure = 0
can_label = 1
/obj/machinery/portable_atmospherics/canister/empty/oxygen
name = "Canister: \[O2\]"
icon_state = "blue"
canister_color = "blue"
/obj/machinery/portable_atmospherics/canister/empty/phoron
name = "Canister \[Phoron\]"
icon_state = "orange"
canister_color = "orange"
/obj/machinery/portable_atmospherics/canister/empty/nitrogen
name = "Canister \[N2\]"
icon_state = "red"
canister_color = "red"
/obj/machinery/portable_atmospherics/canister/empty/carbon_dioxide
name = "Canister \[CO2\]"
icon_state = "black"
canister_color = "black"
/obj/machinery/portable_atmospherics/canister/empty/sleeping_agent
name = "Canister \[N2O\]"
icon_state = "redws"
canister_color = "redws"
/obj/machinery/portable_atmospherics/canister/proc/check_change()
var/old_flag = update_flag
update_flag = 0
if(holding)
update_flag |= 1
if(connected_port)
update_flag |= 2
var/tank_pressure = air_contents.return_pressure()
if(tank_pressure < 10)
update_flag |= 4
else if(tank_pressure < ONE_ATMOSPHERE)
update_flag |= 8
else if(tank_pressure < 15*ONE_ATMOSPHERE)
update_flag |= 16
else
update_flag |= 32
if(update_flag == old_flag)
return 1
else
return 0
/obj/machinery/portable_atmospherics/canister/update_icon()
/*
update_flag
1 = holding
2 = connected_port
4 = tank_pressure < 10
8 = tank_pressure < ONE_ATMOS
16 = tank_pressure < 15*ONE_ATMOS
32 = tank_pressure go boom.
*/
if (src.destroyed)
src.overlays = 0
src.icon_state = text("[]-1", src.canister_color)
return
if(icon_state != "[canister_color]")
icon_state = "[canister_color]"
if(check_change()) //Returns 1 if no change needed to icons.
return
src.overlays = 0
if(update_flag & 1)
overlays += "can-open"
if(update_flag & 2)
overlays += "can-connector"
if(update_flag & 4)
overlays += "can-o0"
if(update_flag & 8)
overlays += "can-o1"
else if(update_flag & 16)
overlays += "can-o2"
else if(update_flag & 32)
overlays += "can-o3"
return
/obj/machinery/portable_atmospherics/canister/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > temperature_resistance)
health -= 5
healthcheck()
/obj/machinery/portable_atmospherics/canister/proc/healthcheck()
if(destroyed)
return 1
if (src.health <= 10)
var/atom/location = src.loc
location.assume_air(air_contents)
src.destroyed = 1
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
src.density = 0
update_icon()
if (src.holding)
src.holding.loc = src.loc
src.holding = null
return 1
else
return 1
/obj/machinery/portable_atmospherics/canister/process()
if (destroyed)
return
..()
if(valve_open)
var/datum/gas_mixture/environment
if(holding)
environment = holding.air_contents
else
environment = loc.return_air()
var/env_pressure = environment.return_pressure()
var/pressure_delta = release_pressure - env_pressure
if((air_contents.temperature > 0) && (pressure_delta > 0))
var/transfer_moles = calculate_transfer_moles(air_contents, environment, pressure_delta)
transfer_moles = min(transfer_moles, (release_flow_rate/air_contents.volume)*air_contents.total_moles) //flow rate limit
var/returnval = pump_gas_passive(src, air_contents, environment, transfer_moles)
if(returnval >= 0)
src.update_icon()
if(air_contents.return_pressure() < 1)
can_label = 1
else
can_label = 0
air_contents.react() //cooking up air cans - add phoron and oxygen, then heat above PHORON_MINIMUM_BURN_TEMPERATURE
/obj/machinery/portable_atmospherics/canister/return_air()
return air_contents
/obj/machinery/portable_atmospherics/canister/proc/return_temperature()
var/datum/gas_mixture/GM = src.return_air()
if(GM && GM.volume>0)
return GM.temperature
return 0
/obj/machinery/portable_atmospherics/canister/proc/return_pressure()
var/datum/gas_mixture/GM = src.return_air()
if(GM && GM.volume>0)
return GM.return_pressure()
return 0
/obj/machinery/portable_atmospherics/canister/blob_act()
src.health -= 200
healthcheck()
return
/obj/machinery/portable_atmospherics/canister/bullet_act(var/obj/item/projectile/Proj)
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
return
if(Proj.damage)
src.health -= round(Proj.damage / 2)
healthcheck()
..()
/obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if(!istype(W, /obj/item/weapon/wrench) && !istype(W, /obj/item/weapon/tank) && !istype(W, /obj/item/device/analyzer) && !istype(W, /obj/item/device/pda))
visible_message("<span class='warning'>\The [user] hits \the [src] with \a [W]!</span>")
src.health -= W.force
src.add_fingerprint(user)
healthcheck()
if(istype(user, /mob/living/silicon/robot) && istype(W, /obj/item/weapon/tank/jetpack))
var/datum/gas_mixture/thejetpack = W:air_contents
var/env_pressure = thejetpack.return_pressure()
var/pressure_delta = min(10*ONE_ATMOSPHERE - env_pressure, (air_contents.return_pressure() - env_pressure)/2)
//Can not have a pressure delta that would cause environment pressure > tank pressure
var/transfer_moles = 0
if((air_contents.temperature > 0) && (pressure_delta > 0))
transfer_moles = pressure_delta*thejetpack.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)//Actually transfer the gas
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
thejetpack.merge(removed)
user << "You pulse-pressurize your jetpack from the tank."
return
..()
nanomanager.update_uis(src) // Update all NanoUIs attached to src
/obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/portable_atmospherics/canister/attack_hand(var/mob/user as mob)
return src.ui_interact(user)
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if (src.destroyed)
return
// this is the data which will be sent to the ui
var/data[0]
data["name"] = name
data["canLabel"] = can_label ? 1 : 0
data["portConnected"] = connected_port ? 1 : 0
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["releasePressure"] = round(release_pressure ? release_pressure : 0)
data["minReleasePressure"] = round(ONE_ATMOSPHERE/10)
data["maxReleasePressure"] = round(10*ONE_ATMOSPHERE)
data["valveOpen"] = valve_open ? 1 : 0
data["hasHoldingTank"] = holding ? 1 : 0
if (holding)
data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure()))
// 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, "canister.tmpl", "Canister", 480, 400)
// 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/portable_atmospherics/canister/Topic(href, href_list)
//Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. // yeah but without SOME sort of Topic check any dick can mess with them via exploits as he pleases -walter0o
//First comment might be outdated.
if (!istype(src.loc, /turf))
return 0
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) // exploit protection -walter0o
usr << browse(null, "window=canister")
onclose(usr, "canister")
return
if(href_list["toggle"])
if (valve_open)
if (holding)
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the [holding]<br>"
else
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the <font color='red'><b>air</b></font><br>"
else
if (holding)
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the [holding]<br>"
else
release_log += "Valve was <b>opened</b> by [usr] ([usr.ckey]), starting the transfer into the <font color='red'><b>air</b></font><br>"
log_open()
valve_open = !valve_open
if (href_list["remove_tank"])
if(holding)
if (valve_open)
valve_open = 0
release_log += "Valve was <b>closed</b> by [usr] ([usr.ckey]), stopping the transfer into the [holding]<br>"
if(istype(holding, /obj/item/weapon/tank))
holding.manipulated_by = usr.real_name
holding.loc = loc
holding = null
if (href_list["pressure_adj"])
var/diff = text2num(href_list["pressure_adj"])
if(diff > 0)
release_pressure = min(10*ONE_ATMOSPHERE, release_pressure+diff)
else
release_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff)
if (href_list["relabel"])
if (can_label)
var/list/colors = list(\
"\[N2O\]" = "redws", \
"\[N2\]" = "red", \
"\[O2\]" = "blue", \
"\[Phoron\]" = "orange", \
"\[CO2\]" = "black", \
"\[Air\]" = "grey", \
"\[CAUTION\]" = "yellow", \
)
var/label = input("Choose canister label", "Gas canister") as null|anything in colors
if (label)
src.canister_color = colors[label]
src.icon_state = colors[label]
src.name = "Canister: [label]"
src.add_fingerprint(usr)
update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/phoron/New()
..()
src.air_contents.adjust_gas("phoron", MolesForPressure())
src.update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/oxygen/New()
..()
src.air_contents.adjust_gas("oxygen", MolesForPressure())
src.update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/oxygen/prechilled/New()
..()
src.air_contents.adjust_gas("oxygen", MolesForPressure())
src.air_contents.temperature = 80
src.update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/sleeping_agent/New()
..()
air_contents.adjust_gas("sleeping_agent", MolesForPressure())
src.update_icon()
return 1
//Dirty way to fill room with gas. However it is a bit easier to do than creating some floor/engine/n2o -rastaf0
/obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller/New()
..()
air_contents.gas["sleeping_agent"] = 9*4000
spawn(10)
var/turf/simulated/location = src.loc
if (istype(src.loc))
while (!location.air)
sleep(10)
location.assume_air(air_contents)
air_contents = new
return 1
/obj/machinery/portable_atmospherics/canister/nitrogen/New()
..()
src.air_contents.adjust_gas("nitrogen", MolesForPressure())
src.update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/carbon_dioxide/New()
..()
src.air_contents.adjust_gas("carbon_dioxide", MolesForPressure())
src.update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/air/New()
..()
var/list/air_mix = StandardAirMix()
src.air_contents.adjust_multi("oxygen", air_mix["oxygen"], "nitrogen", air_mix["nitrogen"])
src.update_icon()
return 1