mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-28 15:47:15 +01:00
Implementing materials checks for techweb designs. (#96257)
## About The Pull Request In similar fashion to what was done with crafting recipes last year, this year it's time for techweb designs and printed items to be audited. This is mostly just about consistency, we've a lot of items that can be printed by protolathes, autolathes, circuit printers and techfab etc. However they almost all (except most stacks, mainly) have custom materials that do not match in one way or another with the materials used by the design, which is what this PR is for. "But items printed from lathes etc. already get the mats used to make them." Yes, they do, however that isn't the case for items of the same type that were spawned in some other way (cargo shuttle, space/maints loot, mapped, admins), this create a subtle discrepancy. It isn't a huge deal (in spite of the size of this PR, ton of designs), but given that I have done something similar with crafting recipes before, I may as well give it a second arc of some sort and bring things to completion. And fix a few possible oversights. TL;DR consistency and stuff ## Why It's Good For The Game Consistency, unit test checks to make it harder not to be consistent in the future. Still has a few TODOs like: - [x] Fixed newly printed, fully charged RCDs costing less than the RCD cartridges required to fully charge one. EDIT: I had to tweak the newly added RDD as well because it suffered from the same fundamental issue. - [x] Fixed plates being made of iron and yet shattering like ceramic ones. A new subtype for metallic ones has been made. ## Changelog 🆑 refactor: Refactored a few things with techweb designs (the ones for autolathes, protolathes, circuit printers, mechfabs etc.) to make sure that the materials of items that can be made from these designs more closely match the materials used to make them. fix: Lizard fries no longer need a plate to be made, like all other treats that used to require plates in a distant past. balance: Tweaked the materials cost of RCD, RDD and RCD cartridges. image: Oven trays now have a more metallic hue. balance: Plates printed printed from lathes won't shatter like ceramic ones, in virtue of them being made out of iron instead. /🆑
This commit is contained in:
@@ -161,7 +161,7 @@
|
||||
var/what_it_is = copycat.transcribe_materials_list(copycat_mats)
|
||||
//compose a text string containing the syntax and paths to use for editing the custom_materials var
|
||||
if(result.custom_materials)
|
||||
what_it_should_be += " (you can round a bit for values above 100)"
|
||||
what_it_should_be += " (you can round values above SHEET_MATERIAL_AMOUNT to the nearest decimal)"
|
||||
|
||||
|
||||
///This tells you about other ways to deal with the issue, if you can't just change the materials of the object. For example, if there are two different recipes for it.
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
//Can't use allocate because of bug with certain datums
|
||||
var/datum/design/default_design = new /datum/design()
|
||||
|
||||
for(var/path in subtypesof(/datum/design) - typesof(/datum/design/surgery)) //We are checking surgery design separatly later since they work differently
|
||||
var/datum/design/current_design = new path //Create an instance of each design
|
||||
if (current_design.id == DESIGN_ID_IGNORE) //Don't check designs with ignore ID
|
||||
continue
|
||||
for(var/design_id in SSresearch.techweb_designs) //We are checking surgery design separatly later since they work differently
|
||||
var/datum/design/current_design = SSresearch.techweb_designs[design_id]
|
||||
if(istype(current_design, /datum/design/surgery))
|
||||
return
|
||||
if (isnull(current_design.name) || current_design.name == default_design.name) //Designs with ID must have non default/null Name
|
||||
TEST_FAIL("Design [current_design.type] has default or null name var but has an ID")
|
||||
if ((!isnull(current_design.materials) && LAZYLEN(current_design.materials)) || (!isnull(current_design.reagents_list) && LAZYLEN(current_design.reagents_list))) //Design requires materials
|
||||
@@ -29,28 +29,23 @@
|
||||
if (isnull(path::desc) && isnull(path::surgery::rnd_desc) && isnull(path::surgery::desc))
|
||||
TEST_FAIL("Surgery Design [path] has no desc set or inferable from surgery type")
|
||||
|
||||
///Check that all designs have a corresponding id and viceversa, and that they're actually implemented (techweb or disks)
|
||||
/datum/unit_test/design_source
|
||||
|
||||
/datum/unit_test/design_source/Run()
|
||||
var/list/all_designs = list()
|
||||
|
||||
for (var/datum/design/design as anything in subtypesof(/datum/design))
|
||||
design = new design()
|
||||
if (design.id == DESIGN_ID_IGNORE)
|
||||
continue
|
||||
if (design.id in all_designs)
|
||||
TEST_FAIL("Design [design.type] shares an ID \"[design.id]\" with another design")
|
||||
continue
|
||||
for(var/id in SSresearch.techweb_designs)
|
||||
var/datum/design/design = SSresearch.techweb_designs[id]
|
||||
all_designs[design.id] = design.type
|
||||
|
||||
for (var/datum/techweb_node/node as anything in subtypesof(/datum/techweb_node))
|
||||
node = new node()
|
||||
for (var/node_id in SSresearch.techweb_nodes)
|
||||
var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id]
|
||||
for (var/design_id in node.design_ids)
|
||||
if (!all_designs[design_id])
|
||||
TEST_FAIL("Techweb node [node.display_name] ([node.id]) has a design_id \"[design_id]\" which doesn't correspond to any existing design!")
|
||||
continue
|
||||
all_designs -= design_id
|
||||
qdel(node)
|
||||
|
||||
// Designs can also be disk-exclusive
|
||||
for (var/obj/item/disk/design_disk/design_disk as anything in subtypesof(/obj/item/disk/design_disk))
|
||||
@@ -81,3 +76,90 @@
|
||||
|
||||
for (var/missing_id in all_designs)
|
||||
TEST_FAIL("Design [all_designs[missing_id]] has an ID \"[missing_id]\" which is not in any of the techweb nodes or tech disks, or it is possibly misconfigured!")
|
||||
|
||||
///Check that the materials present in the printed objects are consistent with the materials used in techweb design that prints said object.
|
||||
/datum/unit_test/design_mats
|
||||
|
||||
/datum/unit_test/design_mats/Run()
|
||||
var/list/special_types = typesof(/datum/material_requirement) + typesof(/datum/material_slot) //we skip designs that can be printed with non-specific materials.
|
||||
|
||||
for (var/design_id in SSresearch.techweb_designs)
|
||||
var/datum/design/design = SSresearch.techweb_designs[design_id]
|
||||
|
||||
var/mat_requirement_design = length(special_types & design.materials)
|
||||
|
||||
if(mat_requirement_design && length(design.transfered_materials))
|
||||
TEST_FAIL("'transfer_materials' doesn't work for [design.type] and other designs that have [/datum/material_slot] or [/datum/material_requirement] in their 'materials' var yet")
|
||||
continue
|
||||
|
||||
//Do not perform further checks if it doesn't have a built path, mat requirements or if it's one of those designs with choosable requirements (harder to implement checks for those)
|
||||
if(mat_requirement_design || !design.build_path || !length(design.materials))
|
||||
continue
|
||||
|
||||
if(length(design.transfered_materials))
|
||||
var/list/mats_total = list()
|
||||
for(var/object_type in design.transfered_materials)
|
||||
var/list/transfered_to_obj = design.transfered_materials[object_type]
|
||||
for(var/mat in design.transfered_materials[object_type])
|
||||
if(!(mat in design.materials))
|
||||
TEST_FAIL("Found material type [mat] in the 'transfered_materials' var of [design.type] that isn't present in its 'materials' var")
|
||||
continue
|
||||
mats_total[mat] += transfered_to_obj[mat]
|
||||
for(var/mat in mats_total)
|
||||
if(round(mats_total[mat]) > design.materials[mat]) // some sneaky weird bug may require rounding the value down
|
||||
TEST_FAIL("Amount of [mat] in the 'transfered_materials' var of [design.type] exceeds what present in its 'materials' var \
|
||||
([transcribe_mat_value_as_sheet(mats_total[mat])] vs [transcribe_mat_value_as_sheet(design.materials[mat])])")
|
||||
|
||||
//The design is exempted from the unit test if it doesn't have the standard inherit_materials val.
|
||||
if(design.inherit_materials != DESIGN_INHERIT_MATS)
|
||||
continue
|
||||
|
||||
// The object that represents the type of object that can be built from the design, though it's simple spawned in this case
|
||||
var/atom/movable/generic_instance = allocate_build_path_for_design(design.build_path)
|
||||
|
||||
// The object that represents the type of object built from the design.
|
||||
var/atom/movable/printed_instance = allocate_build_path_for_design(design.build_path)
|
||||
|
||||
design.transfer_materials(design.materials, 1, printed_instance)
|
||||
|
||||
if(generic_instance.compare_materials(printed_instance))
|
||||
continue
|
||||
|
||||
var/target_var = NAMEOF(generic_instance, custom_materials)
|
||||
var/warning = "[target_var] of [generic_instance.type] differs from the materials of [design.type]"
|
||||
|
||||
var/what_it_should_be
|
||||
var/what_it_is
|
||||
if(isstack(generic_instance))
|
||||
var/obj/item/stack/generic_stack = generic_instance
|
||||
var/obj/item/stack/printed_stack = printed_instance
|
||||
target_var = NAMEOF(generic_stack, mats_per_unit)
|
||||
what_it_should_be = printed_stack.transcribe_materials_list(printed_stack.mats_per_unit)
|
||||
what_it_is = generic_stack.transcribe_materials_list(generic_stack.mats_per_unit)
|
||||
else
|
||||
what_it_should_be = printed_instance.transcribe_materials_list()
|
||||
what_it_is = generic_instance.transcribe_materials_list()
|
||||
|
||||
TEST_FAIL("[warning]. should be: [target_var] = [what_it_should_be] (current value: [what_it_is]). \
|
||||
Fix it or change the value of the [NAMEOF(design, inherit_materials)] var of [design.type]. \
|
||||
You can also edit the [NAMEOF(design, transfered_materials)] list of the design")
|
||||
|
||||
if(!length(printed_instance.contents))
|
||||
continue
|
||||
|
||||
var/list/all_mats = printed_instance.get_contents_custom_materials(/obj/item, TRAIT_IGNORED_BY_MAT_REDEMPTION)
|
||||
for(var/datum/material/mat as anything in all_mats)
|
||||
if(all_mats[mat] > design.materials[mat])
|
||||
var/sheet_val = transcribe_mat_value_as_sheet(all_mats[mat])
|
||||
var/design_val = transcribe_mat_value_as_sheet(design.materials[mat])
|
||||
TEST_FAIL("The [mat.name] ([mat.type] = [sheet_val]) of [printed_instance.type] plus its contents exceeds what presents in [design.type] ([design_val]). Review the code of the object and fix that.")
|
||||
|
||||
///Proc made to reduce copypasted code when allocating an object from a design, because stacks have a tendency to merge with each other, and we don't want that.
|
||||
/datum/unit_test/design_mats/proc/allocate_build_path_for_design(build_path)
|
||||
var/is_stack = ispath(build_path)
|
||||
if(is_stack) //If this is a stack, we don't want it to merge with any other stack on the same location
|
||||
var/obj/item/stack/stack_path = build_path
|
||||
var/stack_amount = initial(stack_path.amount)
|
||||
//So we need to specify the args up to the merge argument to avoid issues
|
||||
return allocate(stack_path, run_loc_floor_bottom_left, /*new_amount =*/ stack_amount, /*merge =*/ FALSE)
|
||||
return allocate(build_path)
|
||||
|
||||
Reference in New Issue
Block a user