Flatpacks now print with upgraded parts if they were researched from upgraded machines (#33290)

* makes the flatpack printer produce updated flatpacks

* fixes several sections of logic, including:
-no longer deletes components from source machine
-phazon parts now have a cost
-now doesn't reuse parts if there's only one source upgraded part
-no longer copies trader parts

* Improved several sections of logic:
- Fixed bitflag check for trade-protected parts
- Adjusted check order to reduce indentation per Kurfurst's requests
- Removed redundant list.Copy()
- Reduced complexity of the replacement proc somewhat
- Added additional comments to explain some of the less obvious code.

Co-authored-by: poales <amcclain02@gmail.com>
This commit is contained in:
kacurasuo
2022-09-24 02:30:48 -04:00
committed by GitHub
parent 2c9c0ecaae
commit ffb25b10a3
4 changed files with 57 additions and 3 deletions

View File

@@ -816,6 +816,35 @@ Class Procs:
return 1
return 0
//exclusively for use with machines being made from the flatpacker
//works like the parts exchange but because we only call this from a certain location
//we can make some particular assumptions about what's going on
/obj/machinery/proc/force_parts_transfer(var/datum/design/mechanic_design/O)
if(component_parts)
var/list/X = O.parts
//We paid for it when we made the flatpack, now we get new components.
//...has to be copied otherwise you delete the parts from the source
var/M = X.Copy(1,0)
var/obj/item/weapon/circuitboard/CB = locate(/obj/item/weapon/circuitboard) in component_parts
var/P
for(var/obj/item/A in component_parts)
//use some logic to, one by one, replace the parts in the flatpack
//we can't just force add all the parts to the machine because (including stock parts) because some parts aren't copiable
for(var/D in CB.req_components)
if(ispath(A.type, D))
P = D
break
for(var/obj/item/B in M)
if(istype(B, P) && istype(A, P))
if(B.get_rating() > A.get_rating()) //base rating parts should not be added (they already shouldn't be in this list, but whatever)
component_parts -= A
component_parts += B
M -= B //if you don't remove the part, one upgraded part will replace everything in the recipe
B.forceMove(null)
break
RefreshParts()
return 1
return 0
/obj/machinery/kick_act(mob/living/carbon/human/H)
if(H.locked_to && isobj(H.locked_to) && H.locked_to != src)

View File

@@ -100,7 +100,7 @@ The required techs are the following:
var/all_correct = 1
for(var/matID in D.materials)
if(copytext(matID, 1, 2) == "$" && (part.materials.storage[matID] != D.materials[matID])) //if it's a materal, but it doesn't match the atom's values
if(copytext(matID, 1, 2) == "$" && (part.materials.storage[matID] != D.materials[matID])) //if it's a material, but it doesn't match the atom's values
all_correct = 0
break
if(all_correct)
@@ -116,6 +116,11 @@ The required techs are the following:
//Acts as FindDesign, but makes a new design if it doesn't find one
//Doesn't take types for the design creation, so don't rely on it for that
/proc/getScanDesign(var/obj/O)
//all the designs are hidden somewhere in the backend
//so if you have an unupgraded machine scanned earlier it'll overwrite an upgraded machine you scan later
//that's why we have to force it to make a new datum if it's a machine
if(istype(O, /obj/machinery))
return new/datum/design/mechanic_design(O)
var/datum/design/D
if(O.materials)
D = FindDesign(O, 1) //The 1 means we check strict materials - if we don't have materials, we just check the type

View File

@@ -43,7 +43,7 @@
RefreshParts()
/obj/machinery/r_n_d/fabricator/mechanic_fab/flatpacker/build_part(var/datum/design/part)
/obj/machinery/r_n_d/fabricator/mechanic_fab/flatpacker/build_part(var/datum/design/mechanic_design/part)
if(!part)
return
@@ -65,6 +65,10 @@
if(being_built)
var/turf/output = get_output()
var/obj/structure/closet/crate/flatpack/new_flatpack = new(output)
if(istype(being_built, /obj/machinery))
var/obj/machinery/X = being_built //we have to cast it to a /obj/machinery so we can use the parts transfer code
X.force_parts_transfer(part) //add in scanned upgraded components
being_built = X
new_flatpack.insert_machine(being_built)
for(var/obj/structure/closet/crate/flatpack/existing in output)
if(existing.try_add_stack(new_flatpack))

View File

@@ -7,6 +7,7 @@
req_tech = list() //the origin tech of either the item, or the board in the machine
category = ""
var/parts = list() //holds a list of nonstandard components that will be added to the flatpack
/datum/design/mechanic_design/New(var/obj/O) //sets the name, type, design, origin_tech, and circuit, all by itself
if(!istype(O))
@@ -22,14 +23,29 @@
materials += list(MAT_IRON = 5 * CC_PER_SHEET_METAL) //cost of the frame
if(M.component_parts && M.component_parts.len)
category = "Machines"
//Now, we need to accomplish a few things. For every part:
//If it can be scanned, we need to add the cost of the part to the flatpack cost
//If it can be scanned and is better than a stock part, add it to the "parts" list that will be transfered to the new flatpack
for(var/obj/item/I in M.component_parts) //fetching the circuit by looking in the parts
if(I.mech_flags & MECH_SCAN_FAIL) //It can't be scanned, i.e. trader parts
continue //don't price it, don't do anything with it
if(istype(I, /obj/item/weapon/circuitboard))
var/obj/item/weapon/circuitboard/CB = I
req_tech = ConvertReqString2List(CB.origin_tech) //our tech is the circuit's requirement
var/datum/design/part_design = FindDesign(I)
//now, if the part has a "design" that could be built in a protolathe, find that and use the costs
//If it doesn't have a design, it'll still have a "materials.storage" that tells us an alt cost
//this applies to t4 parts, which don't have a design.
if(part_design)
copyCost(part_design, filter_chems = 1) //copy those materials requirements
else
for(var/matID in I.materials.storage)
if(I.materials.storage[matID] > 0)
if(!(matID in materials))
materials += list("[matID]" = 0) //Without this, phazon is not charged for t4 parts
materials[matID] += I.materials.storage[matID]
if(I.get_rating()>1) //if it's an upgraded part, add it to the parts list!
parts += I
else if(istype(M, /obj/machinery/computer))
category = "Computers"