mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
* This device converts CO2 to O2 using power and "algae". The extra carbon is a byproduct in the form of "graphite" * This is intended for virgo3b, which has no oxygen in its atmosphere but enough CO2 for us to just extract it.
270 lines
9.1 KiB
Plaintext
270 lines
9.1 KiB
Plaintext
#define MATERIAL_ALGAE "algae"
|
|
#define MATERIAL_CARBON "carbon"
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm
|
|
name = "algae oxygen generator"
|
|
desc = "An oxygen generator using algae to convert carbon dioxide to oxygen."
|
|
icon = 'icons/obj/machines/algae_vr.dmi'
|
|
icon_state = "algae-off"
|
|
circuit = /obj/item/weapon/circuitboard/algae_farm
|
|
anchored = 1
|
|
density = 1
|
|
use_power = 2
|
|
idle_power_usage = 100 // Minimal lights to keep algae alive
|
|
active_power_usage = 5000 // Powerful grow lights to stimulate oxygen production
|
|
//power_rating = 7500 //7500 W ~ 10 HP
|
|
|
|
var/list/stored_material = list(MATERIAL_ALGAE = 10000, MATERIAL_CARBON = 0)
|
|
// Capacity increases with matter bin quality
|
|
var/list/storage_capacity = list(MATERIAL_ALGAE = 10000, MATERIAL_CARBON = 10000)
|
|
// Speed at which we convert CO2 to O2. Increases with manipulator quality
|
|
var/moles_per_tick = 1
|
|
// Power required to convert one mole of CO2 to O2 (this is powering the grow lights). Improves with capacitors
|
|
var/power_per_mole = 1000
|
|
var/algae_per_mole = 2
|
|
var/carbon_per_mole = 2
|
|
|
|
var/recent_power_used = 0
|
|
var/recent_moles_transferred = 0
|
|
var/ui_error = null // For error messages to show up in nano ui.
|
|
|
|
var/datum/gas_mixture/internal = new()
|
|
var/const/input_gas = "carbon_dioxide"
|
|
var/const/output_gas = "oxygen"
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/New()
|
|
..()
|
|
desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]."
|
|
default_apply_parts()
|
|
update_icon()
|
|
// TODO - Make these in acutal icon states so its not silly like this
|
|
var/image/I = image(icon = icon, icon_state = "algae-pipe-overlay", dir = dir)
|
|
I.color = PIPE_COLOR_BLUE
|
|
overlays += I
|
|
I = image(icon = icon, icon_state = "algae-pipe-overlay", dir = reverse_dir[dir])
|
|
I.color = PIPE_COLOR_BLACK
|
|
overlays += I
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/Destroy()
|
|
..()
|
|
internal = null
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/process()
|
|
..()
|
|
recent_moles_transferred = 0
|
|
|
|
if(inoperable() || use_power < 2)
|
|
return 0
|
|
|
|
// STEP 1 - Check material resources
|
|
if(stored_material[MATERIAL_ALGAE] < algae_per_mole)
|
|
ui_error = "Insufficient [material_display_name(MATERIAL_ALGAE)] to process."
|
|
return
|
|
if(stored_material[MATERIAL_CARBON] + carbon_per_mole > storage_capacity[MATERIAL_CARBON])
|
|
ui_error = "[material_display_name(MATERIAL_CARBON)] output storage is full."
|
|
return
|
|
var/moles_to_convert = min(moles_per_tick,\
|
|
stored_material[MATERIAL_ALGAE] * algae_per_mole,\
|
|
storage_capacity[MATERIAL_CARBON] - stored_material[MATERIAL_CARBON] * carbon_per_mole)
|
|
|
|
// STEP 2 - Take the CO2 out of the input!
|
|
var/power_draw = scrub_gas(src, list(input_gas), air1, internal, moles_to_convert)
|
|
network1.update = 1
|
|
if (power_draw > 0)
|
|
use_power(power_draw)
|
|
last_power_draw += power_draw
|
|
|
|
// STEP 3 - Convert CO2 to O2 (Note: We know our internal group multipier is 1, so just be cool)
|
|
var/co2_moles = internal.gas[input_gas]
|
|
if(co2_moles < MINIMUM_MOLES_TO_FILTER)
|
|
ui_error = "Insufficient [gas_data.name[input_gas]] to process."
|
|
return
|
|
|
|
// STEP 4 - Consume the resources
|
|
var/converted_moles = min(co2_moles, moles_per_tick)
|
|
use_power(converted_moles * power_per_mole)
|
|
last_power_draw += converted_moles * power_per_mole
|
|
stored_material[MATERIAL_ALGAE] -= converted_moles * algae_per_mole
|
|
stored_material[MATERIAL_CARBON] += converted_moles * carbon_per_mole
|
|
|
|
// STEP 5 - Output the converted oxygen. Fow now we output for free!
|
|
internal.adjust_gas(input_gas, -converted_moles)
|
|
air2.adjust_gas_temp(output_gas, converted_moles, internal.temperature)
|
|
network2.update = 1
|
|
recent_moles_transferred = converted_moles
|
|
ui_error = null // Success!
|
|
update_icon()
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/update_icon()
|
|
if(inoperable() || !anchored)
|
|
icon_state = "algae-off"
|
|
else if(recent_moles_transferred >= moles_per_tick)
|
|
icon_state = "aglae-full"
|
|
else if(recent_moles_transferred > 0)
|
|
icon_state = "algae-full"
|
|
else
|
|
icon_state = "algae-on"
|
|
return 1
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
|
src.add_fingerprint(user)
|
|
if(default_deconstruction_screwdriver(user, W))
|
|
return
|
|
if(default_deconstruction_crowbar(user, W))
|
|
return
|
|
if(try_load_materials(user, W))
|
|
return
|
|
else
|
|
user << "<span class='notice'>You cannot insert this item into \the [src]!</span>"
|
|
return
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/attack_hand(mob/user)
|
|
if(..()) return 1
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state)
|
|
var/data[0]
|
|
data["panelOpen"] = panel_open
|
|
|
|
var/materials_ui[0]
|
|
for(var/M in stored_material)
|
|
materials_ui[++materials_ui.len] = list(
|
|
"name" = M,
|
|
"display" = material_display_name(M),
|
|
"qty" = stored_material[M],
|
|
"max" = storage_capacity[M],
|
|
"percent" = (stored_material[M] / storage_capacity[M] * 100))
|
|
data["materials"] = materials_ui
|
|
data["last_flow_rate"] = last_flow_rate
|
|
data["last_power_draw"] = last_power_draw
|
|
data["inputDir"] = dir2text(reverse_dir[dir])
|
|
data["outputDir"] = dir2text(dir)
|
|
data["usePower"] = use_power
|
|
data["errorText"] = ui_error
|
|
|
|
if(air1 && network1 && node1)
|
|
data["input"] = list(
|
|
"pressure" = air1.return_pressure(),
|
|
"name" = gas_data.name[input_gas],
|
|
"percent" = air1.total_moles > 0 ? round((air1.gas[input_gas] / air1.total_moles) * 100) : 0,
|
|
"moles" = round(air1.gas[input_gas], 0.01))
|
|
if(air2 && network2 && node2)
|
|
data["output"] = list(
|
|
"pressure" = air2.return_pressure(),
|
|
"name" = gas_data.name[output_gas],
|
|
"percent" = air2.total_moles ? round((air2.gas[output_gas] / air2.total_moles) * 100) : 0,
|
|
"moles" = round(air2.gas[output_gas], 0.01))
|
|
|
|
// 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)
|
|
ui = new(user, src, ui_key, "algae_farm_vr.tmpl", "Algae Farm Control Panel", 500, 600)
|
|
ui.set_initial_data(data)
|
|
ui.set_auto_update(TRUE)
|
|
ui.open()
|
|
|
|
/obj/machinery/atmospherics/binary/algae_farm/Topic(href, href_list)
|
|
if(..())
|
|
return 1
|
|
usr.set_machine(src)
|
|
add_fingerprint(usr)
|
|
|
|
// Queue management can be done even while busy
|
|
if(href_list["activate"])
|
|
update_use_power(2)
|
|
update_icon()
|
|
updateUsrDialog()
|
|
return
|
|
|
|
if(href_list["deactivate"])
|
|
update_use_power(1)
|
|
update_icon()
|
|
updateUsrDialog()
|
|
return
|
|
|
|
if(href_list["ejectMaterial"])
|
|
var/matName = href_list["ejectMaterial"]
|
|
if(!(matName in stored_material))
|
|
return
|
|
eject_materials(matName, 0)
|
|
updateUsrDialog()
|
|
return
|
|
|
|
|
|
// TODO - These should be replaced with materials datum.
|
|
|
|
// 0 amount = 0 means ejecting a full stack; -1 means eject everything
|
|
/obj/machinery/atmospherics/binary/algae_farm/proc/eject_materials(var/material_name, var/amount)
|
|
var/recursive = amount == -1 ? 1 : 0
|
|
var/material/matdata = get_material_by_name(material_name)
|
|
var/stack_type = matdata.stack_type
|
|
var/obj/item/stack/material/S = new stack_type(loc)
|
|
if(amount <= 0)
|
|
amount = S.max_amount
|
|
var/ejected = min(round(stored_material[material_name] / S.perunit), amount)
|
|
S.amount = min(ejected, amount)
|
|
if(S.amount <= 0)
|
|
qdel(S)
|
|
return
|
|
stored_material[material_name] -= ejected * S.perunit
|
|
if(recursive && stored_material[material_name] >= S.perunit)
|
|
eject_materials(material_name, -1)
|
|
|
|
// Attept to load materials. Returns 0 if item wasn't a stack of materials, otherwise 1 (even if failed to load)
|
|
/obj/machinery/atmospherics/binary/algae_farm/proc/try_load_materials(var/mob/user, var/obj/item/stack/material/S)
|
|
if(!istype(S))
|
|
return 0
|
|
if(!(S.material.name in stored_material))
|
|
user << "<span class='warning'>\The [src] doesn't accept [material_display_name(S.material)]!</span>"
|
|
return 1
|
|
var/max_res_amount = storage_capacity[S.material.name]
|
|
if(stored_material[S.material.name] + S.perunit <= max_res_amount)
|
|
var/count = 0
|
|
while(stored_material[S.material.name] + S.perunit <= max_res_amount && S.amount >= 1)
|
|
stored_material[S.material.name] += S.perunit
|
|
S.use(1)
|
|
count++
|
|
user.visible_message("\The [user] inserts [S.name] into \the [src].", "<span class='notice'>You insert [count] [S.name] into \the [src].</span>")
|
|
updateUsrDialog()
|
|
else
|
|
user << "<span class='warning'>\The [src] cannot hold more [S.name].</span>"
|
|
return 1
|
|
|
|
/material/algae
|
|
name = MATERIAL_ALGAE
|
|
stack_type = /obj/item/stack/material/algae
|
|
icon_colour = "#557722"
|
|
shard_type = SHARD_STONE_PIECE
|
|
weight = 10
|
|
hardness = 10
|
|
sheet_singular_name = "sheet"
|
|
sheet_plural_name = "sheets"
|
|
|
|
/obj/item/stack/material/algae
|
|
name = "algae sheet"
|
|
icon_state = "sheet-uranium"
|
|
color = "#557722"
|
|
default_type = MATERIAL_ALGAE
|
|
|
|
/material/carbon
|
|
name = MATERIAL_CARBON
|
|
stack_type = /obj/item/stack/material/carbon
|
|
icon_colour = "#303030"
|
|
shard_type = SHARD_SPLINTER
|
|
weight = 5
|
|
hardness = 20
|
|
icon_base = "stone"
|
|
icon_reinf = "reinf_stone"
|
|
door_icon_base = "stone"
|
|
sheet_singular_name = "sheet"
|
|
sheet_plural_name = "sheets"
|
|
|
|
/obj/item/stack/material/carbon
|
|
name = "carbon sheet"
|
|
icon_state = "sheet-metal"
|
|
color = "#303030"
|
|
default_type = MATERIAL_CARBON
|
|
|
|
#undef MATERIAL_ALGAE
|
|
#undef MATERIAL_CARBON
|