mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-07 23:42:44 +00:00
* Improves upon setting custom materials for printed items (#81015) ## About The Pull Request This is an improvement on #80839 regarding how custom materials are set on items, it's based on the following findings. 1. `set_custom_materials()` proc already comes with an prebuilt `multiplier` var1e8d511946/code/game/atom/atom_materials.dm (L11)This means we can pass the machine's cost coefficiency directly to this proc rather than creating our own list of materials with their values scaled by the factor like so1e8d511946/code/game/machinery/autolathe.dm (L192-L193)We can instead just do `set_custom_materials(design.materials, material_cost_coefficient)` without ever needing this list, thus making code cleaner, with that the changes propogate to how `has_materials()` & `use_materials()` procs are also used as we can now use their `coefficiency` param rather than seeing it go to waste 2. All items custom materials will now always be integer values. With this `SSmaterials.FindOrCreateMaterialCombo` now has better performance because when computing the key for caching values like `1.5` or `1.7` it will become just `1` and will point to the same cache thus reducing memory usage 3. Materials are now uniformly split among all the contents of a printed item from techfab or autolathe. What this means is items like the foam ammo box printed from autolathe will have both the ammo case and their 40 bullets each set with custom materials such that their final sum becomes equal to the design cost. For info on how that's done see the documentation of `split_materials_uniformly` proc. One downside of this proc is when items have a very small amount of `custom_materials`(less than 2). In that case values like `0.8` or `1.5` or `1.7` ends up getting rounded to 1 which means you end up getting less materials when recycling than what you used for printing that item. In this case You get 0.48 iron from both the box & it's ammo instead of 0.79 iron used for printing in tier1 autolathe(Or 0.50 for tier4 autolathe). This shouldn't be an issue as you still can't make any profits from this but at least everything in the box is now recyclable. ## Changelog 🆑 fix: items that contain recursive contents inside them (like foam dart boxes from autolathes) now have their custom materials set to match with its design cost rather than being nullified, meaning they are now recyclable. code: all custom materials are now integer values. Improved code for how materials are used in techfab & auto lathe for printing /🆑 * Improves upon setting custom materials for printed items --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
127 lines
4.9 KiB
Plaintext
127 lines
4.9 KiB
Plaintext
/atom
|
|
///The custom materials this atom is made of, used by a lot of things like furniture, walls, and floors (if I finish the functionality, that is.)
|
|
///The list referenced by this var can be shared by multiple objects and should not be directly modified. Instead, use [set_custom_materials][/atom/proc/set_custom_materials].
|
|
var/list/datum/material/custom_materials
|
|
///Bitfield for how the atom handles materials.
|
|
var/material_flags = NONE
|
|
///Modifier that raises/lowers the effect of the amount of a material, prevents small and easy to get items from being death machines.
|
|
var/material_modifier = 1
|
|
|
|
/// Sets the custom materials for an item.
|
|
/atom/proc/set_custom_materials(list/materials, multiplier = 1)
|
|
if(custom_materials && material_flags & MATERIAL_EFFECTS) //Only runs if custom materials existed at first and affected src.
|
|
for(var/current_material in custom_materials)
|
|
var/datum/material/custom_material = GET_MATERIAL_REF(current_material)
|
|
custom_material.on_removed(src, OPTIMAL_COST(custom_materials[current_material] * material_modifier), material_flags) //Remove the current materials
|
|
|
|
if(!length(materials))
|
|
custom_materials = null
|
|
return
|
|
|
|
if(material_flags & MATERIAL_EFFECTS)
|
|
for(var/current_material in materials)
|
|
var/datum/material/custom_material = GET_MATERIAL_REF(current_material)
|
|
custom_material.on_applied(src, OPTIMAL_COST(materials[current_material] * multiplier * material_modifier), material_flags)
|
|
|
|
custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials, multiplier)
|
|
|
|
/**
|
|
* Returns the material composition of the atom.
|
|
*
|
|
* Used when recycling items, specifically to turn alloys back into their component mats.
|
|
*
|
|
* Exists because I'd need to add a way to un-alloy alloys or otherwise deal
|
|
* with people converting the entire stations material supply into alloys.
|
|
*
|
|
* Arguments:
|
|
* - flags: A set of flags determining how exactly the materials are broken down.
|
|
*/
|
|
/atom/proc/get_material_composition()
|
|
. = list()
|
|
|
|
var/list/cached_materials = custom_materials
|
|
for(var/mat in cached_materials)
|
|
var/datum/material/material = GET_MATERIAL_REF(mat)
|
|
var/list/material_comp = material.return_composition(cached_materials[mat])
|
|
for(var/comp_mat in material_comp)
|
|
.[comp_mat] += material_comp[comp_mat]
|
|
|
|
/**
|
|
* Fetches a list of all of the materials this object has of the desired type. Returns null if there is no valid materials of the type
|
|
*
|
|
* Arguments:
|
|
* - [required_material][/datum/material]: The type of material we are checking for
|
|
* - mat_amount: The minimum required amount of material
|
|
*/
|
|
/atom/proc/has_material_type(datum/material/required_material, mat_amount = 0)
|
|
var/list/cached_materials = custom_materials
|
|
if(!length(cached_materials))
|
|
return null
|
|
|
|
var/materials_of_type
|
|
for(var/current_material in cached_materials)
|
|
if(cached_materials[current_material] < mat_amount)
|
|
continue
|
|
var/datum/material/material = GET_MATERIAL_REF(current_material)
|
|
if(!istype(material, required_material))
|
|
continue
|
|
LAZYSET(materials_of_type, material, cached_materials[current_material])
|
|
|
|
return materials_of_type
|
|
|
|
/**
|
|
* Fetches a list of all of the materials this object has with the desired material category.
|
|
*
|
|
* Arguments:
|
|
* - category: The category to check for
|
|
* - any_flags: Any bitflags that must be present for the category
|
|
* - all_flags: All bitflags that must be present for the category
|
|
* - no_flags: Any bitflags that must not be present for the category
|
|
* - mat_amount: The minimum amount of materials that must be present
|
|
*/
|
|
/atom/proc/has_material_category(category, any_flags=0, all_flags=0, no_flags=0, mat_amount=0)
|
|
var/list/cached_materials = custom_materials
|
|
if(!length(cached_materials))
|
|
return null
|
|
|
|
var/materials_of_category
|
|
for(var/current_material in cached_materials)
|
|
if(cached_materials[current_material] < mat_amount)
|
|
continue
|
|
var/datum/material/material = GET_MATERIAL_REF(current_material)
|
|
var/category_flags = material?.categories[category]
|
|
if(isnull(category_flags))
|
|
continue
|
|
if(any_flags && !(category_flags & any_flags))
|
|
continue
|
|
if(all_flags && (all_flags != (category_flags & all_flags)))
|
|
continue
|
|
if(no_flags && (category_flags & no_flags))
|
|
continue
|
|
LAZYSET(materials_of_category, material, cached_materials[current_material])
|
|
return materials_of_category
|
|
|
|
/**
|
|
* Gets the most common material in the object.
|
|
*/
|
|
/atom/proc/get_master_material()
|
|
var/list/cached_materials = custom_materials
|
|
if(!length(cached_materials))
|
|
return null
|
|
|
|
var/most_common_material = null
|
|
var/max_amount = 0
|
|
for(var/material in cached_materials)
|
|
if(cached_materials[material] > max_amount)
|
|
most_common_material = material
|
|
max_amount = cached_materials[material]
|
|
|
|
if(most_common_material)
|
|
return GET_MATERIAL_REF(most_common_material)
|
|
|
|
/**
|
|
* Gets the total amount of materials in this atom.
|
|
*/
|
|
/atom/proc/get_custom_material_amount()
|
|
return isnull(custom_materials) ? 0 : counterlist_sum(custom_materials)
|