[READY] Bespoke Datum Mats (#55296)

* Bespoke Material Backend

- Adds support for bespoke materials:
  - Reimplements [/datum/material/var/id]
  - Ports GetIdFromArguments from SSdcs
  - Adds a wrapper define for GetMaterialRef
  - Adds [MATERIAL_INIT_BESPOKE]
  - Adds [/datum/material/proc/Initialize]
- Does not actually add any bespoke materials

- [ ] TODO: Code docs
- [ ] TODO: Actually adding bespoke materials

* Some has_material procs and cleaning up some spaghetti

- Adds a pair of has_material procs for use in checking whether a given atom has a given material

* Adds meat

- Adds bespoke meat variants
  - Does not make them accessible
- Shuts up the linter

* Implements bespoke meat

- Makes the material container preserve bespoke materials
- Makes the sheetifier accept bespoke materials
- Makes the autolathe accept bespoke materials
- Makes the gibber produce bespoke meats

* Makes butchering produce bespoke meats

This is jank and really needs to be folded into a unified butchering and gibbing system

* Material documentation

- Adds, fixes, and touches up some documentation

* Material container insertion callback

- Changes the proc used to expand the material container's material list ot a proc used to check whether a material fits into a material container
- Instantiating new materials is no longer O(n) relative to the number of autolathes in existence.

* Makes processing meat conserve materials

- Makes bespoke meat carry over into meatballs

* Makes preserving custom materials an option

- Implements the ability to turn preserving custom materials _off_ for processor recipes

* Fixes all bespoke materials of the same type using the same singleton

- We use ids now, not just types.

* Makes the fat sucker produce bespoke meats

- Because consistency is good.

* Fixes autolathes merging bespoke stacks into normal stacks.

* Makes the callback to test materials for holdibility optional

- @Floyd

* GetMaterialRef -> GET_MATERIAL_REF

- We capitalize macros.

* Removes an extraneous callback

- Makes the sheetifier use functionality I didn't notice I implemented a few commits ago.

* Makes mob and species meat null compatible

* Fixes the ore silo

- The ore silo had really snowflake material handling that has been brought in line with the rest.
- The materials should show up in the correct order.

* Fixes minor lathe bugs

- Fixes stack_traces caused when lathes tried to fetch materials using reagent typepaths
- Fixed the selective reagent disposal topic. I have no idea how long this has been broken.

* Various documentation fixes

- Clarified a couple comments
- Removes an extraneous ?. operator
- Fixed mat floor tiles having bugged reagent temperatures

* More fixes

-/datum/material/meat/mob -> /datum/material/meat/mob_meat
- Adds atom typecheck to material containers.

* Fixes old typepaths
This commit is contained in:
TemporalOroboros
2021-01-15 23:39:58 -08:00
committed by GitHub
parent 685602afd9
commit 976c1fcb8c
55 changed files with 641 additions and 245 deletions
+1 -1
View File
@@ -1065,7 +1065,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
found_mats++
//if there's glass in it and the glass is more than 60% of the item, then we can shatter it
if(custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)] >= total_material_amount * 0.60)
if(custom_materials[GET_MATERIAL_REF(/datum/material/glass)] >= total_material_amount * 0.60)
if(prob(66)) //66% chance to break it
/// The glass shard that is spawned into the source item
var/obj/item/shard/broken_glass = new /obj/item/shard(loc)
+1 -1
View File
@@ -161,7 +161,7 @@ RLD
return FALSE
var/list/materials = list()
materials[SSmaterials.GetMaterialRef(/datum/material/iron)] = 500
materials[GET_MATERIAL_REF(/datum/material/iron)] = 500
silo_mats.mat_container.use_materials(materials, amount)
silo_mats.silo_log(src, "consume", -amount, "build", materials)
return TRUE
+2 -2
View File
@@ -66,8 +66,8 @@
if(iswallturf(T))
T.attackby(src, user, params)
var/metal_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)]/MINERAL_MATERIAL_AMOUNT) //Replace this shit later
var/glass_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)]/MINERAL_MATERIAL_AMOUNT) //Replace this shit later
var/metal_amt = round(custom_materials[GET_MATERIAL_REF(/datum/material/iron)]/MINERAL_MATERIAL_AMOUNT) //Replace this shit later
var/glass_amt = round(custom_materials[GET_MATERIAL_REF(/datum/material/glass)]/MINERAL_MATERIAL_AMOUNT) //Replace this shit later
if(W.tool_behaviour == TOOL_WRENCH && (metal_amt || glass_amt))
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
+1 -1
View File
@@ -22,7 +22,7 @@
refined_type = null
merge_type = /obj/item/stack/ore/bluespace_crystal/refined
/obj/item/stack/ore/bluespace_crystal/Initialize()
/obj/item/stack/ore/bluespace_crystal/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
+1 -1
View File
@@ -14,7 +14,7 @@
var/value = 0
grind_results = list(/datum/reagent/cellulose = 10)
/obj/item/stack/spacecash/Initialize()
/obj/item/stack/spacecash/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
update_desc()
+1 -1
View File
@@ -278,7 +278,7 @@
grind_results = list(/datum/reagent/medicine/spaceacillin = 2)
merge_type = /obj/item/stack/medical/mesh
/obj/item/stack/medical/mesh/Initialize()
/obj/item/stack/medical/mesh/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
if(amount == max_amount) //only seal full mesh packs
is_open = FALSE
+1 -1
View File
@@ -36,7 +36,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
user.visible_message("<span class='suicide'>[user] begins to stuff \the [src] down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide!</span>")//it looks like theyre ur mum
return BRUTELOSS
/obj/item/stack/rods/Initialize(mapload, new_amount, merge = TRUE)
/obj/item/stack/rods/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
update_icon()
@@ -153,7 +153,7 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \
/// Kelvin to start drying
var/drying_threshold_temperature = 500
/obj/item/stack/sheet/wethide/Initialize(mapload, new_amount, merge)
/obj/item/stack/sheet/wethide/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
AddElement(/datum/element/dryable, /obj/item/stack/sheet/leather)
@@ -595,7 +595,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
. = ..()
. += GLOB.bronze_recipes
/obj/item/stack/sheet/paperframes/Initialize()
/obj/item/stack/sheet/paperframes/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
pixel_x = 0
pixel_y = 0
@@ -16,7 +16,7 @@
///What type of wall does this sheet spawn
var/walltype
/obj/item/stack/sheet/Initialize(mapload, new_amount, merge)
/obj/item/stack/sheet/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
pixel_x = rand(-4, 4)
pixel_y = rand(-4, 4)
+6 -5
View File
@@ -40,7 +40,7 @@
/// Amount of matter for RCD
var/matter_amount = 0
/obj/item/stack/Initialize(mapload, new_amount, merge = TRUE)
/obj/item/stack/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
if(new_amount != null)
amount = new_amount
while(amount > max_amount)
@@ -49,7 +49,9 @@
if(!merge_type)
merge_type = type
if(LAZYLEN(mats_per_unit))
if(LAZYLEN(mat_override))
set_mats_per_unit(mat_override, mat_amt)
else if(LAZYLEN(mats_per_unit))
set_mats_per_unit(mats_per_unit, 1)
else if(LAZYLEN(custom_materials))
set_mats_per_unit(custom_materials, amount ? 1/amount : 1)
@@ -62,7 +64,7 @@
var/list/temp_recipes = get_main_recipes()
recipes = temp_recipes.Copy()
if(material_type)
var/datum/material/M = SSmaterials.GetMaterialRef(material_type) //First/main material
var/datum/material/M = GET_MATERIAL_REF(material_type) //First/main material
for(var/i in M.categories)
switch(i)
if(MAT_CATEGORY_BASE_RECIPES)
@@ -477,9 +479,8 @@
/obj/item/stack/proc/split_stack(mob/user, amount)
if(!use(amount, TRUE, FALSE))
return null
var/obj/item/stack/F = new type(user? user : drop_location(), amount, FALSE)
var/obj/item/stack/F = new type(user? user : drop_location(), amount, FALSE, mats_per_unit)
. = F
F.set_mats_per_unit(mats_per_unit, 1) // Required for greyscale sheets and tiles.
F.copy_evidences(src)
if(user)
if(!user.put_in_hands(F, merge_stacks = FALSE))
+1 -1
View File
@@ -8,7 +8,7 @@
max_amount = 30
merge_type = /obj/item/stack/arcadeticket
/obj/item/stack/arcadeticket/Initialize(mapload, new_amount, merge = TRUE)
/obj/item/stack/arcadeticket/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
update_icon()
@@ -20,7 +20,7 @@
var/list/tile_reskin_types
/obj/item/stack/tile/Initialize(mapload, amount)
/obj/item/stack/tile/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1)
. = ..()
pixel_x = rand(-3, 3)
pixel_y = rand(-3, 3) //randomize a little
@@ -320,7 +320,7 @@
if(remaining_mats)
for(var/M=1 to remaining_mats)
new stack_type(get_turf(loc))
else if(custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)])
else if(custom_materials[GET_MATERIAL_REF(/datum/material/iron)])
new /obj/item/stack/rods(get_turf(loc), 2)
qdel(src)
+1 -1
View File
@@ -200,7 +200,7 @@
var/turf/newturf = T.PlaceOnTop(/turf/closed/wall/material)
var/list/material_list = list()
if(S.material_type)
material_list[SSmaterials.GetMaterialRef(S.material_type)] = MINERAL_MATERIAL_AMOUNT * 2
material_list[GET_MATERIAL_REF(S.material_type)] = MINERAL_MATERIAL_AMOUNT * 2
if(material_list)
newturf.set_custom_materials(material_list)
+2 -2
View File
@@ -52,7 +52,7 @@
if(!(flags_1 & NODECONSTRUCT_1))
var/amount_mod = disassembled ? 0 : -2
for(var/mat in custom_materials)
var/datum/material/custom_material = SSmaterials.GetMaterialRef(mat)
var/datum/material/custom_material = GET_MATERIAL_REF(mat)
var/amount = max(0,round(custom_materials[mat]/MINERAL_MATERIAL_AMOUNT) + amount_mod)
if(amount > 0)
new custom_material.sheet_type(drop_location(),amount)
@@ -520,7 +520,7 @@ Moving interrupts
var/list/carving_cost = statue_costs[statue_path]
var/enough_materials = TRUE
for(var/required_material in carving_cost)
if(!custom_materials[required_material] || custom_materials[required_material] < carving_cost[required_material])
if(!has_material_type(required_material, TRUE, carving_cost[required_material]))
enough_materials = FALSE
break
if(enough_materials)