From 12bc03157a63b6ca1b28eb2c1a8df293e530f8bb Mon Sep 17 00:00:00 2001 From: Leshana Date: Wed, 3 May 2017 01:54:36 -0400 Subject: [PATCH] Adds the Algae Oxygen Generator * 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. --- .../binary_devices/algae_generator_vr.dm | 269 + .../weapons/circuitboards/circuitboards_vr.dm | 12 + code/modules/research/designs_vr.dm | 7 + icons/obj/machines/algae_vr.dmi | Bin 0 -> 1166 bytes maps/tether/tether-1-surface.dmm | 9551 +++++++++-------- nano/templates/algae_farm_vr.tmpl | 63 + vorestation.dme | 1 + 7 files changed, 5135 insertions(+), 4768 deletions(-) create mode 100644 code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm create mode 100644 icons/obj/machines/algae_vr.dmi create mode 100644 nano/templates/algae_farm_vr.tmpl diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm new file mode 100644 index 0000000000..84f84e9cff --- /dev/null +++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm @@ -0,0 +1,269 @@ +#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 << "You cannot insert this item into \the [src]!" + 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 << "\The [src] doesn't accept [material_display_name(S.material)]!" + 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].", "You insert [count] [S.name] into \the [src].") + updateUsrDialog() + else + user << "\The [src] cannot hold more [S.name]." + 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 diff --git a/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm b/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm index 25b2514c34..a41d620cb2 100644 --- a/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm +++ b/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm @@ -14,3 +14,15 @@ /obj/item/weapon/stock_parts/matter_bin = 2, /obj/item/weapon/stock_parts/manipulator = 2, /obj/item/weapon/stock_parts/console_screen = 1) + +// Board for the algae oxygen generator in algae_generator.dm +/obj/item/weapon/circuitboard/algae_farm + name = T_BOARD("algae oxygen generator") + build_path = /obj/machinery/atmospherics/binary/algae_farm + board_type = new /datum/frame/frame_types/machine + origin_tech = list(TECH_ENGINEERING = 3, TECH_BIO = 2) + req_components = list( + /obj/item/weapon/stock_parts/matter_bin = 2, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/capacitor = 1, + /obj/item/weapon/stock_parts/console_screen = 1) diff --git a/code/modules/research/designs_vr.dm b/code/modules/research/designs_vr.dm index 4e5ebe6ca3..07285cf921 100644 --- a/code/modules/research/designs_vr.dm +++ b/code/modules/research/designs_vr.dm @@ -128,3 +128,10 @@ materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 3000) build_path = /obj/item/weapon/gun/energy/netgun sort_string = "TAADF" + +/datum/design/circuit/algae_farm + name = "Algae Oxygen Generator" + id = "algae_farm" + req_tech = list(TECH_ENGINEERING = 3, TECH_BIO = 2) + build_path = /obj/item/weapon/circuitboard/algae_farm + sort_string = "HABAE" diff --git a/icons/obj/machines/algae_vr.dmi b/icons/obj/machines/algae_vr.dmi new file mode 100644 index 0000000000000000000000000000000000000000..37457037ca418d01d7bf987598fb2313e1dc8e88 GIT binary patch literal 1166 zcmeAS@N?(olHy`uVBq!ia0vp^4M3d0!3-oHE$ONTQl$YtA+84w91s>34h|0P>+6e+ zjg^s+iHwZgv}sdkXQ#Zp{MM~oo12@rY}wM*)>hfjymIxXLq|^Dd+@+FBuYw3N>ETx zUtj;Os;vD3$vFy=Cfme}EuD0e)STKaE!RXlpU?HYQ(E6#7Z4g$?B?{Jo8clS!=J|t zpN+JBU%wXsbO2*XkY6x^!?PP{K+f8#kcbkO)Z*l#%z~24{5%GRiaEUjj$DTf1Z>jd z1#e}G3U{09UsAHYVb8KFlWC)-=awJU;mll0O4TzZ)5>n>{#{qJ$RlI$l#rM0rltougT(BmNS?590a>d!b{)ONAe=k|#63eMkdE5N_`a6s(O#(y~ zmbb+-Ffj9Zx;TbpG`^jcJAIacKx=sR+AY&Ibe_5vx^nB6|NoEh>6db<>|E%4Xx?VN z4=?j(R8La4^Zd=_%Tu;S)J5s4?R|XW*PefyJfE3<_ZU8xUlUixo2i!u7BkwUKM>4q8A{2gm%z0cVpvXPfVarWl58T}9MI!yDjY7Md0 zn%ZVQL8bHJfxP|US>gu|q;1|P5m3mJvpxE5!<3RqjG`wGRPDXSE0Z$q{3iBU%i~h? zjeaXi+dt8`7OZewZe zQFx%p^x_g`*Q?*&9Y{#n$RY4|)qKUs_`g*%z1SOu5M&Jz`w)FjNu1k_;8xMbAI+C<(%p}UH^ixbnaEaBm(cOOa$V8#edpg-&Ao73>cr4(*O8#kH!I4*u-e&BwykMXk?239{vd&J(Mzu~8IyZj%skIYBJZ~S5W$h?k^8%VrM zJaB|R@B5dS*X`@#vR+oLm_KX(hghb$@+Z3F@4T|!V`_22epcP8>Kk8*RO&DMWXxT9 zkca1M&}_!bKZ?%qY>C|YU+?54&yxA71)qS1B`cJ|47NMgFcIj%hz=l;!|;K5-Myo+u?_0|M;NHMEzpR9J!zEyrX7F_Nb6Mw< G&;$U