mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 03:57:48 +01:00
Improves the bioprinter
This commit is contained in:
@@ -1,84 +1,266 @@
|
||||
//These machines are mostly just here for debugging/spawning. Skeletons of the feature to come.
|
||||
// GENERIC PRINTER - DO NOT USE THIS OBJECT.
|
||||
// Flesh and robot printers are defined below this object.
|
||||
|
||||
/obj/machinery/bioprinter
|
||||
name = "organ bioprinter"
|
||||
desc = "It's a machine that grows replacement organs."
|
||||
/obj/machinery/organ_printer
|
||||
name = "organ printer"
|
||||
desc = "It's a machine that prints organs."
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "bioprinter"
|
||||
|
||||
anchored = 1
|
||||
density = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
active_power_usage = 300
|
||||
|
||||
icon_state = "bioprinter"
|
||||
|
||||
var/prints_prosthetics
|
||||
var/stored_matter = 200
|
||||
var/stored_matter = 0
|
||||
var/max_stored_matter = 0
|
||||
var/print_delay = 100
|
||||
var/printing
|
||||
var/loaded_dna //Blood sample for DNA hashing.
|
||||
|
||||
// These should be subtypes of /obj/item/organ
|
||||
var/list/products = list(
|
||||
O_HEART = list(/obj/item/organ/internal/heart, 50),
|
||||
O_LUNGS = list(/obj/item/organ/internal/lungs, 40),
|
||||
O_KIDNEYS = list(/obj/item/organ/internal/kidneys,20),
|
||||
O_EYES = list(/obj/item/organ/internal/eyes, 30),
|
||||
O_LIVER = list(/obj/item/organ/internal/liver, 50)
|
||||
"Heart" = list(/obj/item/organ/internal/heart, 25),
|
||||
"Lungs" = list(/obj/item/organ/internal/lungs, 25),
|
||||
"Kidneys" = list(/obj/item/organ/internal/kidneys,20),
|
||||
"Eyes" = list(/obj/item/organ/internal/eyes, 20),
|
||||
"Liver" = list(/obj/item/organ/internal/liver, 25),
|
||||
"Arm, Left" = list(/obj/item/organ/external/arm, 65),
|
||||
"Arm, Right" = list(/obj/item/organ/external/arm/right, 65),
|
||||
"Leg, Left" = list(/obj/item/organ/external/leg, 65),
|
||||
"Leg, Right" = list(/obj/item/organ/external/leg/right, 65),
|
||||
"Foot, Left" = list(/obj/item/organ/external/foot, 40),
|
||||
"Foot, Right" = list(/obj/item/organ/external/foot/right, 40),
|
||||
"Hand, Left" = list(/obj/item/organ/external/hand, 40),
|
||||
"Hand, Right" = list(/obj/item/organ/external/hand/right, 40)
|
||||
)
|
||||
|
||||
/obj/machinery/bioprinter/prosthetics
|
||||
name = "prosthetics fabricator"
|
||||
desc = "It's a machine that prints prosthetic organs."
|
||||
prints_prosthetics = 1
|
||||
/obj/machinery/organ_printer/attackby(var/obj/item/O, var/mob/user)
|
||||
if(default_deconstruction_screwdriver(user, O))
|
||||
updateUsrDialog()
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, O))
|
||||
return
|
||||
if(default_part_replacement(user, O))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/bioprinter/attack_hand(mob/user)
|
||||
/obj/machinery/organ_printer/update_icon()
|
||||
overlays.Cut()
|
||||
if(panel_open)
|
||||
overlays += "bioprinter_panel_open"
|
||||
if(printing)
|
||||
overlays += "bioprinter_working"
|
||||
|
||||
var/choice = input("What would you like to print?") as null|anything in products
|
||||
if(!choice)
|
||||
/obj/machinery/organ_printer/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/organ_printer/examine(var/mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>It is loaded with [stored_matter]/[max_stored_matter] matter units.</span>")
|
||||
|
||||
/obj/machinery/organ_printer/RefreshParts()
|
||||
print_delay = initial(print_delay)
|
||||
max_stored_matter = 0
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/bin in component_parts)
|
||||
max_stored_matter += bin.rating * 100
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/manip in component_parts)
|
||||
print_delay -= (manip.rating-1)*10
|
||||
print_delay = max(0,print_delay)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/organ_printer/attack_hand(mob/user)
|
||||
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
if(stored_matter >= products[choice][2])
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='warning'>Close the panel first!</span>")
|
||||
return
|
||||
|
||||
stored_matter -= products[choice][2]
|
||||
var/new_organ = products[choice][1]
|
||||
var/obj/item/organ/O = new new_organ(get_turf(src))
|
||||
if(printing)
|
||||
to_chat(user, "<span class='notice'>\The [src] is busy!</span>")
|
||||
return
|
||||
|
||||
if(prints_prosthetics)
|
||||
O.robotize()
|
||||
else if(loaded_dna)
|
||||
visible_message("<span class='notice'>The printer injects the stored DNA into the biomass.</span>.")
|
||||
O.transplant_data = list()
|
||||
var/mob/living/carbon/C = loaded_dna["donor"]
|
||||
O.transplant_data["species"] = C.species.name
|
||||
O.transplant_data["blood_type"] = loaded_dna["blood_type"]
|
||||
O.transplant_data["blood_DNA"] = loaded_dna["blood_DNA"]
|
||||
var/choice = input("What would you like to print?") as null|anything in products
|
||||
|
||||
visible_message("<span class='info'>The bioprinter spits out a new organ.</span>")
|
||||
if(!choice || printing || (stat & (BROKEN|NOPOWER)))
|
||||
return
|
||||
|
||||
else
|
||||
user << "<span class='warning'>There is not enough matter in the printer.</span>"
|
||||
if(!can_print(choice))
|
||||
return
|
||||
|
||||
/obj/machinery/bioprinter/attackby(obj/item/weapon/W, mob/user)
|
||||
stored_matter -= products[choice][2]
|
||||
|
||||
// DNA sample from syringe.
|
||||
if(!prints_prosthetics && istype(W,/obj/item/weapon/reagent_containers/syringe))
|
||||
use_power = 2
|
||||
printing = 1
|
||||
update_icon()
|
||||
|
||||
visible_message("<span class='notice'>\The [src] begins churning.</span>")
|
||||
|
||||
sleep(print_delay)
|
||||
|
||||
use_power = 1
|
||||
printing = 0
|
||||
update_icon()
|
||||
|
||||
if(!choice || !src || (stat & (BROKEN|NOPOWER)))
|
||||
return
|
||||
|
||||
print_organ(choice)
|
||||
|
||||
/obj/machinery/organ_printer/proc/can_print(var/choice)
|
||||
if(stored_matter < products[choice][2])
|
||||
visible_message("<span class='notice'>\The [src] displays a warning: 'Not enough matter. [stored_matter] stored and [products[choice][2]] needed.'</span>")
|
||||
return 0
|
||||
|
||||
if(!loaded_dna || !loaded_dna["donor"])
|
||||
visible_message("<span class='info'>\The [src] displays a warning: 'No DNA saved. Insert a blood sample.'</span>")
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/organ_printer/proc/print_organ(var/choice)
|
||||
var/new_organ = products[choice][1]
|
||||
var/obj/item/organ/O = new new_organ(get_turf(src))
|
||||
O.status |= ORGAN_CUT_AWAY
|
||||
var/mob/living/carbon/C = loaded_dna["donor"]
|
||||
O.set_dna(C.dna)
|
||||
|
||||
if(O.species)
|
||||
// This is a very hacky way of doing of what organ/New() does if it has an owner
|
||||
O.w_class = max(O.w_class + mob_size_difference(O.species.mob_size, MOB_MEDIUM), 1)
|
||||
|
||||
return O
|
||||
// END GENERIC PRINTER
|
||||
|
||||
// CIRCUITS
|
||||
/obj/item/weapon/circuitboard/bioprinter
|
||||
name = "bioprinter circuit"
|
||||
build_path = /obj/machinery/organ_printer/flesh
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
origin_tech = list(TECH_DATA = 3, TECH_BIO = 3)
|
||||
req_components = list(
|
||||
/obj/item/stack/cable_coil = 2,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 2,
|
||||
/obj/item/weapon/stock_parts/manipulator = 2)
|
||||
|
||||
/obj/item/weapon/circuitboard/roboprinter
|
||||
name = "roboprinter circuit"
|
||||
build_path = /obj/machinery/organ_printer/robot
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
origin_tech = list(TECH_DATA = 3, TECH_BIO = 3)
|
||||
req_components = list(
|
||||
/obj/item/stack/cable_coil = 2,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 2,
|
||||
/obj/item/weapon/stock_parts/manipulator = 2)
|
||||
|
||||
// ROBOT ORGAN PRINTER
|
||||
// Still Requires DNA, /obj/machinery/pros_fab is better for limbs
|
||||
/obj/machinery/organ_printer/robot
|
||||
name = "prosthetic organ fabricator"
|
||||
desc = "It's a machine that prints prosthetic organs."
|
||||
icon_state = "roboprinter"
|
||||
circuit = /obj/item/weapon/circuitboard/roboprinter
|
||||
|
||||
var/matter_amount_per_sheet = 10
|
||||
var/matter_type = DEFAULT_WALL_MATERIAL
|
||||
|
||||
/obj/machinery/organ_printer/robot/full/New()
|
||||
. = ..()
|
||||
stored_matter = max_stored_matter
|
||||
|
||||
/obj/machinery/organ_printer/robot/dismantle()
|
||||
if(stored_matter >= matter_amount_per_sheet)
|
||||
new /obj/item/stack/material/steel(get_turf(src), Floor(stored_matter/matter_amount_per_sheet))
|
||||
return ..()
|
||||
|
||||
/obj/machinery/organ_printer/robot/print_organ(var/choice)
|
||||
var/obj/item/organ/O = ..()
|
||||
O.robotize()
|
||||
O.status |= ORGAN_CUT_AWAY // robotize() resets status to 0
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
audible_message("<span class='info'>\The [src] dings, then spits out \a [O].</span>")
|
||||
return O
|
||||
|
||||
/obj/machinery/organ_printer/robot/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
if(istype(W, /obj/item/stack/material) && W.get_material_name() == matter_type)
|
||||
if((max_stored_matter-stored_matter) < matter_amount_per_sheet)
|
||||
to_chat(user, "<span class='warning'>\The [src] is too full.</span>")
|
||||
return
|
||||
var/obj/item/stack/S = W
|
||||
var/space_left = max_stored_matter - stored_matter
|
||||
var/sheets_to_take = min(S.amount, Floor(space_left/matter_amount_per_sheet))
|
||||
if(sheets_to_take <= 0)
|
||||
to_chat(user, "<span class='warning'>\The [src] is too full.</span>")
|
||||
return
|
||||
stored_matter = min(max_stored_matter, stored_matter + (sheets_to_take*matter_amount_per_sheet))
|
||||
to_chat(user, "<span class='info'>\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]</span>")
|
||||
S.use(sheets_to_take)
|
||||
return
|
||||
else if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actuall empty the syringe
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = W
|
||||
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
|
||||
if(injected && injected.data)
|
||||
loaded_dna = injected.data
|
||||
user << "<span class='info'>You inject the blood sample into the bioprinter.</span>"
|
||||
return
|
||||
// Meat for biomass.
|
||||
if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
|
||||
stored_matter += 50
|
||||
user.drop_item()
|
||||
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>"
|
||||
qdel(W)
|
||||
return
|
||||
// Steel for matter.
|
||||
if(prints_prosthetics && istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL)
|
||||
var/obj/item/stack/S = W
|
||||
stored_matter += S.amount * 10
|
||||
user.drop_item()
|
||||
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]</span>"
|
||||
qdel(W)
|
||||
to_chat(user, "<span class='info'>You scan the blood sample into the bioprinter.</span>")
|
||||
return
|
||||
return ..()
|
||||
// END ROBOT ORGAN PRINTER
|
||||
|
||||
return..()
|
||||
// FLESH ORGAN PRINTER
|
||||
/obj/machinery/organ_printer/flesh
|
||||
name = "bioprinter"
|
||||
desc = "It's a machine that prints replacement organs."
|
||||
icon_state = "bioprinter"
|
||||
circuit = /obj/item/weapon/circuitboard/bioprinter
|
||||
|
||||
var/amount_per_slab = 50
|
||||
|
||||
/obj/machinery/organ_printer/flesh/full/New()
|
||||
. = ..()
|
||||
stored_matter = max_stored_matter
|
||||
|
||||
/obj/machinery/organ_printer/flesh/dismantle()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
while(stored_matter >= amount_per_slab)
|
||||
stored_matter -= amount_per_slab
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat(T)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/organ_printer/flesh/print_organ(var/choice)
|
||||
var/obj/item/organ/O = ..()
|
||||
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
visible_message("<span class='info'>\The [src] dings, then spits out \a [O].</span>")
|
||||
return O
|
||||
|
||||
/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user)
|
||||
// Load with matter for printing.
|
||||
if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
|
||||
if((max_stored_matter - stored_matter) < amount_per_slab)
|
||||
to_chat(user, "<span class='warning'>\The [src] is too full.</span>")
|
||||
return
|
||||
stored_matter += amount_per_slab
|
||||
user.drop_item()
|
||||
to_chat(user, "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>")
|
||||
qdel(W)
|
||||
return
|
||||
// DNA sample from syringe.
|
||||
else if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = W
|
||||
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
|
||||
if(injected && injected.data)
|
||||
loaded_dna = injected.data
|
||||
to_chat(user, "<span class='info'>You scan the blood sample into the bioprinter.</span>")
|
||||
return
|
||||
return ..()
|
||||
// END FLESH ORGAN PRINTER
|
||||
@@ -78,8 +78,9 @@ var/list/organ_cache = list()
|
||||
/obj/item/organ/proc/set_dna(var/datum/dna/new_dna)
|
||||
if(new_dna)
|
||||
dna = new_dna.Clone()
|
||||
blood_DNA.Cut()
|
||||
blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
if(blood_DNA)
|
||||
blood_DNA.Cut()
|
||||
blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
|
||||
/obj/item/organ/proc/die()
|
||||
if(robotic >= ORGAN_ROBOT)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 21 KiB |
Reference in New Issue
Block a user