diff --git a/code/__DEFINES/~nova_defines/techweb_nodes.dm b/code/__DEFINES/~nova_defines/techweb_nodes.dm index 58490c04df3..79b3c0ed05e 100644 --- a/code/__DEFINES/~nova_defines/techweb_nodes.dm +++ b/code/__DEFINES/~nova_defines/techweb_nodes.dm @@ -15,6 +15,7 @@ #define TECHWEB_NODE_CYBERNETICS_DIGITIGRADE_ADVANCED "adv_digitigrade_cyber" #define TECHWEB_NODE_CYBERNETICS_TESHARI "teshari_cyber" #define TECHWEB_NODE_CYBERNETICS_TESHARI_ADVANCED "adv_teshari_cyber" +#define TECHWEB_NODE_MEDBAY_MEDIPENS "medbay_medipens" #define TECHWEB_NODE_MUTANT_TECH "mutant_tech" #define TECHWEB_NODE_NIGHT_VISION_IMPLANTS "nv_implants" #define TECHWEB_NODE_ROBOTIC_SURGERY "improved_robotic_surgery" diff --git a/code/game/machinery/medipen_refiller.dm b/code/game/machinery/medipen_refiller.dm index 57c3fa2f8d4..f6a528e4b63 100644 --- a/code/game/machinery/medipen_refiller.dm +++ b/code/game/machinery/medipen_refiller.dm @@ -19,7 +19,28 @@ /obj/item/reagent_containers/hypospray/medipen/survival = /datum/reagent/medicine/c2/libital, /obj/item/reagent_containers/hypospray/medipen/survival/luxury = /datum/reagent/medicine/c2/penthrite, /obj/item/reagent_containers/hypospray/medipen/invisibility = /datum/reagent/drug/saturnx, + // NOVA EDIT ADDITION BEGIN - Universal medipens and lathe medipens + /obj/item/reagent_containers/hypospray/medipen/universal = null, + /obj/item/reagent_containers/hypospray/medipen/universal/lowpressure = null, + /obj/item/reagent_containers/hypospray/medipen/empty = /datum/reagent/medicine/epinephrine, + /obj/item/reagent_containers/hypospray/medipen/atropine/empty = /datum/reagent/medicine/atropine, + /obj/item/reagent_containers/hypospray/medipen/salbutamol/empty = /datum/reagent/medicine/salbutamol, + /obj/item/reagent_containers/hypospray/medipen/oxandrolone/empty = /datum/reagent/medicine/oxandrolone, + /obj/item/reagent_containers/hypospray/medipen/salacid/empty = /datum/reagent/medicine/sal_acid, + /obj/item/reagent_containers/hypospray/medipen/penacid/empty = /datum/reagent/medicine/pen_acid, + // NOVA EDIT ADDITION END ) + // NOVA EDIT ADDITION BEGIN - Universal medipens + ///Whitelist typecache of reagent types which are allowed to refill universal medipens. + var/static/list/medipen_reagent_whitelist = typecacheof(list( + /datum/reagent/medicine, + /datum/reagent/vaccine, + )) + ///Blacklist typecache of reagent types which are disallowed to refill universal medipens. + var/static/list/medipen_reagent_blacklist = typecacheof(list( + /datum/reagent/medicine/morphine, + )) + // NOVA EDIT ADDITION END /obj/machinery/medipen_refiller/Initialize(mapload) . = ..() @@ -37,7 +58,9 @@ context[SCREENTIP_CONTEXT_LMB] = panel_open ? "Close panel" : "Open panel" else if(is_reagent_container(held_item) && held_item.is_open_container()) context[SCREENTIP_CONTEXT_LMB] = "Refill machine" - else if(istype(held_item, /obj/item/reagent_containers/hypospray/medipen) && reagents.has_reagent(allowed_pens[held_item.type])) + // NOVA EDIT CHANGE - ORIGINAL: else if(istype(held_item, /obj/item/reagent_containers/hypospray/medipen) && reagents.has_reagent(allowed_pens[held_item.type])) + else if(istype(held_item, /obj/item/reagent_containers/hypospray/medipen/universal) || istype(held_item, /obj/item/reagent_containers/hypospray/medipen) && reagents.has_reagent(allowed_pens[held_item.type])) + // NOVA EDIT CHANGE END context[SCREENTIP_CONTEXT_LMB] = "Refill medipen" else if(istype(held_item, /obj/item/plunger)) context[SCREENTIP_CONTEXT_LMB] = "Plunge machine" @@ -76,14 +99,40 @@ if(medipen.reagents?.reagent_list.len) balloon_alert(user, "medipen full!") return - if(!reagents.has_reagent(allowed_pens[medipen.type], 10)) + //if(!reagents.has_reagent(allowed_pens[medipen.type], 10)) // NOVA EDIT REMOVAL + // NOVA EDIT ADDITION BEGIN - Universal medipen and lathe medipens + var/list/datum/reagent/compatible_universal_reagents + if(istype(medipen, /obj/item/reagent_containers/hypospray/medipen/universal)) + if(!reagents.total_volume) + balloon_alert(user, "not enough reagents!") + return + // Ignore reagents which aren't the blacklist or whitelist + compatible_universal_reagents = typecache_filter_multi_list_exclusion(reagents.reagent_list, medipen_reagent_whitelist, medipen_reagent_blacklist) + // Ensure there is enough of the whitelisted reagents + if(!length(compatible_universal_reagents)) + balloon_alert(user, "reagents incompatible!") + return + else if(!reagents.has_reagent(allowed_pens[medipen.type], medipen.volume)) + // NOVA EDIT ADDITION END balloon_alert(user, "not enough reagents!") return add_overlay("active") if(do_after(user, 2 SECONDS, src)) + // NOVA EDIT ADDITION BEGIN - Universal medipen and lathe medipens + if(istype(medipen, /obj/item/reagent_containers/hypospray/medipen/universal)) + // Create list of transferable reagent typepaths + var/list/target_reagent_types = list() + for(var/datum/reagent/target_reagent as anything in compatible_universal_reagents) + target_reagent_types += target_reagent.type + // Transfer proportionally distributed amounts of each reagent + reagents.trans_to_multiple(target_atom = medipen, amount = medipen.volume, target_ids = target_reagent_types) + else + medipen.add_initial_reagents() + reagents.remove_reagent(allowed_pens[medipen.type], medipen.volume) + // NOVA EDIT ADDITION END medipen.used_up = FALSE - medipen.add_initial_reagents() - reagents.remove_reagent(allowed_pens[medipen.type], 10) + //medipen.add_initial_reagents() // NOVA EDIT REMOVAL - Handled above + //reagents.remove_reagent(allowed_pens[medipen.type], 10) // NOVA EDIT REMOVAL - Handled above balloon_alert(user, "refilled") use_energy(active_power_usage) cut_overlays() diff --git a/modular_nova/master_files/code/modules/reagents/chemistry/holder.dm b/modular_nova/master_files/code/modules/reagents/chemistry/holder.dm index 278a685dbb7..2e38f3f4555 100644 --- a/modular_nova/master_files/code/modules/reagents/chemistry/holder.dm +++ b/modular_nova/master_files/code/modules/reagents/chemistry/holder.dm @@ -15,3 +15,101 @@ return TRUE return FALSE + +/** + * Proportionally transfers each reagent to the target atom. Calls trans_to() to do the actual transfer. + * Unlike trans_to(), target_id is replaced with list target_ids. + * + * Arguments: + * * obj/target - Target atom to attempt transfers to + * * amount - Maximum total reagent volume to transfer + * * multiplier - multiplies each reagent amount by this number well byond their available volume before transfering. used to create reagents from thin air if you ever need to + * * list/datum/reagent/target_ids - transfers only the listed reagent types in this holder leaving others untouched + * * preserve_data - if preserve_data=FALSE, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. + * * no_react - passed through to [/datum/reagents/proc/add_reagent] + * * mob/transferred_by - used for logging + * * remove_blacklisted - skips transferring of reagents without REAGENT_CAN_BE_SYNTHESIZED in chemical_flags + * * methods - passed through to [/datum/reagents/proc/expose] and [/datum/reagent/proc/on_transfer] + * * show_message - passed through to [/datum/reagents/proc/expose] + * * ignore_stomach - when using methods INGEST will not use the stomach as the target + */ +/datum/reagents/proc/trans_to_multiple( + atom/target_atom, + amount = 1, + multiplier = 1, + list/datum/reagent/target_ids, + preserve_data = TRUE, + no_react = FALSE, + mob/transferred_by, + remove_blacklisted = FALSE, + methods = NONE, + show_message = TRUE, + ignore_stomach = FALSE, +) + // Nothing to transfer, or the targeted atom can't hold reagents + if(!total_volume || QDELETED(target_atom) || isnull(target_atom.reagents)) + return FALSE + + if(!IS_FINITE(amount)) + stack_trace("non-number or infinite number passed to trans_to_equal: amount = [amount]") + return FALSE + + // Ensure given amount is in a safe range + amount = round(amount, CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) + return FALSE + + // Maximum amount of reagents which can fit inside the target + var/max_volume = min(amount, target_atom.reagents.maximum_volume) + // Total volume of fillable empty space inside the target, accounting for given maximum + var/empty_volume = max(0, max_volume - target_atom.reagents.total_volume) + + // Targeted atom is already full of reagents + if(max_volume == 0 || empty_volume == 0) + return FALSE + + // Total volume of transferable reagents after whitelisting and rounding + var/possible_transfer_volume = 0 + // Only FALSE if a reagent whitelist was given + var/ignore_whitelist = isnull(target_ids) + // Associative list of reagent typepaths to datums + var/list/datum/reagent/target_reagents = list() + var/list/cached_reagents = reagent_list + // Perform whitelisting, then calculate total possible transfer volume + for(var/datum/reagent/reagent as anything in cached_reagents) + if(remove_blacklisted && !(reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) + continue + if(ignore_whitelist || is_type_in_list(reagent, target_ids) && reagent.volume) + target_reagents[reagent.type] = reagent + possible_transfer_volume += reagent.volume + + // There are no transferable reagents + if(!length(target_reagents) || !possible_transfer_volume) + return FALSE + + // Associative list of reagent typepaths to transfer volumes + // Used to provide reagent transfer amounts to trans_to() + var/list/transfer_volumes = list() + // Calculate proportional transfer volumes per reagent + // Account for reagents with insufficient and excess volumes + for(var/reagent_type as anything in target_reagents) + var/datum/reagent/reagent = target_reagents[reagent_type] + var/distributed_volume = round(reagent.volume / possible_transfer_volume, CHEMICAL_QUANTISATION_LEVEL) + transfer_volumes[reagent.type] = empty_volume * distributed_volume + + // Actually perform the reagent transfers and return total volume transferred + var/transfer_total = 0 + for(var/datum/reagent/reagent as anything in target_reagents) + transfer_total += trans_to( + target = target_atom, + amount = transfer_volumes[reagent], + target_id = reagent.type, + preserve_data = preserve_data, + no_react = no_react, + transferred_by = transferred_by, + remove_blacklisted = remove_blacklisted, + methods = methods, + show_message = show_message, + ignore_stomach = ignore_stomach, + ) + return transfer_total diff --git a/modular_nova/master_files/code/modules/reagents/reagent_containers/hypospray.dm b/modular_nova/master_files/code/modules/reagents/reagent_containers/hypospray.dm new file mode 100644 index 00000000000..afa35fce29f --- /dev/null +++ b/modular_nova/master_files/code/modules/reagents/reagent_containers/hypospray.dm @@ -0,0 +1,58 @@ +/obj/item/reagent_containers/hypospray/medipen + /// If TRUE, the medipen will initialize without reagents + var/init_empty = FALSE + /// If TRUE, indicates that the medipen hasn't been injected by a mob yet + var/unused = TRUE + +// Allows medipens to initialize without reagents if init_empty is TRUE +/obj/item/reagent_containers/hypospray/medipen/Initialize(mapload) + if(init_empty != TRUE) + return ..() + + // Temporarily sets list_reagents to null to avoid filling the medipen + var/initial_reagents = list_reagents + list_reagents = null + . = ..() + list_reagents = initial_reagents + + if(label_examine) + var/reagent_types = assoc_to_keys(list_reagents) + // Set label text via list_reagents, due to actual reagents being empty + label_text = span_notice("There is a sticker pasted onto the side which reads, 'WARNING: This medipen contains [pretty_string_from_reagent_list(reagent_types, names_only = TRUE, join_text = ", ", final_and = TRUE, capitalize_names = TRUE)], do not use if allergic to any listed chemicals.") + +// Sends a more generic chat message when an unused medipen is empty +/obj/item/reagent_containers/hypospray/medipen/inject(mob/living/affected_mob, mob/user) + if(!reagents?.total_volume || (init_empty && used_up && unused)) + to_chat(user, span_warning("You push [src]'s button, but nothing happens. It's empty!")) + return FALSE + + // Attempt the injection + . = ..() + + // If the injection succeeded, then the medipen is not unused anymore + if(unused && .) + unused = FALSE + +/obj/item/reagent_containers/hypospray/medipen/empty + init_empty = TRUE + used_up = TRUE + +/obj/item/reagent_containers/hypospray/medipen/atropine/empty + init_empty = TRUE + used_up = TRUE + +/obj/item/reagent_containers/hypospray/medipen/salbutamol/empty + init_empty = TRUE + used_up = TRUE + +/obj/item/reagent_containers/hypospray/medipen/oxandrolone/empty + init_empty = TRUE + used_up = TRUE + +/obj/item/reagent_containers/hypospray/medipen/salacid/empty + init_empty = TRUE + used_up = TRUE + +/obj/item/reagent_containers/hypospray/medipen/penacid/empty + init_empty = TRUE + used_up = TRUE diff --git a/modular_nova/modules/lathe_medipens/README.md b/modular_nova/modules/lathe_medipens/README.md new file mode 100644 index 00000000000..d97668dc557 --- /dev/null +++ b/modular_nova/modules/lathe_medipens/README.md @@ -0,0 +1,37 @@ +https://github.com/NovaSector/NovaSector/pull/3577 + +## Title: Lathe Medipens + +MODULE ID: lathe_medipens + +### Description: + +Contains empty subtypes of several medipens, custom/universal medipen subtypes with new icons, and techweb nodes/designs for them. + +### TG Proc Changes: + +- `/obj/item/reagent_containers/hypospray/medipen/Initialize()` +- `/obj/item/reagent_containers/hypospray/medipen/inject()` +- `/obj/machinery/medipen_refiller/add_context()` +- `/obj/machinery/medipen_refiller/attackby()` + +### Defines: + +- N/A + +### Master file additions + +- `modular_nova/master_files/code/modules/reagents/reagent_containers/hypospray.dm` + - Overrides `Initialize()` and `inject()`. + - Adds new variables `medipen/var/init_empty` and `medipen/var/unused`. +- `modular_nova/master_files/code/modules/reagents/chemistry/holder.dm` + - Adds new proc `/datum/reagents/proc/trans_to_multiple()` + +### Included files that are not contained in this module: + +Dependent to avoid runtime errors: + +- `modular_nova/master_files/code/modules/reagents/reagent_containers/hypospray.dm` + +### Credits: +- [@Floofies](https://github.com/Floofies) diff --git a/modular_nova/modules/lathe_medipens/code/autolathe_designs.dm b/modular_nova/modules/lathe_medipens/code/autolathe_designs.dm new file mode 100644 index 00000000000..b95c933e665 --- /dev/null +++ b/modular_nova/modules/lathe_medipens/code/autolathe_designs.dm @@ -0,0 +1,57 @@ +// Basetype for developer usage only. Shouldn't be visible ingame. +/datum/design/medipen + name = "Medipen Basetype" + id = DESIGN_ID_IGNORE + build_type = PROTOLATHE | AWAY_LATHE + materials = list( + /datum/material/plastic = SHEET_MATERIAL_AMOUNT * 3, + /datum/material/glass = SHEET_MATERIAL_AMOUNT * 2, + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.1, + /datum/material/silver = SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/reagent_containers/hypospray/medipen + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_CHEMISTRY, + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL + +/datum/design/medipen/universal + name = "Universal Medipen" + id = "medipen_universal" + build_path = /obj/item/reagent_containers/hypospray/medipen/universal + +/datum/design/medipen/universal_lowpressure + name = "Universal Low-Pressure Medipen" + id = "medipen_universal_lowpressure" + build_path = /obj/item/reagent_containers/hypospray/medipen/universal/lowpressure + +/datum/design/medipen/epinephrine + name = "Epinephrine Medipen" + id = "medipen_epinephrine" + build_path = /obj/item/reagent_containers/hypospray/medipen/empty + +/datum/design/medipen/atropine + name = "Atropine Medipen" + id = "medipen_atropine" + build_path = /obj/item/reagent_containers/hypospray/medipen/atropine/empty + +/datum/design/medipen/salbutamol + name = "Salbutamol Medipen" + id = "medipen_salbutamol" + build_path = /obj/item/reagent_containers/hypospray/medipen/salbutamol/empty + +/datum/design/medipen/oxandrolone + name = "Oxandrolone Medipen" + id = "medipen_oxandrolone" + build_path = /obj/item/reagent_containers/hypospray/medipen/oxandrolone/empty + +/datum/design/medipen/salacid + name = "Salicylic Acid Medipen" + id = "medipen_salacid" + build_path = /obj/item/reagent_containers/hypospray/medipen/salacid/empty + +/datum/design/medipen/penacid + name = "Pentetic Acid Medipen" + id = "medipen_penacid" + build_path = /obj/item/reagent_containers/hypospray/medipen/penacid/empty diff --git a/modular_nova/modules/lathe_medipens/code/hypospray.dm b/modular_nova/modules/lathe_medipens/code/hypospray.dm new file mode 100644 index 00000000000..be269b83162 --- /dev/null +++ b/modular_nova/modules/lathe_medipens/code/hypospray.dm @@ -0,0 +1,85 @@ +/obj/item/reagent_containers/hypospray/medipen/universal + name = "universal medipen" + article = "a" + desc = "It's an auto-injecting syringe with a universal refill port on the side." + icon = 'modular_nova/modules/lathe_medipens/icons/syringe.dmi' + lefthand_file = 'modular_nova/modules/lathe_medipens/icons/medical_lefthand.dmi' + righthand_file = 'modular_nova/modules/lathe_medipens/icons//medical_righthand.dmi' + icon_state = "medipen_blue_unused" + base_icon_state = "medipen_blue" + inhand_icon_state = "medipen_blue" + reagent_flags = TRANSPARENT + list_reagents = null + label_examine = FALSE + used_up = TRUE + init_empty = TRUE + +/obj/item/reagent_containers/hypospray/medipen/universal/update_overlays() + . = ..() + var/list/reagent_overlays = update_reagent_overlay() + if(reagent_overlays) + . += reagent_overlays + +/// Returns a list of overlays to add that relate to the reagents inside the syringe +/obj/item/reagent_containers/hypospray/medipen/universal/proc/update_reagent_overlay() + if(!reagents?.total_volume) + return + var/mutable_appearance/filling_overlay = mutable_appearance('modular_nova/modules/lathe_medipens/icons/reagent_fillings.dmi', "medipen") + filling_overlay.color = mix_color_from_reagents(reagents.reagent_list) + . += filling_overlay + +/obj/item/reagent_containers/hypospray/medipen/universal/inject(mob/living/affected_mob, mob/user) + . = ..() + if(. && used_up) + // Workaround to reset reagent flags after injection (gets set to 0 by parent proc) + reagents.flags = reagent_flags + +/obj/item/reagent_containers/hypospray/medipen/universal/lowpressure + name = "universal low-pressure medipen" + desc = "It's a low-pressure auto-injecting syringe with a universal refill port on the side. WARNING: This device is designed to be operated in low-pressure environments only." + icon_state = "medipen_red_unused" + base_icon_state = "medipen_red" + inhand_icon_state = "medipen_red" + volume = 30 + amount_per_transfer_from_this = 30 + +/obj/item/reagent_containers/hypospray/medipen/universal/lowpressure/update_icon_state() + . = ..() + if(reagents?.total_volume == 0) + icon_state = "[base_icon_state]0" + else if(reagents?.total_volume > (volume * 0.5)) + icon_state = base_icon_state + else + icon_state = "[base_icon_state]15" + +/// Returns a list of overlays to add that relate to the reagents inside the syringe +/obj/item/reagent_containers/hypospray/medipen/universal/lowpressure/update_reagent_overlay() + if(!reagents?.total_volume) + return + var/overlay_icon = "medipen" + if(reagents?.total_volume <= (volume * 0.5)) + overlay_icon = "medipen_half" + var/mutable_appearance/filling_overlay = mutable_appearance('modular_nova/modules/lathe_medipens/icons/reagent_fillings.dmi', overlay_icon) + filling_overlay.color = mix_color_from_reagents(reagents.reagent_list) + . += filling_overlay + +/obj/item/reagent_containers/hypospray/medipen/universal/lowpressure/inject(mob/living/affected_mob, mob/user) + // Calculate quantity to inject, depending on if the user is on lavaland. + if(lavaland_equipment_pressure_check(get_turf(user))) + amount_per_transfer_from_this = initial(amount_per_transfer_from_this) + else + if(DOING_INTERACTION(user, DOAFTER_SOURCE_SURVIVALPEN)) + to_chat(user,span_notice("You are too busy to use \the [src]!")) + return + + to_chat(user,span_notice("You start manually releasing the low-pressure gauge...")) + if(!do_after(user, 10 SECONDS, affected_mob, interaction_key = DOAFTER_SOURCE_SURVIVALPEN)) + return + + amount_per_transfer_from_this = initial(amount_per_transfer_from_this) * 0.5 + + // Attempt the injection + . = ..() + // Workaround to update icon and overlay after partial injection + if(. && !used_up) + update_appearance() diff --git a/modular_nova/modules/lathe_medipens/code/medbay_nodes.dm b/modular_nova/modules/lathe_medipens/code/medbay_nodes.dm new file mode 100644 index 00000000000..e2b3339fea0 --- /dev/null +++ b/modular_nova/modules/lathe_medipens/code/medbay_nodes.dm @@ -0,0 +1,16 @@ +/datum/techweb_node/medbay_medipens + id = TECHWEB_NODE_MEDBAY_MEDIPENS + display_name = "Auto-Injecting 'Medipen' Syringes" + description = "Advanced auto-injecting syringes, or 'medipens'. Used for automatically injecting medications." + prereq_ids = list(TECHWEB_NODE_CHEM_SYNTHESIS) + design_ids = list( + "medipen_universal", + "medipen_universal_lowpressure", + "medipen_epinephrine", + "medipen_atropine", + "medipen_salbutamol", + "medipen_oxandrolone", + "medipen_salacid", + "medipen_penacid", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) diff --git a/modular_nova/modules/lathe_medipens/icons/medical_lefthand.dmi b/modular_nova/modules/lathe_medipens/icons/medical_lefthand.dmi new file mode 100644 index 00000000000..8414511a452 Binary files /dev/null and b/modular_nova/modules/lathe_medipens/icons/medical_lefthand.dmi differ diff --git a/modular_nova/modules/lathe_medipens/icons/medical_righthand.dmi b/modular_nova/modules/lathe_medipens/icons/medical_righthand.dmi new file mode 100644 index 00000000000..c55f0af5f12 Binary files /dev/null and b/modular_nova/modules/lathe_medipens/icons/medical_righthand.dmi differ diff --git a/modular_nova/modules/lathe_medipens/icons/reagent_fillings.dmi b/modular_nova/modules/lathe_medipens/icons/reagent_fillings.dmi new file mode 100644 index 00000000000..f6429080333 Binary files /dev/null and b/modular_nova/modules/lathe_medipens/icons/reagent_fillings.dmi differ diff --git a/modular_nova/modules/lathe_medipens/icons/syringe.dmi b/modular_nova/modules/lathe_medipens/icons/syringe.dmi new file mode 100644 index 00000000000..ea831fb2739 Binary files /dev/null and b/modular_nova/modules/lathe_medipens/icons/syringe.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 14f3ecd3edc..b7f57a97821 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7008,6 +7008,7 @@ #include "modular_nova\master_files\code\modules\reagents\chemistry\reagents.dm" #include "modular_nova\master_files\code\modules\reagents\chemistry\recipes.dm" #include "modular_nova\master_files\code\modules\reagents\medicine_reagents\medicine_reagents.dm" +#include "modular_nova\master_files\code\modules\reagents\reagent_containers\hypospray.dm" #include "modular_nova\master_files\code\modules\reagents\withdrawal\generic_addictions.dm" #include "modular_nova\master_files\code\modules\religion\religious_sects.dm" #include "modular_nova\master_files\code\modules\research\designs\biogenerator_designs.dm" @@ -7901,6 +7902,9 @@ #include "modular_nova\modules\kahraman_equipment\code\organic_printer_designs\equipment.dm" #include "modular_nova\modules\kahraman_equipment\code\organic_printer_designs\resources.dm" #include "modular_nova\modules\knives\knives.dm" +#include "modular_nova\modules\lathe_medipens\code\autolathe_designs.dm" +#include "modular_nova\modules\lathe_medipens\code\hypospray.dm" +#include "modular_nova\modules\lathe_medipens\code\medbay_nodes.dm" #include "modular_nova\modules\layer_shift\code\mob_movement.dm" #include "modular_nova\modules\liquids\code\drains.dm" #include "modular_nova\modules\liquids\code\height_floors.dm"