diff --git a/_maps/map_files/stations/boxstation.dmm b/_maps/map_files/stations/boxstation.dmm index 50511c8af66..924e17cfcb3 100644 --- a/_maps/map_files/stations/boxstation.dmm +++ b/_maps/map_files/stations/boxstation.dmm @@ -68036,9 +68036,7 @@ /area/station/public/dorms) "nXu" = ( /obj/structure/window/reinforced, -/obj/structure/table/reinforced, -/obj/item/hemostat, -/obj/item/scalpel, +/obj/machinery/smithing/scientific_assembler, /turf/simulated/floor/plasteel{ icon_state = "whitepurple" }, @@ -87485,6 +87483,8 @@ }, /obj/item/slime_scanner, /obj/item/slime_scanner, +/obj/item/hemostat, +/obj/item/scalpel, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whitepurple" diff --git a/_maps/map_files/stations/cerestation.dmm b/_maps/map_files/stations/cerestation.dmm index 7f7f5e4a3fa..d3e252ae669 100644 --- a/_maps/map_files/stations/cerestation.dmm +++ b/_maps/map_files/stations/cerestation.dmm @@ -59464,6 +59464,12 @@ }, /turf/simulated/floor/plasteel, /area/station/engineering/atmos) +"lCN" = ( +/obj/machinery/smithing/scientific_assembler, +/turf/simulated/floor/plasteel{ + icon_state = "whitepurple" + }, +/area/station/science/xenobiology) "lCO" = ( /obj/structure/rack, /obj/effect/spawner/random/tech_storage/engineering, @@ -133877,7 +133883,7 @@ cGd cGd wNA qKO -yiP +lCN xIa xIa xIa diff --git a/_maps/map_files/stations/deltastation.dmm b/_maps/map_files/stations/deltastation.dmm index 64865129e61..e919db87503 100644 --- a/_maps/map_files/stations/deltastation.dmm +++ b/_maps/map_files/stations/deltastation.dmm @@ -85488,6 +85488,13 @@ /obj/effect/turf_decal/stripes/corner, /turf/simulated/floor/plating/airless, /area/station/engineering/control) +"tgQ" = ( +/obj/machinery/smithing/scientific_assembler, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "whitepurple" + }, +/area/station/science/xenobiology) "thl" = ( /obj/effect/turf_decal/delivery, /obj/machinery/door/firedoor, @@ -130127,7 +130134,7 @@ eGq exC mek tjH -cQP +tgQ cVf cVf cSc diff --git a/_maps/map_files/stations/emeraldstation.dmm b/_maps/map_files/stations/emeraldstation.dmm index 819f156c3a4..750f2d9aa87 100644 --- a/_maps/map_files/stations/emeraldstation.dmm +++ b/_maps/map_files/stations/emeraldstation.dmm @@ -23053,7 +23053,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/filingcabinet/chestdrawer, +/obj/machinery/smithing/scientific_assembler, /turf/simulated/floor/plasteel{ icon_state = "whitepurplecorner" }, diff --git a/_maps/map_files/stations/metastation.dmm b/_maps/map_files/stations/metastation.dmm index 536099d8cc6..cb1bdca4b82 100644 --- a/_maps/map_files/stations/metastation.dmm +++ b/_maps/map_files/stations/metastation.dmm @@ -42933,6 +42933,13 @@ }, /turf/simulated/floor/plasteel, /area/station/engineering/break_room) +"fbq" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/smithing/scientific_assembler, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, +/area/station/science/xenobiology) "fbr" = ( /obj/machinery/ai_status_display{ pixel_y = 32 @@ -130284,7 +130291,7 @@ gZe deu sFX pNz -kjo +fbq fvN aaa aaa diff --git a/code/game/machinery/machine_frame.dm b/code/game/machinery/machine_frame.dm index 690f78f37ec..7b3c1ce0743 100644 --- a/code/game/machinery/machine_frame.dm +++ b/code/game/machinery/machine_frame.dm @@ -1097,6 +1097,17 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/manipulator = 3, /obj/item/stack/sheet/glass = 1) +/obj/item/circuitboard/scientific_assembler + board_name = "Scientific Assembler" + icon_state = "supply" + build_path = /obj/machinery/smithing/scientific_assembler + board_type = "machine" + origin_tech = "programming=1;engineering=4" + req_components = list( + /obj/item/stock_parts/micro_laser = 1, + /obj/item/stock_parts/manipulator = 3, + /obj/item/stack/sheet/glass = 1) + /obj/item/circuitboard/ore_redemption board_name = "Ore Redemption" icon_state = "supply" diff --git a/code/game/machinery/vendors/departmental_vendors.dm b/code/game/machinery/vendors/departmental_vendors.dm index 00cd0897362..01437bc26c5 100644 --- a/code/game/machinery/vendors/departmental_vendors.dm +++ b/code/game/machinery/vendors/departmental_vendors.dm @@ -367,6 +367,7 @@ /obj/item/smithing_cast/component/lens_focus = 3, /obj/item/smithing_cast/component/lens_frame = 3, /obj/item/smithing_cast/component/trim = 3, + /obj/item/smithing_cast/misc/egun_parts = 3, /obj/item/storage/bag/smith = 2, /obj/item/storage/box/crewvend = 1) diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 20715cfbd5e..dd8950b2e81 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -582,6 +582,16 @@ build_path = /obj/item/circuitboard/kinetic_assembler category = list ("Misc. Machinery") +/datum/design/scientific_assembler + name = "Machine Design (Kinetic Assembler)" + desc = "The circuit board for a Kinetic Assembler." + id = "scientific_assembler" + req_tech = list("programming" = 2, "engineering" = 4, "plasmatech" = 3) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + build_path = /obj/item/circuitboard/scientific_assembler + category = list ("Misc. Machinery") + /datum/design/mining_equipment_vendor name = "Machine Design (Mining Rewards Vendor Board)" desc = "The circuit board for a Mining Rewards Vendor." diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index be67faed004..60a5b196fa8 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -17,6 +17,8 @@ var/Uses = 1 /// The mob who last injected the extract with plasma, water or blood. Used for logging. var/mob/living/injector_mob + /// The gun type associated with the extract + var/obj/item/gun/energy/associated_gun_type /obj/item/slime_extract/attackby__legacy__attackchain(obj/item/O, mob/user) if(istype(O, /obj/item/slimepotion/enhancer)) @@ -41,86 +43,107 @@ /obj/item/slime_extract/gold name = "gold slime extract" icon_state = "gold slime extract" + associated_gun_type = /obj/item/gun/energy/gun/shotgun /obj/item/slime_extract/silver name = "silver slime extract" icon_state = "silver slime extract" + associated_gun_type = /obj/item/gun/energy/disabler/smg /obj/item/slime_extract/metal name = "metal slime extract" icon_state = "metal slime extract" + associated_gun_type = /obj/item/gun/energy/gun/mini /obj/item/slime_extract/purple name = "purple slime extract" icon_state = "purple slime extract" + associated_gun_type = /obj/item/gun/energy/disabler /obj/item/slime_extract/darkpurple name = "dark purple slime extract" icon_state = "dark purple slime extract" + associated_gun_type = /obj/item/gun/energy/laser /obj/item/slime_extract/orange name = "orange slime extract" icon_state = "orange slime extract" + associated_gun_type = /obj/item/gun/energy/gun/mini /obj/item/slime_extract/yellow name = "yellow slime extract" icon_state = "yellow slime extract" + associated_gun_type = /obj/item/gun/energy/ionrifle/carbine /obj/item/slime_extract/red name = "red slime extract" icon_state = "red slime extract" + associated_gun_type = /obj/item/gun/energy/plasma_pistol /obj/item/slime_extract/blue name = "blue slime extract" icon_state = "blue slime extract" + associated_gun_type = /obj/item/gun/energy/disabler /obj/item/slime_extract/darkblue name = "dark blue slime extract" icon_state = "dark blue slime extract" + associated_gun_type = /obj/item/gun/energy/gun /obj/item/slime_extract/pink name = "pink slime extract" icon_state = "pink slime extract" + associated_gun_type = /obj/item/gun/energy/gun/blueshield /obj/item/slime_extract/green name = "green slime extract" icon_state = "green slime extract" + associated_gun_type = /obj/item/gun/projectile/automatic/laserrifle /obj/item/slime_extract/lightpink name = "light pink slime extract" icon_state = "light pink slime extract" + associated_gun_type = /obj/item/gun/energy/arc_revolver /obj/item/slime_extract/black name = "black slime extract" icon_state = "black slime extract" + associated_gun_type = /obj/item/gun/energy/lasercannon /obj/item/slime_extract/oil name = "oil slime extract" icon_state = "oil slime extract" + associated_gun_type = /obj/item/gun/energy/immolator /obj/item/slime_extract/adamantine name = "adamantine slime extract" icon_state = "adamantine slime extract" + associated_gun_type = /obj/item/gun/energy/gun/nuclear /obj/item/slime_extract/bluespace name = "bluespace slime extract" icon_state = "bluespace slime extract" + associated_gun_type = /obj/item/gun/energy/sparker /obj/item/slime_extract/pyrite name = "pyrite slime extract" icon_state = "pyrite slime extract" + associated_gun_type = /obj/item/gun/energy/gun/mini /obj/item/slime_extract/cerulean name = "cerulean slime extract" icon_state = "cerulean slime extract" + associated_gun_type = /obj/item/gun/energy/gun/shotgun /obj/item/slime_extract/sepia name = "sepia slime extract" icon_state = "sepia slime extract" + associated_gun_type = /obj/item/gun/energy/laser/retro /obj/item/slime_extract/rainbow name = "rainbow slime extract" icon_state = "rainbow slime extract" + associated_gun_type = /obj/item/gun/energy/lwap ////Slime-derived potions/// diff --git a/code/modules/smithing/machinery/casting_basin.dm b/code/modules/smithing/machinery/casting_basin.dm index 12e5708ece0..cf4fa0eeb3d 100644 --- a/code/modules/smithing/machinery/casting_basin.dm +++ b/code/modules/smithing/machinery/casting_basin.dm @@ -50,6 +50,16 @@ . += " - [MAT]: [ROUND_UP(((temp_product.materials[MAT] * quality.material_mult) * efficiency) / MINERAL_MATERIAL_AMOUNT)] sheets." // Get rid of the temp product qdel(temp_product) + else if(istype(cast, /obj/item/smithing_cast/misc) && !produced_item) + var/obj/item/temp_product = new cast.selected_product(src) // This is necessary due to selected_product being a type + var/obj/item/smithing_cast/component/comp_cast = cast + . += "Required Resources:" + var/MAT + // Get the materials the item needs and display + for(MAT in temp_product.materials) + . += " - [MAT]: [ROUND_UP((temp_product.materials[MAT] * efficiency) / MINERAL_MATERIAL_AMOUNT)] sheets." + // Get rid of the temp product + qdel(temp_product) if(produced_item) . += "There is a [produced_item] in the machine. You can pick it up with your hand." @@ -86,6 +96,8 @@ . += "cast_lens" else if(istype(cast, /obj/item/smithing_cast/component/trim)) . += "cast_trim" + else if(istype(cast, /obj/item/smithing_cast/misc/egun_parts)) + . += "cast_egun_parts" . += "casting_lip" if(panel_open) . += "casting_wires" @@ -233,6 +245,32 @@ qdel(temp_product) return FINISH_ATTACK + if(istype(cast, /obj/item/smithing_cast/misc)) + var/list/used_mats = list() + + // Check if there is enough materials to craft the item + for(MAT in temp_product.materials) + used_mats[MAT] = temp_product.materials[MAT] * efficiency + + if(!materials.has_materials(used_mats, 1)) + to_chat(user, "Not enough materials in the crucible to smelt [temp_product.name]!") + qdel(temp_product) + return FINISH_ATTACK + + to_chat(user, "You begin to pour the liquid minerals into the [src]...") + // Use the materials and create the item. + materials.use_amount(used_mats) + linked_crucible.animate_pour(operation_time SECONDS) + operate(operation_time, user) + produced_item = new cast.selected_product(src) + produced_item.set_worktime() + produced_item.update_appearance(UPDATE_NAME) + produced_item.update_icon(UPDATE_ICON_STATE) + update_icon(UPDATE_OVERLAYS) + // Clean up temps + qdel(temp_product) + return FINISH_ATTACK + /obj/machinery/smithing/casting_basin/Destroy() if(linked_crucible) linked_crucible.linked_machines -= src diff --git a/code/modules/smithing/machinery/kinetic_assembler.dm b/code/modules/smithing/machinery/kinetic_assembler.dm index 00032834333..c2aefbc3cf1 100644 --- a/code/modules/smithing/machinery/kinetic_assembler.dm +++ b/code/modules/smithing/machinery/kinetic_assembler.dm @@ -231,3 +231,148 @@ extra_product.update_appearance(UPDATE_NAME) extra_product.scatter_atom() finished_product = null + +// MARK: Scientific Assembler + +/obj/machinery/smithing/scientific_assembler + name = "scientific assembler" + desc = "A smart assembler that takes slime cores, energy cells, and energy gun parts to produce energy guns." + icon = 'icons/obj/machines/smithing_machines.dmi' + icon_state = "assembler" + max_integrity = 100 + pixel_x = 0 // 1x1 + pixel_y = 0 + bound_height = 32 + bound_width = 32 + bound_y = 0 + operation_sound = 'sound/items/welder.ogg' + /// Slime extract for the egun + var/obj/item/slime_extract/slime_core + /// The gun frame + var/obj/item/smithed_item/component/egun_parts/parts + /// The battery + var/obj/item/stock_parts/cell/cell + +/obj/machinery/smithing/scientific_assembler/Initialize(mapload) + . = ..() + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/kinetic_assembler(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/stack/sheet/glass(null) + RefreshParts() + +/obj/machinery/smithing/scientific_assembler/examine(mob/user) + . = ..() + if(slime_core || parts || cell) + . += "You can activate the machine with your hand, or remove a component by alt-clicking." + if(slime_core) + . += "There is a [slime_core] in the core slot." + if(parts) + . += "There is a [parts] in the gun frame slot." + if(cell) + . += "There is a [cell] in the power cell slot." + +/obj/machinery/smithing/scientific_assembler/RefreshParts() + var/operation_mult = 0 + for(var/obj/item/stock_parts/component in component_parts) + operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating + // Update our values + operation_time = operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) + +/obj/machinery/smithing/scientific_assembler/update_icon_state() + . = ..() + if(panel_open) + icon_state = "assembler_wires" + +/obj/machinery/smithing/kinetic_assembler/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_ICON_STATE) + +/obj/machinery/smithing/scientific_assembler/update_overlays() + . = ..() + overlays.Cut() + if(panel_open) + icon_state = "assembler_wires" + +/obj/machinery/smithing/scientific_assembler/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(operating) + to_chat(user, "[src] is still operating!") + return ITEM_INTERACT_COMPLETE + + if(istype(used, /obj/item/slime_extract)) + var/obj/item/slime_extract/core = used + if(!core.associated_gun_type) + to_chat(user, "[core] is not capable of producing an energy gun!") + return ITEM_INTERACT_COMPLETE + if(slime_core) + to_chat(user, "You remove [slime_core] from the core component slot of [src].") + slime_core.forceMove(src.loc) + slime_core = null + if(used.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[used] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + to_chat(user, "You insert [used] into the core component slot of [src].") + slime_core = used + return ITEM_INTERACT_COMPLETE + + if(istype(used, /obj/item/smithed_item/component/egun_parts)) + if(parts) + to_chat(user, "You remove [parts] from the gun parts component slot of [src].") + parts.forceMove(src.loc) + parts = null + if(used.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[used] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + var/obj/item/smithed_item/component/egun_parts/new_parts = used + if(new_parts.hammer_time) + to_chat(user, "[new_parts] is not complete yet!") + return ITEM_INTERACT_COMPLETE + to_chat(user, "You insert [used] into the gun parts component slot of [src].") + parts = used + return ITEM_INTERACT_COMPLETE + + if(istype(used, /obj/item/stock_parts/cell)) + if(cell) + to_chat(user, "You remove [cell] from the power cell component slot of [src].") + cell.forceMove(src.loc) + cell = null + if(used.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[used] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + to_chat(user, "You insert [used] into the power cell component slot of [src].") + cell = used + return ITEM_INTERACT_COMPLETE + + to_chat(user, "You feel like there's no reason to process [used].") + return ITEM_INTERACT_COMPLETE + +/obj/machinery/smithing/scientific_assembler/attack_hand(mob/user) + if(!slime_core) + to_chat(user, "[src] lacks a slime core!") + return FINISH_ATTACK + + if(!parts) + to_chat(user, "[src] lacks an energy gun frame!") + return FINISH_ATTACK + + if(!cell) + to_chat(user, "[src] lacks a power cell!") + return FINISH_ATTACK + + operate(operation_time, user) + return FINISH_ATTACK + +/obj/machinery/smithing/scientific_assembler/operate(loops, mob/living/user) + ..() + var/obj/item/gun/energy/finished_product = new slime_core.associated_gun_type(src) + finished_product.forceMove(src.loc) + qdel(slime_core) + qdel(parts) + qdel(cell) + slime_core = null + parts = null + cell = null diff --git a/code/modules/smithing/machinery/power_hammer.dm b/code/modules/smithing/machinery/power_hammer.dm index 7bc9e78e5f8..af463db6671 100644 --- a/code/modules/smithing/machinery/power_hammer.dm +++ b/code/modules/smithing/machinery/power_hammer.dm @@ -48,7 +48,7 @@ /obj/machinery/smithing/power_hammer/operate(loops, mob/living/user) if(!working_component) - to_chat(user, "There is no component in the machine.") + to_chat(user, "There is no component to hammer!") return if(!working_component.heat) to_chat(user, "[working_component] is too cold to properly shape.") diff --git a/code/modules/smithing/smithed_items/misc_smithed.dm b/code/modules/smithing/smithed_items/misc_smithed.dm new file mode 100644 index 00000000000..e98d5c8af8a --- /dev/null +++ b/code/modules/smithing/smithed_items/misc_smithed.dm @@ -0,0 +1,7 @@ +// MARK: Energy Gun Frame +/obj/item/smithed_item/component/egun_parts + name = "energy gun parts" + desc = "Smithed component of an energy gun." + icon_state = "egun_parts" + materials = list(MAT_TITANIUM = 10000, MAT_PLASMA = 10000) + hammer_time = 6 diff --git a/code/modules/smithing/smithing_cast.dm b/code/modules/smithing/smithing_cast.dm index 9a2140be5a0..d46507e7826 100644 --- a/code/modules/smithing/smithing_cast.dm +++ b/code/modules/smithing/smithing_cast.dm @@ -26,11 +26,15 @@ . = ..() if(!possible_products) return + if(!length(possible_products)) + return var/list/product_names = list() var/product for(product in possible_products) var/obj/item/possible_product = product product_names[possible_product.name] = possible_product + if(!length(product_names)) + return var/new_product = tgui_input_list(user, "Select a product", src, product_names) if(!new_product) selected_product = possible_products[1] @@ -158,3 +162,20 @@ icon_state = "trim_cast" desc = "A cast for creating trims." product_type = /obj/item/smithed_item/component/trim + +/obj/item/smithing_cast/misc + name = "misc cast" + icon_state = "insert_frame_cast" + desc = "Debug cast. If you see this, notify the development team." + +/obj/item/smithing_cast/misc/AltClick(mob/user, modifiers) + return + +/obj/item/smithing_cast/misc/examine(mob/user) + . = desc + +/obj/item/smithing_cast/misc/egun_parts + name = "energy gun parts cast" + icon_state = "egun_parts_cast" + desc = "A cast for creating energy gun frames." + selected_product = /obj/item/smithed_item/component/egun_parts diff --git a/icons/obj/machines/smithing_machines.dmi b/icons/obj/machines/smithing_machines.dmi index cd2c5a5fb34..fbe6aa2c129 100644 Binary files a/icons/obj/machines/smithing_machines.dmi and b/icons/obj/machines/smithing_machines.dmi differ diff --git a/icons/obj/smithing.dmi b/icons/obj/smithing.dmi index 6ce76869a53..9ad42d26bf7 100644 Binary files a/icons/obj/smithing.dmi and b/icons/obj/smithing.dmi differ diff --git a/paradise.dme b/paradise.dme index c69c1fef5cd..6ebfb4fad68 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2984,6 +2984,7 @@ #include "code\modules\smithing\machinery\smart_hopper.dm" #include "code\modules\smithing\smithed_items\inserts.dm" #include "code\modules\smithing\smithed_items\lens.dm" +#include "code\modules\smithing\smithed_items\misc_smithed.dm" #include "code\modules\smithing\smithed_items\tool_bits.dm" #include "code\modules\space_management\level_check.dm" #include "code\modules\space_management\level_traits.dm"