diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm
index d0b83ffaeb..08d98d496a 100644
--- a/code/datums/autolathe/autolathe.dm
+++ b/code/datums/autolathe/autolathe.dm
@@ -107,4 +107,4 @@ var/global/datum/category_collection/autolathe/autolathe_recipes
var/man_rating = 0
/datum/category_item/autolathe/dd_SortValue()
- return name
\ No newline at end of file
+ return name
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 51e76df29d..ab2bda1a00 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -39,7 +39,6 @@
for(var/Name in name_to_material)
if(Name in materials)
continue
-
materials[Name] = 0
storage_capacity[Name] = 0
@@ -367,4 +366,4 @@
/obj/machinery/autolathe/dismantle()
eject_materials() //obj/machinery proc, in machinery/machinery.dm
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index ccad12978b..4a85660c84 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -513,14 +513,54 @@ Class Procs:
return
/obj/machinery/proc/eject_material_of_type(var/incoming_material) //Used for autolathe, protolathe, mechfab, exofab. Stuff that takes materials, basically.
- if(!LAZYLEN(materials[incoming_material]))
+ if(!LAZYACCESS(materials, incoming_material))
return
var/datum/material/M = get_material_by_name(incoming_material)
if(!istype(M))
return
-
while(materials[incoming_material] > M.perunit)
var/obj/item/stack/material/S = new M.stack_type(get_turf(src))
S.amount = min(round(materials[incoming_material] / S.perunit), S.max_amount)
materials[incoming_material] -= (S.amount * S.perunit)
return
+
+// 0 amount = 0 means ejecting a full stack; -1 means eject everything
+/obj/machinery/proc/eject_materials_partial(var/material, var/amount)
+
+ // Does the mat we want to dump exist?
+ var/matstring = lowertext(material)
+ var/datum/material/M = matstring && get_material_by_name(matstring)
+ if(!istype(M))
+ return
+
+ // If we're dumping the entire cache we can just use the general proc.
+ if(amount == -1 && materials[matstring] >= M.perunit)
+ eject_material_of_type(matstring)
+ return
+
+ // Get our stack place type for metadata retrieval via initial()
+ // Does this mat even have an ejectable stack form?
+ var/obj/item/stack/material/S = M.get_place_stack_type()
+ if(!ispath(S, /obj/item/stack))
+ return
+
+ // Place the maximum available based on the material store, or the target amount, whichever is lower (to avoid duplicating mats)
+ if(amount <= 0)
+ amount = initial(S.max_amount)
+ amount = clamp(amount, 0, round(materials[matstring] / initial(S.perunit)))
+
+ // Can we actually eject a viable sheet object?
+ if(amount <= 0)
+ return
+
+ // Fire it out the chute, ptooie.
+ S = M.place_sheet(get_turf(src), amount)
+ if(istype(S) && !QDELETED(S))
+ materials[matstring] = max(0, materials[matstring] - round(S.amount * S.perunit))
+
+ // Refresh our queue (if we handle queues; see below)
+ refresh_queue()
+
+// Stub for above proc. Implemented on exosuit fabricators and prosthetics fabricators.
+/obj/machinery/proc/refresh_queue()
+ return
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index c234b20f09..9528595315 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -38,9 +38,7 @@
for(var/Name in name_to_material)
if(Name in materials)
continue
-
hidden_materials |= Name
-
materials[Name] = 0
default_apply_parts()
@@ -175,7 +173,7 @@
S.use(1)
count++
to_chat(user, "You insert [count] [sname] into the fabricator.")
- update_busy()
+ refresh_queue()
else
to_chat(user, "The fabricator cannot hold more [sname].")
@@ -202,7 +200,7 @@
if(1)
visible_message("[bicon(src)] [src] beeps: \"No records in User DB\"")
-/obj/machinery/mecha_part_fabricator/proc/update_busy()
+/obj/machinery/mecha_part_fabricator/refresh_queue()
if(queue.len)
if(can_build(queue[1]))
busy = 1
@@ -217,13 +215,13 @@
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(var/index)
var/datum/design/D = files.known_designs[index]
queue += D
- update_busy()
+ refresh_queue()
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(var/index)
if(index == 1)
progress = 0
queue.Cut(index, index + 1)
- update_busy()
+ refresh_queue()
/obj/machinery/mecha_part_fabricator/proc/can_build(var/datum/design/D)
for(var/M in D.materials)
@@ -307,22 +305,3 @@
files.RefreshResearch()
sync_message = "Sync complete."
update_categories()
-
-/obj/machinery/mecha_part_fabricator/proc/eject_materials_partial(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything
- var/recursive = amount == -1
- var/matstring = lowertext(material)
- var/datum/material/M = get_material_by_name(matstring)
- if(recursive && materials[matstring] >= M.perunit)
- eject_material_of_type(matstring)
- return
-
- var/obj/item/stack/material/S = M.place_sheet(get_turf(src))
- if(amount <= 0)
- amount = S.max_amount
- var/ejected = min(round(materials[matstring] / S.perunit), amount)
- S.amount = min(ejected, amount)
- if(S.amount <= 0)
- qdel(S)
- return
- materials[matstring] -= ejected * S.perunit
- update_busy()
diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm
index 72cb78bbe2..e56410f138 100644
--- a/code/game/mecha/mech_prosthetics.dm
+++ b/code/game/mecha/mech_prosthetics.dm
@@ -208,7 +208,7 @@
S.use(1)
count++
to_chat(user, "You insert [count] [sname] into the fabricator.")
- update_busy()
+ refresh_queue()
else
to_chat(user, "The fabricator cannot hold more [sname].")
@@ -235,7 +235,7 @@
if(1)
visible_message("[bicon(src)] [src] beeps: \"No records in User DB\"")
-/obj/machinery/pros_fabricator/proc/update_busy()
+/obj/machinery/pros_fabricator/refresh_queue()
if(queue.len)
if(can_build(queue[1]))
busy = 1
@@ -250,13 +250,13 @@
/obj/machinery/pros_fabricator/proc/add_to_queue(var/index)
var/datum/design/D = files.known_designs[index]
queue += D
- update_busy()
+ refresh_queue()
/obj/machinery/pros_fabricator/proc/remove_from_queue(var/index)
if(index == 1)
progress = 0
queue.Cut(index, index + 1)
- update_busy()
+ refresh_queue()
/obj/machinery/pros_fabricator/proc/can_build(var/datum/design/D)
for(var/M in D.materials)
@@ -340,23 +340,3 @@
files.RefreshResearch()
sync_message = "Sync complete."
update_categories()
-
-/obj/machinery/pros_fabricator/proc/eject_materials_partial(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything
- var/recursive = amount == -1 ? 1 : 0
- var/matstring = lowertext(material)
- var/datum/material/M = get_material_by_name(matstring)
-
- if(recursive && materials[matstring] >= M.perunit)
- eject_material_of_type(matstring)
- return
-
- var/obj/item/stack/material/S = M.place_sheet(get_turf(src))
- if(amount <= 0)
- amount = S.max_amount
- var/ejected = min(round(materials[matstring] / S.perunit), amount)
- S.amount = min(ejected, amount)
- if(S.amount <= 0)
- qdel(S)
- return
- materials[matstring] -= ejected * S.perunit
- update_busy()
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index e9d6d18f0b..950789b9d9 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -227,7 +227,7 @@
to_chat(user, "There isn't enough material here to construct a wall.")
return 0
- var/datum/material/M = name_to_material[S.default_type]
+ var/datum/material/M = get_material_by_name(S.default_type)
if(!istype(M))
return 0
@@ -268,7 +268,7 @@
to_chat(user, "There isn't enough material here to reinforce the girder.")
return 0
- var/datum/material/M = name_to_material[S.default_type]
+ var/datum/material/M = get_material_by_name(S.default_type)
if(!istype(M) || M.integrity < 50)
to_chat(user, "You cannot reinforce \the [src] with that; it is too soft.")
return 0
@@ -402,7 +402,7 @@
var/turf/simulated/wall/new_T = get_turf(src) // Ref to the wall we just built.
// Apparently set_material(...) for walls requires refs to the material singletons and not strings.
// This is different from how other material objects with their own set_material(...) do it, but whatever.
- var/datum/material/M = name_to_material[the_rcd.material_to_use]
+ var/datum/material/M = get_material_by_name(the_rcd.material_to_use)
new_T.set_material(M, the_rcd.make_rwalls ? M : null, girder_material)
new_T.add_hiddenprint(user)
qdel(src)
@@ -412,4 +412,3 @@
to_chat(user, span("notice", "You deconstruct \the [src]."))
qdel(src)
return TRUE
-
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 42e2fcf1a1..476241ce9e 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -218,7 +218,7 @@
var/turf/simulated/wall/T = get_turf(src) // Ref to the wall we just built.
// Apparently set_material(...) for walls requires refs to the material singletons and not strings.
// This is different from how other material objects with their own set_material(...) do it, but whatever.
- var/datum/material/M = name_to_material[the_rcd.material_to_use]
+ var/datum/material/M = get_material_by_name(the_rcd.material_to_use)
T.set_material(M, the_rcd.make_rwalls ? M : null, M)
T.add_hiddenprint(user)
return TRUE
diff --git a/code/modules/materials/materials/_materials.dm b/code/modules/materials/materials/_materials.dm
index 31e6f52ce4..9b8b72f472 100644
--- a/code/modules/materials/materials/_materials.dm
+++ b/code/modules/materials/materials/_materials.dm
@@ -62,6 +62,7 @@ var/global/list/name_to_material
// Safety proc to make sure the material list exists before trying to grab from it.
/proc/get_material_by_name(name)
+ name = lowertext(name)
if(!name_to_material)
populate_material_list()
return name_to_material[name]
@@ -227,10 +228,14 @@ var/global/list/name_to_material
/datum/material/proc/place_dismantled_product(var/turf/target)
place_sheet(target)
+/datum/material/proc/get_place_stack_type()
+ return stack_type
+
// Debris product. Used ALL THE TIME.
-/datum/material/proc/place_sheet(var/turf/target)
- if(stack_type)
- return new stack_type(target)
+/datum/material/proc/place_sheet(var/turf/target, var/amount)
+ var/place_stack_type = get_place_stack_type()
+ if(place_stack_type)
+ return new place_stack_type(target, amount)
// As above.
/datum/material/proc/place_shard(var/turf/target)
diff --git a/code/modules/materials/materials/metals/hull.dm b/code/modules/materials/materials/metals/hull.dm
index caf8f13de7..8c113afbe0 100644
--- a/code/modules/materials/materials/metals/hull.dm
+++ b/code/modules/materials/materials/metals/hull.dm
@@ -7,8 +7,8 @@
icon_reinf = "reinf_mesh"
icon_colour = "#666677"
-/datum/material/steel/hull/place_sheet(var/turf/target) //Deconstructed into normal steel sheets.
- new /obj/item/stack/material/steel(target)
+/datum/material/steel/hull/get_place_stack_type() //Deconstructed into normal steel sheets.
+ return /obj/item/stack/material/steel
/datum/material/plasteel/hull
name = MAT_PLASTEELHULL
@@ -19,8 +19,8 @@
icon_colour = "#777788"
explosion_resistance = 40
-/datum/material/plasteel/hull/place_sheet(var/turf/target) //Deconstructed into normal plasteel sheets.
- new /obj/item/stack/material/plasteel(target)
+/datum/material/plasteel/hull/get_place_stack_type() //Deconstructed into normal plasteel sheets.
+ return /obj/item/stack/material/plasteel
/datum/material/durasteel/hull //The 'Hardball' of starship hulls.
name = MAT_DURASTEELHULL
@@ -31,8 +31,8 @@
explosion_resistance = 90
reflectivity = 0.9
-/datum/material/durasteel/hull/place_sheet(var/turf/target) //Deconstructed into normal durasteel sheets.
- new /obj/item/stack/material/durasteel(target)
+/datum/material/durasteel/hull/get_place_stack_type() //Deconstructed into normal durasteel sheets.
+ return /obj/item/stack/material/durasteel
/datum/material/titanium/hull
name = MAT_TITANIUMHULL
@@ -40,8 +40,8 @@
icon_base = "hull"
icon_reinf = "reinf_mesh"
-/datum/material/titanium/hull/place_sheet(var/turf/target) //Deconstructed into normal titanium sheets.
- new /obj/item/stack/material/titanium(target)
+/datum/material/titanium/hull/get_place_stack_type() //Deconstructed into normal titanium sheets.
+ return /obj/item/stack/material/titanium
/datum/material/morphium/hull
name = MAT_MORPHIUMHULL
@@ -49,5 +49,5 @@
icon_base = "hull"
icon_reinf = "reinf_mesh"
-/datum/material/morphium/hull/place_sheet(var/turf/target)
- new /obj/item/stack/material/morphium(target)
\ No newline at end of file
+/datum/material/morphium/hull/get_place_stack_type()
+ return /obj/item/stack/material/morphium
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index c946f9db7c..a8774af291 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -31,9 +31,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
for(var/Name in name_to_material)
if(Name in materials)
continue
-
hidden_materials |= Name
-
materials[Name] = 0
default_apply_parts()
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index de51f73c6c..19d49ede8e 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -26,9 +26,7 @@
for(var/Name in name_to_material)
if(Name in materials)
continue
-
hidden_materials |= Name
-
materials[Name] = 0
default_apply_parts()
@@ -209,4 +207,4 @@
if(mat_efficiency != 1) // No matter out of nowhere
if(new_item.matter && new_item.matter.len > 0)
for(var/i in new_item.matter)
- new_item.matter[i] = new_item.matter[i] * mat_efficiency
\ No newline at end of file
+ new_item.matter[i] = new_item.matter[i] * mat_efficiency