diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index dbaaf68cc1b..d1c2826a5ce 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -104,7 +104,7 @@ return output /obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D) - var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10]sec" + var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10] seconds" return output /obj/machinery/mecha_part_fabricator/proc/output_part_cost(datum/design/D) @@ -327,14 +327,16 @@ [left_part] - + [list_queue()] "} - user << browse(dat, "window=mecha_fabricator;size=1000x430") + var/datum/browser/popup = new(user, "mecha_fabricator", name, 1000, 600) + popup.set_content(dat) + popup.open(0) onclose(user, "mecha_fabricator") return diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 9306eec9829..add66a81e90 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -3,28 +3,33 @@ /obj/machinery/mineral/ore_redemption name = "ore redemption machine" - desc = "A machine that accepts ore and instantly transforms it into workable material sheets, but cannot produce alloys such as Plasteel. Points for ore are generated based on type and can be redeemed at a mining equipment vendor." + desc = "A machine that accepts ore and instantly transforms it into workable material sheets. Points for ore are generated based on type and can be redeemed at a mining equipment vendor." icon = 'icons/obj/machines/mining_machines.dmi' icon_state = "ore_redemption" - density = 1 - anchored = 1.0 + density = TRUE + anchored = TRUE input_dir = NORTH output_dir = SOUTH req_access = list(access_mineral_storeroom) - var/stk_types = list() - var/stk_amt = list() - var/stack_list[0] //Key: Type. Value: Instance of type. + speed_process = TRUE + layer = BELOW_OBJ_LAYER + var/req_access_reclaim = access_mining_station var/obj/item/card/id/inserted_id var/points = 0 var/ore_pickup_rate = 15 var/sheet_per_ore = 1 var/point_upgrade = 1 - var/list/ore_values = list(("sand" = 1), ("iron" = 1), ("plasma" = 15), ("silver" = 16), ("gold" = 18), ("titanium" = 30), ("uranium" = 30), ("diamond" = 50), ("bluespace crystal" = 50), ("bananium" = 60), ("tranquillite" = 60)) + var/list/ore_values = list("sand" = 1, "iron" = 1, "plasma" = 15, "silver" = 16, "gold" = 18, "titanium" = 30, "uranium" = 30, "diamond" = 50, "bluespace crystal" = 50, "bananium" = 60, "tranquillite" = 60) + var/message_sent = FALSE + var/list/ore_buffer = list() + var/datum/research/files + var/obj/item/disk/design_disk/inserted_disk var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"), "Virology" = list("plasma", "uranium", "gold")) - speed_process = 1 /obj/machinery/mineral/ore_redemption/New() ..() + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE),INFINITY) + files = new /datum/research/smelter(src) component_parts = list() component_parts += new /obj/item/circuitboard/ore_redemption(null) component_parts += new /obj/item/stock_parts/matter_bin(null) @@ -45,6 +50,12 @@ component_parts += new /obj/item/stock_parts/console_screen(null) RefreshParts() +/obj/machinery/mineral/ore_redemption/Destroy() + QDEL_NULL(files) + GET_COMPONENT(materials, /datum/component/material_container) + materials.retrieve_all() + return ..() + /obj/machinery/mineral/ore_redemption/RefreshParts() var/ore_pickup_rate_temp = 15 var/point_upgrade_temp = 1 @@ -59,147 +70,195 @@ point_upgrade = point_upgrade_temp sheet_per_ore = sheet_per_ore_temp -/obj/machinery/mineral/ore_redemption/proc/process_sheet(obj/item/ore/O) - var/obj/item/stack/sheet/processed_sheet = SmeltMineral(O) - if(processed_sheet) - if(!(processed_sheet in stack_list)) //It's the first of this sheet added - var/obj/item/stack/sheet/s = new processed_sheet(src,0) - s.amount = 0 - stack_list[processed_sheet] = s - // Not including tg's ignoring of metal, glass being stocked because if cargo's not telling science when ores are there, they probably won't - // help with restocking metal/glass either - var/msg = "\[[station_time_timestamp()]\]: [capitalize(s.name)] sheets have been stocked in the ore reclaimer." - for(var/obj/machinery/requests_console/D in allConsoles) - if(D.department in src.supply_consoles) - if(supply_consoles[D.department] == null || (s.name in supply_consoles[D.department])) - D.createMessage("Ore Redemption Machine", "New Minerals Available!", msg, 1) +/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/ore/O) - var/obj/item/stack/sheet/storage = stack_list[processed_sheet] - storage.amount += sheet_per_ore //Stack the sheets - O.loc = null //Let the old sheet... - qdel(O) //... garbage collect + ore_buffer -= O + + if(O && O.refined_type) + points += O.points * point_upgrade + + GET_COMPONENT(materials, /datum/component/material_container) + var/material_amount = materials.get_item_material_amount(O) + + if(!material_amount) + qdel(O) //no materials, incinerate it + + else if(!materials.has_space(material_amount * sheet_per_ore)) //if there is no space, eject it + unload_mineral(O) + + else + materials.insert_item(O, sheet_per_ore) //insert it + qdel(O) + +/obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D) + if(D.make_reagents.len) + return FALSE + + var/build_amount = 0 + + GET_COMPONENT(materials, /datum/component/material_container) + for(var/mat_id in D.materials) + var/M = D.materials[mat_id] + var/datum/material/redemption_mat = materials.materials[mat_id] + + if(!M || !redemption_mat) + return FALSE + + var/smeltable_sheets = round(redemption_mat.amount / M) + + if(!smeltable_sheets) + return FALSE + + if(!build_amount) + build_amount = smeltable_sheets + + build_amount = min(build_amount, smeltable_sheets) + + return build_amount + +/obj/machinery/mineral/ore_redemption/proc/process_ores(list/ores_to_process) + var/current_amount = 0 + for(var/ore in ores_to_process) + if(current_amount >= ore_pickup_rate) + break + smelt_ore(ore) + +/obj/machinery/mineral/ore_redemption/proc/send_console_message() + if(!is_station_level(z)) + return + message_sent = TRUE + var/area/A = get_area(src) + var/msg = "Now available in [A]:
" + + var/has_minerals = FALSE + var/mineral_name = null + GET_COMPONENT(materials, /datum/component/material_container) + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT + mineral_name = capitalize(M.name) + if(mineral_amount) + has_minerals = TRUE + msg += "[mineral_name]: [mineral_amount] sheets
" + + if(!has_minerals) + return + + for(var/obj/machinery/requests_console/D in allConsoles) + if(D.department in src.supply_consoles) + if(supply_consoles[D.department] == null || (mineral_name in supply_consoles[D.department])) + D.createMessage("Ore Redemption Machine", "New Minerals Available!", msg, 1) /obj/machinery/mineral/ore_redemption/process() - if(!panel_open && powered()) //If the machine is partially disassembled and/or depowered, it should not process minerals - var/turf/T = get_step(src, input_dir) - var/i = 0 - if(T) - for(var/obj/item/ore/O in T) - if(i >= ore_pickup_rate) - break - else if(!O || !O.refined_type) - continue - else - process_sheet(O) - i++ - else - var/obj/structure/ore_box/B = locate() in T - if(B) - for(var/obj/item/ore/O in B.contents) - if(i >= ore_pickup_rate) - break - else if(!O || !O.refined_type) - continue - else - process_sheet(O) - i++ + if(panel_open || !powered()) + return + var/atom/input = get_step(src, input_dir) + var/obj/structure/ore_box/OB = locate() in input + if(OB) + input = OB -/obj/machinery/mineral/ore_redemption/attackby(var/obj/item/W, var/mob/user, params) - if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", W)) - updateUsrDialog() - return + for(var/obj/item/ore/O in input) + if(QDELETED(O)) + continue + ore_buffer |= O + O.forceMove(src) + CHECK_TICK + + if(LAZYLEN(ore_buffer)) + message_sent = FALSE + process_ores(ore_buffer) + else if(!message_sent) + send_console_message() + +/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params) if(exchange_parts(user, W)) return - if(panel_open) - if(istype(W, /obj/item/crowbar)) - if(inserted_id) - inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it. - empty_content() - default_deconstruction_crowbar(W) - if(ismultitool(W)) - input_dir = turn(input_dir, -90) - output_dir = turn(output_dir, -90) - to_chat(user, "You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].") - return if(default_unfasten_wrench(user, W)) return - if(istype(W,/obj/item/card/id)) - if(!powered()) - return - else - var/obj/item/card/id/I = usr.get_active_hand() - if(istype(I) && !istype(inserted_id)) - if(!user.drop_item()) - return - I.forceMove(src) - inserted_id = I - interact(user) - return - ..() + if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", W)) + updateUsrDialog() + return + if(default_deconstruction_crowbar(W)) + return -/obj/machinery/mineral/ore_redemption/proc/SmeltMineral(var/obj/item/ore/O) - if(O.refined_type) - var/obj/item/stack/sheet/M = O.refined_type - points += O.points * point_upgrade - return M - qdel(O)//No refined type? Purge it. - return + if(!powered()) + return + if(istype(W, /obj/item/card/id)) + var/obj/item/card/id/I = user.get_active_hand() + if(istype(I) && !istype(inserted_id)) + if(!user.drop_item()) + return + I.forceMove(src) + inserted_id = I + interact(user) + return + + if(ismultitool(W) && panel_open) + input_dir = turn(input_dir, -90) + output_dir = turn(output_dir, -90) + to_chat(user, "You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].") + return + + if(istype(W, /obj/item/disk/design_disk)) + if(user.drop_item()) + W.forceMove(src) + inserted_disk = W + interact(user) + return TRUE + + return ..() /obj/machinery/mineral/ore_redemption/attack_hand(mob/user) if(..()) return interact(user) -/obj/machinery/mineral/ore_redemption/attack_ghost(mob/user) - interact(user) - /obj/machinery/mineral/ore_redemption/interact(mob/user) - user.set_machine(src) + var/dat = "This machine only accepts ore. Gibtonite and Slag are not accepted.

" + dat += "Current unclaimed points: [points]
" - var/obj/item/stack/sheet/s - var/dat - - dat += text("This machine only accepts ore. Gibtonite and Slag are not accepted.

") - dat += text("Current unclaimed points: [points]
") - - if(istype(inserted_id)) - dat += text("You have [inserted_id.mining_points] mining points collected. Eject ID.
") - dat += text("Claim points.
") + if(inserted_id) + dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
" + dat += "Claim points.

" else - dat += text("No ID inserted. Insert ID.
") + dat += "No ID inserted. Insert ID.

" - for(var/O in stack_list) - s = stack_list[O] - if(s.amount > 0) - if(O == stack_list[1]) - dat += "
" //just looks nicer - dat += text("[capitalize(s.name)]: [s.amount] Release
") + GET_COMPONENT(materials, /datum/component/material_container) + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + if(M.amount) + var/sheet_amount = M.amount / MINERAL_MATERIAL_AMOUNT + dat += "[capitalize(M.name)]: [sheet_amount] " + if(sheet_amount >= 1) + dat += "Release
" + else + dat += "Release
" - var/obj/item/stack/sheet/metalstack - if(/obj/item/stack/sheet/metal in stack_list) - metalstack = stack_list[/obj/item/stack/sheet/metal] + dat += "
Alloys:
" - var/obj/item/stack/sheet/glass/glassstack - if(/obj/item/stack/sheet/glass in stack_list) - glassstack = stack_list[/obj/item/stack/sheet/glass] + for(var/v in files.known_designs) + var/datum/design/D = files.known_designs[v] + if(can_smelt_alloy(D)) + dat += "[D.name]: Smelt
" + else + dat += "[D.name]: Smelt
" - var/obj/item/stack/sheet/plasmastack - if((/obj/item/stack/sheet/mineral/plasma in stack_list)) - plasmastack = stack_list[/obj/item/stack/sheet/mineral/plasma] + dat += "
Mineral Value List:
[get_ore_values()]
" - var/obj/item/stack/sheet/mineral/titaniumstack - if((/obj/item/stack/sheet/mineral/titanium in stack_list)) - titaniumstack = stack_list[/obj/item/stack/sheet/mineral/titanium] + if(inserted_disk) + dat += "Eject disk
" + dat += "
Uploadable designs:
" - if(metalstack && plasmastack && min(metalstack.amount, plasmastack.amount)) - dat += text("Plasteel Alloy (Metal + Plasma): Smelt
") - if(titaniumstack && plasmastack && min(titaniumstack.amount, plasmastack.amount)) - dat += text("Plastitanium Alloy (Titanium + Plasma): Smelt
") - if(glassstack && plasmastack && min(glassstack.amount, plasmastack.amount)) - dat += text("Plasma Glass (Glass + Plasma): Smelt
") - dat += text("
Mineral Value List:
[get_ore_values()]
") + if(inserted_disk.blueprint) + var/datum/design/D = inserted_disk.blueprint + if(D.build_type & SMELTER) + dat += "Name: [D.name] Upload to smelter" - var/datum/browser/popup = new(user, "console_stacking_machine", "Ore Redemption Machine", 400, 500) + dat += "

" + else + dat += "Insert design disk

" + + var/datum/browser/popup = new(user, "ore_redemption_machine", "Ore Redemption Machine", 400, 500) popup.set_content(dat) popup.open() return @@ -214,63 +273,80 @@ /obj/machinery/mineral/ore_redemption/Topic(href, href_list) if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - inserted_id.loc = loc - inserted_id.verb_pickup() - inserted_id = null - if(href_list["choice"] == "claim") - if(access_mining_station in inserted_id.access) - inserted_id.mining_points += points - points = 0 - else - to_chat(usr, "Required access not found.") - else if(href_list["choice"] == "insert") - var/obj/item/card/id/I = usr.get_active_hand() - if(istype(I)) - if(!usr.drop_item()) - return 1 - I.loc = src - inserted_id = I + return + GET_COMPONENT(materials, /datum/component/material_container) + if(href_list["eject_id"]) + usr.put_in_hands(inserted_id) + inserted_id = null + if(href_list["claim"]) + if(inserted_id) + if(req_access_reclaim in inserted_id.access) + inserted_id.mining_points += points + points = 0 else - to_chat(usr, "No valid ID.") + to_chat(usr, "Required access not found.") + else if(href_list["insert_id"]) + var/obj/item/card/id/I = usr.get_active_hand() + if(istype(I)) + if(!usr.drop_item()) + return + I.forceMove(src) + inserted_id = I + else + to_chat(usr, "Not a valid ID!") + if(href_list["eject_disk"]) + if(inserted_disk) + inserted_disk.forceMove(loc) + inserted_disk = null + if(href_list["insert_disk"]) + var/obj/item/disk/design_disk/D = usr.get_active_hand() + if(istype(D)) + if(!usr.drop_item()) + return + D.forceMove(src) + inserted_disk = D + if(href_list["upload"]) + if(inserted_disk && inserted_disk.blueprint) + files.AddDesign2Known(inserted_disk.blueprint) if(href_list["release"]) - if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user. - if(!(text2path(href_list["release"]) in stack_list)) return - var/obj/item/stack/sheet/inp = stack_list[text2path(href_list["release"])] - var/obj/item/stack/sheet/out = new inp.type() - var/desired = input("How much?", "How much to eject?", 1) as num - out.amount = round(min(desired,50,inp.amount)) - if(out.amount >= 1) - inp.amount -= out.amount - unload_mineral(out) - if(inp.amount < 1) - stack_list -= text2path(href_list["release"]) + if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user + var/mat_id = href_list["release"] + if(!materials.materials[mat_id]) + return + + var/datum/material/mat = materials.materials[mat_id] + var/stored_amount = mat.amount / MINERAL_MATERIAL_AMOUNT + + if(!stored_amount) + return + + var/desired = input("How many sheets?", "How many sheets to eject?", 1) as null|num + var/sheets_to_remove = round(min(desired,50,stored_amount)) + + var/out = get_step(src, output_dir) + materials.retrieve_sheets(sheets_to_remove, mat_id, out) + else to_chat(usr, "Required access not found.") - if(href_list["alloytype1"] && href_list["alloytype2"] && href_list["alloytypeout"]) - var/alloytype1 = text2path(href_list["alloytype1"]) - var/alloytype2 = text2path(href_list["alloytype2"]) - var/alloytypeout = text2path(href_list["alloytypeout"]) - if(check_access(inserted_id) || allowed(usr)) - if(!(alloytype1 in stack_list)) - return - if(!(alloytype2 in stack_list)) - return - var/obj/item/stack/sheet/stack1 = stack_list[alloytype1] - var/obj/item/stack/sheet/stack2 = stack_list[alloytype2] - var/desired = input("How much?", "How much would you like to smelt?", 1) as num - var/obj/item/stack/sheet/alloyout = new alloytypeout - alloyout.amount = round(min(desired,50,stack1.amount,stack2.amount)) - if(alloyout.amount >= 1) - stack1.amount -= alloyout.amount - stack2.amount -= alloyout.amount - unload_mineral(alloyout) + if(href_list["alloy"]) + var/alloy_id = href_list["alloy"] + var/datum/design/alloy = files.FindDesignByID(alloy_id) + if((check_access(inserted_id) || allowed(usr)) && alloy) + var/desired = input("How many sheets?", "How many sheets would you like to smelt?", 1) as null|num + var/smelt_amount = can_smelt_alloy(alloy) + var/amount = round(min(desired,50,smelt_amount)) + materials.use_amount(alloy.materials, amount) + + var/output = new alloy.build_path(src) + if(istype(output, /obj/item/stack/sheet)) + var/obj/item/stack/sheet/mineral/produced_alloy = output + produced_alloy.amount = amount + unload_mineral(produced_alloy) + else + unload_mineral(output) + else to_chat(usr, "Required access not found.") updateUsrDialog() @@ -281,31 +357,16 @@ s.start() if(severity == 1) if(prob(50)) - empty_content() qdel(src) else if(severity == 2) if(prob(25)) - empty_content() qdel(src) -//empty the redemption machine by stacks of at most max_amount (50 at this time) size -/obj/machinery/mineral/ore_redemption/proc/empty_content() - var/obj/item/stack/sheet/s - - for(var/O in stack_list) - s = stack_list[O] - while(s.amount > s.max_amount) - new s.type(loc,s.max_amount) - s.use(s.max_amount) - s.forceMove(loc) - s.layer = initial(s.layer) - s.plane = initial(s.plane) - /obj/machinery/mineral/ore_redemption/power_change() ..() update_icon() if(inserted_id && !powered()) - visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.") + visible_message("The ID slot indicator light flickers on [src] as it spits out a card before powering down.") inserted_id.forceMove(loc) /obj/machinery/mineral/ore_redemption/update_icon() @@ -313,7 +374,6 @@ icon_state = initial(icon_state) else icon_state = "[initial(icon_state)]-off" - return /**********************Mining Equipment Locker**************************/ diff --git a/code/modules/telesci/bscrystal.dm b/code/modules/telesci/bscrystal.dm index 89c7153f018..78b1da7f2a9 100644 --- a/code/modules/telesci/bscrystal.dm +++ b/code/modules/telesci/bscrystal.dm @@ -36,10 +36,12 @@ if(isliving(hit_atom)) blink_mob(hit_atom) qdel(src) + // Blueapce crystal fragments (stops point farming) -/obj/item/ore/bluespace_crystal/fragment - points = 0 - refined_type = null +/obj/item/ore/bluespace_crystal/refined + name = "refined bluespace crystal" + points = 0 + refined_type = null // Artifical bluespace crystal, doesn't give you much research. /obj/item/ore/bluespace_crystal/artificial @@ -53,7 +55,7 @@ // Polycrystals, aka stacks -var/global/list/datum/stack_recipe/bluespace_crystal_recipes = list(new/datum/stack_recipe("Breakdown into bluespace crystal", /obj/item/ore/bluespace_crystal/fragment, 1, one_per_turf = 0, on_floor = 1)) +var/global/list/datum/stack_recipe/bluespace_crystal_recipes = list(new/datum/stack_recipe("Breakdown into bluespace crystal", /obj/item/ore/bluespace_crystal/refined, 1, one_per_turf = 0, on_floor = 1)) /obj/item/stack/sheet/bluespace_crystal name = "bluespace polycrystal"