mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 07:46:20 +00:00
Crafting refactor, implementing materials (#89465)
My original plan was to just implement materials into crafting so that items would inherit the materials of their components, allowing for some interesting stuff if the material flags of the item allow it. However to my dismay crafting is a pile of old tech debt, starting from the old `del_reqs` and `CheckParts` which still contain lines about old janky bandaids that are no longer in use nor reachable, up to the `customizable_reagent_holder` component which has some harddel issues when your custom food is sliced, and items used in food recipes not being deleted and instead stored inside the result with no purpose as well as other inconsistencies like stack recipes that transfer materials having counterparts in the UI that don't do that. EDIT: Several things have come up while working on this, so I apologise that it ended up changing over 100+ files. I managed to atomize some of the changes, but it's a bit tedious. EDIT: TLDR because I was told this section is too vague and there's too much going on. This PR: - Improves the dated crafting code (not the UI). - replaced `atom/CheckParts` and `crafting_recipe/on_craft_completion` with `atom/on_craft_completion`. - Reqs used in food recipes are now deleted by default and not stored inside the result (they did nothing). - Renames the customizable_reagent_holder comp and improves it (No harddels/ref issues). - Adds a unit test that tries to craft all recipes to see what's wrong (it skips some of the much more specific reqs for now). - In the unit test is also the code to make sure materials of the crafted item and a non-crafted item of the same type are roughly the same, so far only applied to food. - Some mild material/food refactoring around the fact that food item code has been changed to support materials. Improving the backbone of the crafting system. Also materials and food code. 🆑 refactor: Refactored crafting backend. Report possible pesky bugs. balance: the MEAT backpack (from the MEAT cargo pack) may be a smidge different because of code standardization. /🆑
This commit is contained in:
@@ -62,6 +62,11 @@
|
||||
#define MATERIAL_GREYSCALE (1<<4)
|
||||
/// Materials like plasteel and alien alloy won't apply slowdowns.
|
||||
#define MATERIAL_NO_SLOWDOWN (1<<5)
|
||||
/**
|
||||
* This item is not affected by the standard food-related effects of materials like meat and pizza.
|
||||
* Necessary for the edible component counterparts, on_edible_applied() and on_edible_removed()
|
||||
*/
|
||||
#define MATERIAL_NO_EDIBILITY (1<<6)
|
||||
|
||||
//Special return values of [/datum/component/material_container/insert_item]
|
||||
/// No material was found inside them item
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#define CRAFTING_MACHINERY_USE 0
|
||||
///If the structure is only "used" i.e. it checks to see if it's nearby and allows crafting, but doesn't delete it
|
||||
#define CRAFTING_STRUCTURE_USE 0
|
||||
///If the ingredient is only "used" i.e. it checks to see if it's nearby and allows crafting, but doesn't delete it
|
||||
#define CRAFTING_INGREDIENT_USE 0
|
||||
|
||||
//stack recipe placement check types
|
||||
/// Checks if there is an object of the result type in any of the cardinal directions
|
||||
@@ -34,6 +32,10 @@
|
||||
#define CRAFT_TRANSFERS_REAGENTS (1<<7)
|
||||
/// Crafting clears all reagents present in the finished product
|
||||
#define CRAFT_CLEARS_REAGENTS (1<<8)
|
||||
/// For the crafting unit test, ensures that the custom materials of an item are the same when crafted and spawned.
|
||||
#define CRAFT_ENFORCE_MATERIALS_PARITY (1<<9)
|
||||
/// Exclusive to the personal_crafting component, skips the time spent crafting the recipe.
|
||||
#define CRAFT_IGNORE_DO_AFTER (1<<10)
|
||||
|
||||
//food/drink crafting defines
|
||||
//When adding new defines, please make sure to also add them to the encompassing list
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
#define CALTROP_NOSTUN (1 << 3)
|
||||
#define CALTROP_NOCRAWL (1 << 4)
|
||||
|
||||
//Ingredient type in datum/component/customizable_reagent_holder
|
||||
//Ingredient type in datum/component/ingredients_holder
|
||||
#define CUSTOM_INGREDIENT_TYPE_EDIBLE 1
|
||||
#define CUSTOM_INGREDIENT_TYPE_DRYABLE 2
|
||||
|
||||
//Icon overlay type in datum/component/customizable_reagent_holder
|
||||
//Icon overlay type in datum/component/ingredients_holder
|
||||
#define CUSTOM_INGREDIENT_ICON_NOCHANGE 0
|
||||
#define CUSTOM_INGREDIENT_ICON_FILL 1
|
||||
#define CUSTOM_INGREDIENT_ICON_SCATTER 2
|
||||
|
||||
@@ -149,6 +149,11 @@
|
||||
/// From /datum/component/tether/UnregisterFromParent()
|
||||
#define COMSIG_ATOM_TETHER_SNAPPED "atom_tether_snapped"
|
||||
|
||||
/// From /atom/finalize_material_effects(): (list/materials, datum/material/main_material)
|
||||
#define COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS "atom_finalize_material_effects"
|
||||
/// From /atom/finalize_remove_material_effects(): (list/materials, datum/material/main_material)
|
||||
#define COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS "atom_finalize_remove_material_effects"
|
||||
|
||||
/// From /atom/proc/update_atom_colour() : (color_changed)
|
||||
#define COMSIG_ATOM_COLOR_UPDATED "atom_color_updated"
|
||||
/// Cancels update_appearance call in case you are somehow forced to call it manually to prevent dupe calls
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#define COMPONENT_BULLET_PIERCED (1<<2)
|
||||
///from base of atom/bullet_act(): (/obj/proj, def_zone, piercing_hit, blocked)
|
||||
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act"
|
||||
///from base of atom/CheckParts(): (list/parts_list, datum/crafting_recipe/R)
|
||||
#define COMSIG_ATOM_CHECKPARTS "atom_checkparts"
|
||||
///from base of atom/CheckParts(): (atom/movable/new_craft) - The atom has just been used in a crafting recipe and has been moved inside new_craft.
|
||||
///from base of atom/on_craft_completion(): (components, datum/crafting_recipe/current_recipe)
|
||||
#define COMSIG_ATOM_ON_CRAFT "atom_checkparts"
|
||||
///from base of atom/used_in_craft(): (atom/result)
|
||||
#define COMSIG_ATOM_USED_IN_CRAFT "atom_used_in_craft"
|
||||
///from base of atom/blob_act(): (/obj/structure/blob)
|
||||
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//Customizable
|
||||
///called when an atom with /datum/component/customizable_reagent_holder is customized (obj/item/I)
|
||||
///called when an atom with /datum/component/ingredients_holder is customized (obj/item/I)
|
||||
#define COMSIG_ATOM_CUSTOMIZED "atom_customized"
|
||||
|
||||
@@ -285,3 +285,10 @@ DEFINE_BITFIELD(food_flags, list(
|
||||
|
||||
/// How much milk is needed to make butter on a reagent grinder
|
||||
#define MILK_TO_BUTTER_COEFF 25
|
||||
|
||||
/// How much material one slab of meat usually contains
|
||||
#define MEATSLAB_MATERIAL_AMOUNT SHEET_MATERIAL_AMOUNT * 4
|
||||
/// How many cutlets or meatballs one slab gives when processed
|
||||
#define MEATSLAB_PROCESSED_AMOUNT 3
|
||||
/// This should be 1/3 of the amount found in a slab (a portion will be lost when rounding but it's negligible)
|
||||
#define MEATDISH_MATERIAL_AMOUNT (MEATSLAB_MATERIAL_AMOUNT / MEATSLAB_PROCESSED_AMOUNT)
|
||||
|
||||
@@ -798,6 +798,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_T_RAY_VISIBLE "t-ray-visible"
|
||||
/// If this item's been fried
|
||||
#define TRAIT_FOOD_FRIED "food_fried"
|
||||
/// Has the ingredients_holder component
|
||||
#define TRAIT_INGREDIENTS_HOLDER "ingredients_holder"
|
||||
/// If this item's been bbq grilled
|
||||
#define TRAIT_FOOD_BBQ_GRILLED "food_bbq_grilled"
|
||||
/// This is a silver slime created item
|
||||
@@ -949,8 +951,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_DRYABLE "trait_dryable"
|
||||
///Trait for dried items
|
||||
#define TRAIT_DRIED "trait_dried"
|
||||
/// Trait for customizable reagent holder
|
||||
#define TRAIT_CUSTOMIZABLE_REAGENT_HOLDER "customizable_reagent_holder"
|
||||
/// Trait for allowing an item that isn't food into the customizable reagent holder
|
||||
#define TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT "odd_customizable_food_ingredient"
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED,
|
||||
"TRAIT_CLIMBABLE" = TRAIT_CLIMBABLE,
|
||||
"TRAIT_CURRENTLY_CLEANING" = TRAIT_CURRENTLY_CLEANING,
|
||||
"TRAIT_CUSTOMIZABLE_REAGENT_HOLDER" = TRAIT_CUSTOMIZABLE_REAGENT_HOLDER,
|
||||
"TRAIT_DO_NOT_SPLASH" = TRAIT_DO_NOT_SPLASH,
|
||||
"TRAIT_DRIED" = TRAIT_DRIED,
|
||||
"TRAIT_DRYABLE" = TRAIT_DRYABLE,
|
||||
@@ -24,11 +23,12 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_FOOD_CHEF_MADE" = TRAIT_FOOD_CHEF_MADE,
|
||||
"TRAIT_FOOD_FRIED" = TRAIT_FOOD_FRIED,
|
||||
"TRAIT_GOT_DAMPENED" = TRAIT_GOT_DAMPENED,
|
||||
"TRAIT_QUALITY_FOOD_INGREDIENT" = TRAIT_QUALITY_FOOD_INGREDIENT,
|
||||
"TRAIT_INGREDIENTS_HOLDER" = TRAIT_INGREDIENTS_HOLDER,
|
||||
"TRAIT_FOOD_SILVER" = TRAIT_FOOD_SILVER,
|
||||
"TRAIT_KEEP_TOGETHER" = TRAIT_KEEP_TOGETHER,
|
||||
"TRAIT_LIGHTING_DEBUGGED" = TRAIT_LIGHTING_DEBUGGED,
|
||||
"TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION" = TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION,
|
||||
"TRAIT_QUALITY_FOOD_INGREDIENT" = TRAIT_QUALITY_FOOD_INGREDIENT,
|
||||
"TRAIT_RECENTLY_COINED" = TRAIT_RECENTLY_COINED,
|
||||
"TRAIT_RUSTY" = TRAIT_RUSTY,
|
||||
"TRAIT_SPINNING" = TRAIT_SPINNING,
|
||||
|
||||
@@ -15,10 +15,17 @@
|
||||
var/list/tool_behaviors
|
||||
/// Type paths of items needed but not consumed. Lazy list.
|
||||
var/list/tool_paths
|
||||
/**
|
||||
* If defined, it'll spawn paths in this list first during the unit test.
|
||||
* This is an assoc list, with the key being the paths and the value being the amount (e.g. list(/obj/item = 2))
|
||||
*/
|
||||
var/list/unit_test_spawn_extras
|
||||
///time in seconds. Remember to use the SECONDS define!
|
||||
var/time = 3 SECONDS
|
||||
///type paths of items that will be forceMoved() into the result, or added to the reagents of it
|
||||
///type paths of items that will be forceMoved() into the result instead of being deleted
|
||||
var/list/parts = list()
|
||||
///items, structures and machineries of types that are in this list won't transfer their materials to the result
|
||||
var/list/requirements_mats_blacklist
|
||||
///like tool_behaviors but for reagents
|
||||
var/list/chem_catalysts = list()
|
||||
///where it shows up in the crafting UI
|
||||
@@ -71,6 +78,10 @@
|
||||
tool_behaviors = string_list(tool_behaviors)
|
||||
if(tool_paths)
|
||||
tool_paths = string_list(tool_paths)
|
||||
for(var/key in parts)
|
||||
if(!parts[key])
|
||||
//ensure every single, same-type part used for the recipe will be transferred if the value is otherwise not specified
|
||||
parts[key] = INFINITY
|
||||
|
||||
/datum/crafting_recipe/stack/New(obj/item/stack/material, datum/stack_recipe/stack_recipe)
|
||||
if(!material || !stack_recipe || !stack_recipe.result_type)
|
||||
@@ -86,6 +97,9 @@
|
||||
src.category = stack_recipe.category || CAT_MISC
|
||||
src.placement_checks = stack_recipe.placement_checks
|
||||
|
||||
if(!(stack_recipe.crafting_flags & CRAFT_APPLIES_MATS))
|
||||
requirements_mats_blacklist = list(material) //the item is not intended to have mats :shrug:
|
||||
|
||||
/**
|
||||
* Run custom pre-craft checks for this recipe, don't add feedback messages in this because it will spam the client
|
||||
*
|
||||
@@ -95,8 +109,9 @@
|
||||
/datum/crafting_recipe/proc/check_requirements(mob/user, list/collected_requirements)
|
||||
return TRUE
|
||||
|
||||
/datum/crafting_recipe/proc/on_craft_completion(mob/user, atom/result)
|
||||
return
|
||||
///Run custom pre-craft checks for this recipe for tools, rather than consumed requirements.
|
||||
/datum/crafting_recipe/proc/check_tools(atom/source, list/collected_tools, final_check = FALSE)
|
||||
return TRUE
|
||||
|
||||
/// Additional UI data to be passed to the crafting UI for this recipe
|
||||
/datum/crafting_recipe/proc/crafting_ui_data()
|
||||
|
||||
@@ -49,13 +49,6 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/crafting_recipe/spec_pipe/on_craft_completion(mob/user, atom/result)
|
||||
var/obj/item/pipe/crafted_pipe = result
|
||||
crafted_pipe.pipe_type = pipe_type
|
||||
crafted_pipe.pipe_color = ATMOS_COLOR_OMNI
|
||||
crafted_pipe.setDir(user.dir)
|
||||
crafted_pipe.update()
|
||||
|
||||
/datum/crafting_recipe/spec_pipe/layer_adapter
|
||||
name = "Layer manifold fitting"
|
||||
tool_behaviors = list(TOOL_WRENCH, TOOL_WELDER)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
/obj/item/rag = 1,
|
||||
/obj/item/reagent_containers/cup/glass/bottle = 1,
|
||||
)
|
||||
parts = list(/obj/item/reagent_containers/cup/glass/bottle = 1)
|
||||
time = 4 SECONDS
|
||||
category = CAT_CHEMISTRY
|
||||
|
||||
@@ -30,7 +29,6 @@
|
||||
/obj/item/grenade/c4 = 1,
|
||||
/obj/item/grenade/chem_grenade = 2
|
||||
)
|
||||
parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
|
||||
time = 3 SECONDS
|
||||
category = CAT_CHEMISTRY
|
||||
|
||||
@@ -42,7 +40,6 @@
|
||||
/obj/item/gibtonite = 1,
|
||||
/obj/item/grenade/chem_grenade = 2,
|
||||
)
|
||||
parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
|
||||
time = 5 SECONDS
|
||||
category = CAT_CHEMISTRY
|
||||
|
||||
@@ -149,17 +146,6 @@
|
||||
machinery = list(/obj/machinery/space_heater = CRAFTING_MACHINERY_CONSUME)
|
||||
category = CAT_CHEMISTRY
|
||||
|
||||
/datum/crafting_recipe/improvised_chem_heater/on_craft_completion(mob/user, atom/result)
|
||||
if(!istype(user))
|
||||
return
|
||||
var/obj/item/stock_parts/power_store/cell/cell = locate(/obj/item/stock_parts/power_store/cell) in range(1)
|
||||
if(!cell)
|
||||
return
|
||||
var/obj/machinery/space_heater/improvised_chem_heater/heater = result
|
||||
var/turf/turf = get_turf(cell)
|
||||
heater.forceMove(turf)
|
||||
heater.attackby(cell, user) //puts it into the heater
|
||||
|
||||
/datum/crafting_recipe/improvised_coolant
|
||||
name = "Improvised cooling spray"
|
||||
tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
//list key declarations used in check_contents(), get_surroundings() and check_tools()
|
||||
#define CONTENTS_INSTANCES "instances"
|
||||
#define CONTENTS_MACHINERY "machinery"
|
||||
#define CONTENTS_STRUCTURES "structures"
|
||||
#define CONTENTS_REAGENTS "reagents"
|
||||
#define CONTENTS_TOOL_BEHAVIOUR "tool_behaviour"
|
||||
|
||||
/datum/component/personal_crafting
|
||||
/// Custom screen_loc for our element
|
||||
var/screen_loc_override
|
||||
@@ -37,32 +44,32 @@
|
||||
check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff
|
||||
check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep
|
||||
construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs
|
||||
del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list
|
||||
get_used_reqs - takes recipe, a user and a list (for mats), loops over the recipes reqs var and tries to find everything in the list make by get_environment and returns a list of the components to be used
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check that the contents of the recipe meet the requirements.
|
||||
*
|
||||
* user: The /mob that initated the crafting.
|
||||
* R: The /datum/crafting_recipe being attempted.
|
||||
* contents: List of items to search for R's reqs.
|
||||
* recipe: The /datum/crafting_recipe being attempted.
|
||||
* contents: List of items to search for the recipe's reqs.
|
||||
*/
|
||||
/datum/component/personal_crafting/proc/check_contents(atom/a, datum/crafting_recipe/R, list/contents)
|
||||
var/list/item_instances = contents["instances"]
|
||||
var/list/machines = contents["machinery"]
|
||||
var/list/structures = contents["structures"]
|
||||
contents = contents["other"]
|
||||
/datum/component/personal_crafting/proc/check_contents(atom/a, datum/crafting_recipe/recipe, list/contents)
|
||||
var/list/item_instances = contents[CONTENTS_INSTANCES]
|
||||
var/list/machines = contents[CONTENTS_MACHINERY]
|
||||
var/list/structures = contents[CONTENTS_STRUCTURES]
|
||||
contents = contents[CONTENTS_REAGENTS]
|
||||
|
||||
|
||||
var/list/requirements_list = list()
|
||||
|
||||
// Process all requirements
|
||||
for(var/requirement_path in R.reqs)
|
||||
for(var/requirement_path in recipe.reqs)
|
||||
// Check we have the appropriate amount available in the contents list
|
||||
var/needed_amount = R.reqs[requirement_path]
|
||||
var/needed_amount = recipe.reqs[requirement_path]
|
||||
for(var/content_item_path in contents)
|
||||
// Right path and not blacklisted
|
||||
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(content_item_path))
|
||||
if(!ispath(content_item_path, requirement_path) || recipe.blacklist.Find(content_item_path))
|
||||
continue
|
||||
|
||||
needed_amount -= contents[content_item_path]
|
||||
@@ -72,7 +79,7 @@
|
||||
if(needed_amount > 0)
|
||||
return FALSE
|
||||
|
||||
// Store the instances of what we will use for R.check_requirements() for requirement_path
|
||||
// Store the instances of what we will use for recipe.check_requirements() for requirement_path
|
||||
var/list/instances_list = list()
|
||||
for(var/instance_path in item_instances)
|
||||
if(ispath(instance_path, requirement_path))
|
||||
@@ -80,37 +87,32 @@
|
||||
|
||||
requirements_list[requirement_path] = instances_list
|
||||
|
||||
for(var/requirement_path in R.chem_catalysts)
|
||||
if(contents[requirement_path] < R.chem_catalysts[requirement_path])
|
||||
for(var/requirement_path in recipe.chem_catalysts)
|
||||
if(contents[requirement_path] < recipe.chem_catalysts[requirement_path])
|
||||
return FALSE
|
||||
|
||||
var/mech_found = FALSE
|
||||
for(var/machinery_path in R.machinery)
|
||||
for(var/machinery_path in recipe.machinery)
|
||||
mech_found = FALSE
|
||||
for(var/obj/machinery/machine as anything in machines)
|
||||
if(ispath(machine, machinery_path))//We don't care for volume with machines, just if one is there or not
|
||||
if(ispath(machine, machinery_path))// We only need one machine per key, unlike items
|
||||
mech_found = TRUE
|
||||
break
|
||||
if(!mech_found)
|
||||
return FALSE
|
||||
|
||||
for(var/required_structure_path in R.structures)
|
||||
// Check for the presence of the required structure. Allow for subtypes to be used if not blacklisted
|
||||
var/needed_amount = R.structures[required_structure_path]
|
||||
for(var/structure_path in structures)
|
||||
if(!ispath(structure_path, required_structure_path) || R.blacklist.Find(structure_path))
|
||||
continue
|
||||
|
||||
needed_amount -= structures[required_structure_path]
|
||||
requirements_list[required_structure_path] = structures[structure_path] // Store an instance of what we are using for check_requirements
|
||||
if(needed_amount <= 0)
|
||||
break
|
||||
|
||||
// We didn't find the required item
|
||||
if(needed_amount > 0)
|
||||
var/found = FALSE
|
||||
for(var/structure_path in recipe.structures)
|
||||
found = FALSE
|
||||
for(var/obj/structure/structure as anything in structures)
|
||||
if(ispath(structure, structure_path))// We only need one structure per key, unlike items
|
||||
found = TRUE
|
||||
break
|
||||
if(!found)
|
||||
return FALSE
|
||||
|
||||
return R.check_requirements(a, requirements_list)
|
||||
//Skip extra requirements when unit testing, like, underwater basket weaving? Get the hell out of here
|
||||
return PERFORM_ALL_TESTS(crafting) || recipe.check_requirements(a, requirements_list)
|
||||
|
||||
/datum/component/personal_crafting/proc/get_environment(atom/a, list/blacklist = null, radius_range = 1)
|
||||
. = list()
|
||||
@@ -129,59 +131,60 @@
|
||||
|
||||
/datum/component/personal_crafting/proc/get_surroundings(atom/a, list/blacklist=null)
|
||||
. = list()
|
||||
.["tool_behaviour"] = list()
|
||||
.["other"] = list()
|
||||
.["instances"] = list()
|
||||
.["machinery"] = list()
|
||||
.["structures"] = list()
|
||||
.[CONTENTS_TOOL_BEHAVIOUR] = list()
|
||||
.[CONTENTS_REAGENTS] = list()
|
||||
.[CONTENTS_INSTANCES] = list()
|
||||
.[CONTENTS_MACHINERY] = list()
|
||||
.[CONTENTS_STRUCTURES] = list()
|
||||
for(var/obj/object in get_environment(a, blacklist))
|
||||
if(isitem(object))
|
||||
var/obj/item/item = object
|
||||
LAZYADDASSOCLIST(.["instances"], item.type, item)
|
||||
LAZYADDASSOCLIST(.[CONTENTS_INSTANCES], item.type, item)
|
||||
if(isstack(item))
|
||||
var/obj/item/stack/stack = item
|
||||
.["other"][item.type] += stack.amount
|
||||
.[CONTENTS_REAGENTS][item.type] += stack.amount
|
||||
else
|
||||
.["other"][item.type] += 1
|
||||
.[CONTENTS_REAGENTS][item.type] += 1
|
||||
if(is_reagent_container(item) && item.is_drainable() && length(item.reagents.reagent_list)) //some container that has some reagents inside it that can be drained
|
||||
var/obj/item/reagent_containers/container = item
|
||||
for(var/datum/reagent/reagent as anything in container.reagents.reagent_list)
|
||||
.["other"][reagent.type] += reagent.volume
|
||||
.[CONTENTS_REAGENTS][reagent.type] += reagent.volume
|
||||
else //a reagent container that is empty can also be used as a tool. e.g. glass bottle can be used as a rolling pin
|
||||
if(item.tool_behaviour)
|
||||
.["tool_behaviour"] += item.tool_behaviour
|
||||
.[CONTENTS_TOOL_BEHAVIOUR] += item.tool_behaviour
|
||||
else if (ismachinery(object))
|
||||
LAZYADDASSOCLIST(.["machinery"], object.type, object)
|
||||
LAZYADDASSOCLIST(.[CONTENTS_MACHINERY], object.type, object)
|
||||
else if (isstructure(object))
|
||||
LAZYADDASSOCLIST(.["structures"], object.type, object)
|
||||
LAZYADDASSOCLIST(.[CONTENTS_STRUCTURES], object.type, object)
|
||||
|
||||
/// Returns a boolean on whether the tool requirements of the input recipe are satisfied by the input source and surroundings.
|
||||
/datum/component/personal_crafting/proc/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings)
|
||||
/datum/component/personal_crafting/proc/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings, final_check = FALSE)
|
||||
if(!length(recipe.tool_behaviors) && !length(recipe.tool_paths))
|
||||
return TRUE
|
||||
|
||||
var/list/available_tools = list()
|
||||
var/list/present_qualities = list()
|
||||
|
||||
for(var/obj/item/contained_item in source.contents)
|
||||
if(contained_item.atom_storage)
|
||||
for(var/obj/item/subcontained_item in contained_item.contents)
|
||||
available_tools[subcontained_item.type] = TRUE
|
||||
if(subcontained_item.tool_behaviour)
|
||||
present_qualities[subcontained_item.tool_behaviour] = TRUE
|
||||
var/list/all_instances = list()
|
||||
for(var/atom/movable/movable as anything in source.contents)
|
||||
all_instances += movable
|
||||
if(movable.atom_storage)
|
||||
all_instances += movable.contents
|
||||
|
||||
for(var/obj/item/contained_item in all_instances) //fill the available tools list with available tool types and behaviours
|
||||
available_tools[contained_item.type] = TRUE
|
||||
if(contained_item.tool_behaviour)
|
||||
present_qualities[contained_item.tool_behaviour] = TRUE
|
||||
|
||||
for(var/quality in surroundings["tool_behaviour"])
|
||||
for(var/quality in surroundings[CONTENTS_TOOL_BEHAVIOUR])
|
||||
present_qualities[quality] = TRUE
|
||||
|
||||
for(var/path in surroundings["other"])
|
||||
for(var/path in surroundings[CONTENTS_REAGENTS])
|
||||
available_tools[path] = TRUE
|
||||
|
||||
for(var/required_quality in recipe.tool_behaviors)
|
||||
if(present_qualities[required_quality])
|
||||
continue
|
||||
return FALSE
|
||||
if(!present_qualities[required_quality])
|
||||
return FALSE
|
||||
|
||||
for(var/required_path in recipe.tool_paths)
|
||||
var/found_this_tool = FALSE
|
||||
@@ -190,12 +193,15 @@
|
||||
continue
|
||||
found_this_tool = TRUE
|
||||
break
|
||||
if(found_this_tool)
|
||||
continue
|
||||
return FALSE
|
||||
if(!found_this_tool)
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
//add the contents of the assoc list of the surrounding instances to all_instances for the recipe.check_tools() call
|
||||
var/list/surrounding_instances = surroundings[CONTENTS_INSTANCES]
|
||||
for(var/type_key in surrounding_instances)
|
||||
all_instances |= surrounding_instances[type_key]
|
||||
|
||||
return recipe.check_tools(source, all_instances, final_check)
|
||||
|
||||
/datum/component/personal_crafting/proc/construct_item(atom/crafter, datum/crafting_recipe/recipe)
|
||||
if(!crafter)
|
||||
@@ -205,13 +211,82 @@
|
||||
return ", invalid recipe!" // This can happen, I can't really explain why, but it can. Better safe than sorry.
|
||||
|
||||
var/list/contents = get_surroundings(crafter, recipe.blacklist)
|
||||
var/send_feedback = 1
|
||||
var/turf/dest_turf = get_turf(crafter)
|
||||
var/fail_message = perform_all_checks(crafter, recipe, contents, check_tools_last = ignored_flags & CRAFT_IGNORE_DO_AFTER)
|
||||
if(fail_message)
|
||||
return fail_message
|
||||
|
||||
//If we're a mob we'll try a do_after; non mobs will instead instantly construct the item
|
||||
if(!(ignored_flags & CRAFT_IGNORE_DO_AFTER))
|
||||
// BUBBER EDIT ADDITION BEGIN - Construction skill
|
||||
var/mob/crafting_mob = crafter
|
||||
var/skill_modifier = 1
|
||||
if(istype(crafting_mob))
|
||||
skill_modifier = crafter_mob.mind.get_skill_modifier(/datum/skill/construction, SKILL_SPEED_MODIFIER)
|
||||
// BUBBER EDIT ADDITION END - Construction skill
|
||||
if(!do_after(crafter, recipe.time * skill_modifier, target = crafter)) // BUBBER EDIT CHANGE - Construction skill - Original: if(!do_after(crafter, recipe.time, target = crafter))
|
||||
return "."
|
||||
contents = get_surroundings(crafter, recipe.blacklist)
|
||||
fail_message = perform_all_checks(crafter, recipe, contents, check_tools_last = TRUE)
|
||||
if(fail_message)
|
||||
return fail_message
|
||||
|
||||
//used to gather the material composition of the utilized requirements to transfer to the result
|
||||
var/list/total_materials = list()
|
||||
var/list/stuff_to_use = get_used_reqs(recipe, crafter, total_materials)
|
||||
var/atom/result
|
||||
var/turf/craft_turf = get_turf(crafter.loc)
|
||||
var/set_materials = TRUE
|
||||
if(ispath(recipe.result, /turf))
|
||||
result = craft_turf.place_on_top(recipe.result)
|
||||
else if(ispath(recipe.result, /obj/item/stack))
|
||||
//we don't merge the stack right away but try to put it in the hand of the crafter
|
||||
result = new recipe.result(craft_turf, recipe.result_amount || 1, /*merge =*/FALSE)
|
||||
set_materials = FALSE //stacks are bit too complex for it for now, but you're free to change that.
|
||||
else
|
||||
result = new recipe.result(craft_turf)
|
||||
if(result.atom_storage && recipe.delete_contents)
|
||||
for(var/obj/item/thing in result)
|
||||
qdel(thing)
|
||||
// BUBBER EDIT ADDITION BEGIN - Construction skill
|
||||
var/mob/crafting_mob = crafter
|
||||
if(istype(crafting_mob))
|
||||
crafting_mob.mind.adjust_experience(/datum/skill/construction, 5)
|
||||
// BUBBER EDIT ADDITION END - Construction skill
|
||||
result.setDir(crafter.dir)
|
||||
var/datum/reagents/holder = locate() in stuff_to_use
|
||||
if(holder) //transfer reagents from ingredients to result
|
||||
if(!ispath(recipe.result, /obj/item/reagent_containers) && result.reagents)
|
||||
if(recipe.crafting_flags & CRAFT_CLEARS_REAGENTS)
|
||||
result.reagents.clear_reagents()
|
||||
if(recipe.crafting_flags & CRAFT_TRANSFERS_REAGENTS)
|
||||
holder.trans_to(result.reagents, holder.total_volume, no_react = TRUE)
|
||||
stuff_to_use -= holder //This is the only non-movable in our list, we need to remove it.
|
||||
qdel(holder)
|
||||
result.on_craft_completion(stuff_to_use, recipe, crafter)
|
||||
if(set_materials)
|
||||
result.set_custom_materials(total_materials)
|
||||
for(var/atom/movable/component as anything in stuff_to_use) //delete anything that wasn't stored inside the object
|
||||
if(component.loc != result || isturf(result))
|
||||
qdel(component)
|
||||
if(!PERFORM_ALL_TESTS(crafting))
|
||||
SSblackbox.record_feedback("tally", "object_crafted", 1, result.type)
|
||||
return result //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
|
||||
|
||||
///This proc performs all the necessary conditional control statement to ensure that the object is allowed to be crafted by the crafter.
|
||||
/datum/component/personal_crafting/proc/perform_all_checks(atom/crafter, datum/crafting_recipe/recipe, list/contents, check_tools_last = FALSE)
|
||||
if(!check_contents(crafter, recipe, contents))
|
||||
return ", missing component."
|
||||
|
||||
if(!check_tools(crafter, recipe, contents))
|
||||
var/turf/dest_turf = get_turf(crafter)
|
||||
|
||||
// Mobs call perform_all_checks() twice since they don't have the CRAFT_IGNORE_DO_AFTER flag,
|
||||
// one before the do_after() and another after that. While other entities may have that flag and therefore only call the proc once.
|
||||
// Check_tools() meanwhile has a final_check arg which, if true, may perform some statements that can
|
||||
// modify some of the tools, like expending charges from a crayon or spraycan, which may make it unable
|
||||
// to meet some criterias afterward, so it's important to call that, last by the end of the final perform_all_checks().
|
||||
// For any non-final perform_all_checks() call, just keep check_tools() here because it's
|
||||
// the most imporant feedback after "missing component".
|
||||
if(!check_tools_last && !check_tools(crafter, recipe, contents, FALSE))
|
||||
return ", missing tool."
|
||||
|
||||
var/considered_flags = recipe.crafting_flags & ~(ignored_flags)
|
||||
@@ -256,185 +331,99 @@
|
||||
if(!locate(/obj/structure/transport/linear/tram) in dest_turf)
|
||||
return ", must be made on a tram!"
|
||||
|
||||
//If we're a mob we'll try a do_after; non mobs will instead instantly construct the item
|
||||
//SKYRAT EDIT START: Two Skills (Construction)
|
||||
var/mob/crafter_mob
|
||||
var/skill_modifier = 1
|
||||
if(ismob(crafter))
|
||||
crafter_mob = crafter
|
||||
skill_modifier = crafter_mob.mind.get_skill_modifier(/datum/skill/construction, SKILL_SPEED_MODIFIER)
|
||||
if(!do_after(crafter, recipe.time * skill_modifier, target = crafter))
|
||||
return "."
|
||||
contents = get_surroundings(crafter, recipe.blacklist)
|
||||
if(!check_contents(crafter, recipe, contents))
|
||||
return ", missing component."
|
||||
if(!check_tools(crafter, recipe, contents))
|
||||
if(check_tools_last && !check_tools(crafter, recipe, contents, TRUE))
|
||||
return ", missing tool."
|
||||
var/list/parts = del_reqs(recipe, crafter)
|
||||
var/atom/movable/result
|
||||
if(ispath(recipe.result, /obj/item/stack))
|
||||
result = new recipe.result(get_turf(crafter.loc), recipe.result_amount || 1)
|
||||
result.dir = crafter.dir
|
||||
else
|
||||
result = new recipe.result(get_turf(crafter.loc))
|
||||
result.dir = crafter.dir
|
||||
if(result.atom_storage && recipe.delete_contents)
|
||||
for(var/obj/item/thing in result)
|
||||
qdel(thing)
|
||||
if(crafter_mob)
|
||||
crafter_mob.mind.adjust_experience(/datum/skill/construction, 5)
|
||||
//SKYRAT EDIT END
|
||||
var/datum/reagents/holder = locate() in parts
|
||||
if(holder) //transfer reagents from ingredients to result
|
||||
if(!ispath(recipe.result, /obj/item/reagent_containers) && result.reagents)
|
||||
if(recipe.crafting_flags & CRAFT_CLEARS_REAGENTS)
|
||||
result.reagents.clear_reagents()
|
||||
if(recipe.crafting_flags & CRAFT_TRANSFERS_REAGENTS)
|
||||
holder.trans_to(result.reagents, holder.total_volume, no_react = TRUE)
|
||||
parts -= holder
|
||||
qdel(holder)
|
||||
result.CheckParts(parts, recipe)
|
||||
if(send_feedback)
|
||||
SSblackbox.record_feedback("tally", "object_crafted", 1, result.type)
|
||||
return result //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
|
||||
|
||||
/*Del reqs works like this:
|
||||
/**
|
||||
* get_used_reqs works like this:
|
||||
* Loop over reqs var of the recipe
|
||||
* Set var amt to the value current cycle req is pointing to, its amount of type we need to delete
|
||||
* Get var/surroundings list of things accessable to crafting by get_environment()
|
||||
* Check the type of the current cycle req
|
||||
* * If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isn't remove thing from surroundings
|
||||
* * * Transfer a quantity (The required amount of the contained quantity, whichever is lower) of the reagent to the temporary reagents holder
|
||||
*
|
||||
* * If it's a stack, create a tally stack and then transfer an amount of the stack to the stack until it reaches the required amount.
|
||||
*
|
||||
* * If it's anything else just locate() it in the list in a while loop, for each find reduce the amt var by 1 and put the found stuff in return list
|
||||
*
|
||||
* For stacks and items, the material composition is also tallied in total_materials, to be transferred to the result after that is spawned.
|
||||
*
|
||||
* get_used_reqs returns the list of used required object the result will receive as argument of atom/CheckParts()
|
||||
* If one or some of the object types is in the 'parts' list of the recipe, they will be stored inside the contents of the result
|
||||
* The rest will instead be deleted by atom/CheckParts()
|
||||
**/
|
||||
|
||||
Loop over reqs var of the recipe
|
||||
Set var amt to the value current cycle req is pointing to, its amount of type we need to delete
|
||||
Get var/surroundings list of things accessable to crafting by get_environment()
|
||||
Check the type of the current cycle req
|
||||
If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isn't remove thing from surroundings
|
||||
If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list
|
||||
If there isn't enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching
|
||||
While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one
|
||||
If its stack check if it has enough amount
|
||||
If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack
|
||||
If no put all of the stack in the deletion list, substract its amount from amt and keep searching
|
||||
While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one
|
||||
If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop
|
||||
|
||||
Then do a loop over parts var of the recipe
|
||||
Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return
|
||||
|
||||
After its done loop over deletion list and delete all the shit that wasn't taken by parts loop
|
||||
|
||||
del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already
|
||||
*/
|
||||
|
||||
/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, atom/a)
|
||||
. = list()
|
||||
/datum/component/personal_crafting/proc/get_used_reqs(datum/crafting_recipe/recipe, atom/atom, list/total_materials = list())
|
||||
var/list/return_list = list()
|
||||
|
||||
var/datum/reagents/holder
|
||||
var/list/surroundings
|
||||
var/list/Deletion = list()
|
||||
var/amt
|
||||
var/list/requirements = list()
|
||||
if(R.reqs)
|
||||
requirements += R.reqs
|
||||
if(R.machinery)
|
||||
requirements += R.machinery
|
||||
if(R.structures)
|
||||
requirements += R.structures
|
||||
main_loop:
|
||||
for(var/path_key in requirements)
|
||||
amt = R.reqs?[path_key] || R.machinery?[path_key] || R.structures?[path_key]
|
||||
if(!amt)//since machinery & structures can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it!
|
||||
continue main_loop
|
||||
surroundings = get_environment(a, R.blacklist)
|
||||
surroundings -= Deletion
|
||||
if(ispath(path_key, /datum/reagent))
|
||||
while(amt > 0)
|
||||
var/obj/item/reagent_containers/RC = locate() in surroundings
|
||||
if(isnull(RC)) //not found
|
||||
break
|
||||
if(QDELING(RC)) //deleting so is unusable
|
||||
surroundings -= RC
|
||||
continue
|
||||
if(recipe.reqs)
|
||||
requirements += recipe.reqs
|
||||
if(recipe.machinery)
|
||||
requirements += recipe.machinery
|
||||
if(recipe.structures)
|
||||
requirements += recipe.structures
|
||||
|
||||
var/reagent_volume = RC.reagents.get_reagent_amount(path_key)
|
||||
if(reagent_volume)
|
||||
if(!holder)
|
||||
holder = new(INFINITY, NO_REACT) //an infinite volume holder than can store reagents without reacting
|
||||
. += holder
|
||||
if(reagent_volume >= amt)
|
||||
RC.reagents.trans_to(holder, amt, target_id = path_key, no_react = TRUE)
|
||||
continue main_loop
|
||||
else
|
||||
RC.reagents.trans_to(holder, reagent_volume, target_id = path_key, no_react = TRUE)
|
||||
surroundings -= RC
|
||||
amt -= reagent_volume
|
||||
else
|
||||
surroundings -= RC
|
||||
RC.update_appearance(UPDATE_ICON)
|
||||
else if(ispath(path_key, /obj/item/stack))
|
||||
var/obj/item/stack/S
|
||||
var/obj/item/stack/SD
|
||||
while(amt > 0)
|
||||
S = locate(path_key) in surroundings
|
||||
if(S.amount >= amt)
|
||||
if(!locate(S.type) in Deletion)
|
||||
SD = new S.type()
|
||||
Deletion += SD
|
||||
S.use(amt)
|
||||
SD = SD || locate(S.type) in Deletion // SD might be already set here, no sense in searching for it again
|
||||
SD.amount += amt
|
||||
continue main_loop
|
||||
else
|
||||
amt -= S.amount
|
||||
if(!locate(S.type) in Deletion)
|
||||
Deletion += S
|
||||
else
|
||||
SD = SD || locate(S.type) in Deletion
|
||||
SD.add(S.amount) // add the amount to our tally stack, SD
|
||||
qdel(S) // We can just delete it straight away as it's going to be fully consumed anyway, saving some overhead from calling use()
|
||||
surroundings -= S
|
||||
else
|
||||
var/atom/movable/I
|
||||
while(amt > 0)
|
||||
I = locate(path_key) in surroundings
|
||||
Deletion += I
|
||||
surroundings -= I
|
||||
amt--
|
||||
var/list/partlist = list(R.parts.len)
|
||||
for(var/M in R.parts)
|
||||
partlist[M] = R.parts[M]
|
||||
for(var/part in R.parts)
|
||||
if(istype(part, /datum/reagent))
|
||||
var/datum/reagent/RG = locate(part) in Deletion
|
||||
if(RG.volume > partlist[part])
|
||||
RG.volume = partlist[part]
|
||||
. += RG
|
||||
Deletion -= RG
|
||||
continue
|
||||
else if(isstack(part))
|
||||
var/obj/item/stack/ST = locate(part) in Deletion
|
||||
if(ST.amount > partlist[part])
|
||||
ST.amount = partlist[part]
|
||||
. += ST
|
||||
Deletion -= ST
|
||||
for(var/path_key in requirements)
|
||||
var/list/surroundings
|
||||
var/amount = recipe.reqs?[path_key] || recipe.machinery?[path_key] || recipe.structures?[path_key]
|
||||
if(!amount)//since machinery & structures can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it!
|
||||
continue
|
||||
surroundings = get_environment(atom, recipe.blacklist)
|
||||
surroundings -= return_list
|
||||
if(ispath(path_key, /datum/reagent))
|
||||
if(!holder)
|
||||
holder = new(INFINITY, NO_REACT) //an infinite volume holder than can store reagents without reacting
|
||||
return_list += holder
|
||||
while(amount > 0)
|
||||
var/obj/item/reagent_containers/container = locate() in surroundings
|
||||
if(isnull(container)) //This would only happen if the previous checks for contents and tools were flawed.
|
||||
stack_trace("couldn't fulfill the required amount for [path_key]. Dangit")
|
||||
if(QDELING(container)) //it's deleting...
|
||||
surroundings -= container
|
||||
continue
|
||||
var/reagent_volume = container.reagents.get_reagent_amount(path_key)
|
||||
if(reagent_volume)
|
||||
container.reagents.trans_to(holder, min(amount, reagent_volume), target_id = path_key, no_react = TRUE)
|
||||
amount -= reagent_volume
|
||||
surroundings -= container
|
||||
container.update_appearance(UPDATE_ICON)
|
||||
else if(ispath(path_key, /obj/item/stack))
|
||||
var/obj/item/stack/tally_stack
|
||||
while(amount > 0)
|
||||
var/obj/item/stack/origin_stack = locate(path_key) in surroundings
|
||||
if(isnull(origin_stack)) //This would only happen if the previous checks for contents and tools were flawed.
|
||||
stack_trace("couldn't fulfill the required amount for [path_key]. Dangit")
|
||||
if(QDELING(origin_stack))
|
||||
continue
|
||||
var/amount_to_give = min(origin_stack.amount, amount)
|
||||
if(!tally_stack)
|
||||
tally_stack = origin_stack.split_stack(amount = amount_to_give)
|
||||
return_list += tally_stack
|
||||
else
|
||||
origin_stack.merge(tally_stack, amount_to_give)
|
||||
amount -= amount_to_give
|
||||
surroundings -= origin_stack
|
||||
if(!(path_key in recipe.requirements_mats_blacklist))
|
||||
for(var/material in tally_stack.custom_materials)
|
||||
total_materials[material] += tally_stack.custom_materials[material]
|
||||
else
|
||||
while(partlist[part] > 0)
|
||||
var/atom/movable/AM = locate(part) in Deletion
|
||||
. += AM
|
||||
Deletion -= AM
|
||||
partlist[part] -= 1
|
||||
while(Deletion.len)
|
||||
var/DL = Deletion[Deletion.len]
|
||||
Deletion.Cut(Deletion.len)
|
||||
// Snowflake handling of reagent containers, storage atoms, and structures with contents.
|
||||
// If we consumed them in our crafting, we should dump their contents out before qdeling them.
|
||||
if(is_reagent_container(DL))
|
||||
var/obj/item/reagent_containers/container = DL
|
||||
container.reagents.expose(container.loc, TOUCH)
|
||||
else if(istype(DL, /obj/item/storage))
|
||||
var/obj/item/storage/container = DL
|
||||
container.emptyStorage()
|
||||
else if(isstructure(DL))
|
||||
var/obj/structure/structure = DL
|
||||
structure.dump_contents(structure.drop_location())
|
||||
qdel(DL)
|
||||
while(amount > 0)
|
||||
var/atom/movable/item = locate(path_key) in surroundings
|
||||
if(isnull(item)) //This would only happen if the previous checks for contents and tools were flawed.
|
||||
stack_trace("couldn't fulfill the required amount for [path_key]. Dangit")
|
||||
if(QDELING(item))
|
||||
continue
|
||||
return_list += item
|
||||
surroundings -= item
|
||||
amount--
|
||||
if(!(path_key in recipe.requirements_mats_blacklist))
|
||||
for(var/material in item.custom_materials)
|
||||
total_materials[material] += item.custom_materials[material]
|
||||
|
||||
return return_list
|
||||
|
||||
/datum/component/personal_crafting/proc/is_recipe_available(datum/crafting_recipe/recipe, mob/user)
|
||||
if((recipe.crafting_flags & CRAFT_MUST_BE_LEARNED) && !(recipe.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
|
||||
@@ -541,17 +530,17 @@
|
||||
return data
|
||||
|
||||
/datum/component/personal_crafting/proc/make_action(datum/crafting_recipe/recipe, mob/user)
|
||||
var/atom/movable/result = construct_item(user, recipe)
|
||||
var/atom/result = construct_item(user, recipe)
|
||||
if(istext(result)) //We failed to make an item and got a fail message
|
||||
to_chat(user, span_warning("Construction failed[result]"))
|
||||
return FALSE
|
||||
if(ismob(user) && isitem(result)) //In case the user is actually possessing a non mob like a machine
|
||||
user.put_in_hands(result)
|
||||
else if(!istype(result, /obj/effect/spawner))
|
||||
result.forceMove(user.drop_location())
|
||||
else if(ismovable(result) && !istype(result, /obj/effect/spawner))
|
||||
var/atom/movable/movable = result
|
||||
movable.forceMove(user.drop_location())
|
||||
to_chat(user, span_notice("[recipe.name] crafted."))
|
||||
user.investigate_log("crafted [recipe]", INVESTIGATE_CRAFTING)
|
||||
recipe.on_craft_completion(user, result)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -723,7 +712,7 @@
|
||||
return FALSE
|
||||
|
||||
/datum/component/personal_crafting/machine
|
||||
ignored_flags = CRAFT_CHECK_DENSITY
|
||||
ignored_flags = CRAFT_CHECK_DENSITY|CRAFT_IGNORE_DO_AFTER
|
||||
|
||||
/datum/component/personal_crafting/machine/get_environment(atom/crafter, list/blacklist = null, radius_range = 1)
|
||||
. = list()
|
||||
@@ -737,5 +726,11 @@
|
||||
continue
|
||||
. += content
|
||||
|
||||
/datum/component/personal_crafting/machine/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings)
|
||||
/datum/component/personal_crafting/machine/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings, final_check = FALSE)
|
||||
return TRUE
|
||||
|
||||
#undef CONTENTS_INSTANCES
|
||||
#undef CONTENTS_MACHINERY
|
||||
#undef CONTENTS_STRUCTURES
|
||||
#undef CONTENTS_REAGENTS
|
||||
#undef CONTENTS_TOOL_BEHAVIOUR
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
/obj/item/stack/sheet/animalhide/mothroach = 2,
|
||||
/obj/item/clothing/shoes/clown_shoes = 1,
|
||||
)
|
||||
parts = list(/obj/item/clothing/shoes/clown_shoes = 1)
|
||||
blacklist = list(
|
||||
/obj/item/clothing/shoes/clown_shoes/combat,
|
||||
/obj/item/clothing/shoes/clown_shoes/banana_shoes,
|
||||
@@ -83,7 +82,6 @@
|
||||
/obj/item/camera = 1,
|
||||
/datum/reagent/water/holywater = 10,
|
||||
)
|
||||
parts = list(/obj/item/camera = 1)
|
||||
category = CAT_ENTERTAINMENT
|
||||
|
||||
|
||||
@@ -186,7 +184,7 @@
|
||||
category = CAT_ENTERTAINMENT
|
||||
tool_behaviors = list(TOOL_WRENCH)
|
||||
reqs = list(/obj/item/flamethrower = 1)
|
||||
structures = list(/obj/structure/toilet = CRAFTING_STRUCTURE_USE) // we will handle the consumption manually in on_craft_completion for this one
|
||||
structures = list(/obj/structure/toilet = CRAFTING_STRUCTURE_CONSUME)
|
||||
result = /obj/structure/toiletbong
|
||||
time = 5 SECONDS
|
||||
steps = list(
|
||||
@@ -199,21 +197,6 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/crafting_recipe/toiletbong/on_craft_completion(mob/user, atom/result)
|
||||
var/obj/structure/toiletbong/toiletbong = result
|
||||
|
||||
// because we want to set the toilet's location and dir, we need to do the consumption manually
|
||||
var/obj/structure/toilet/toilet = locate(/obj/structure/toilet) in range(1)
|
||||
if(toilet)
|
||||
for (var/obj/item/cistern_item in toilet.contents)
|
||||
cistern_item.forceMove(user.drop_location())
|
||||
to_chat(user, span_warning("[cistern_item] falls out of the toilet!"))
|
||||
toiletbong.dir = toilet.dir
|
||||
toiletbong.loc = toilet.loc
|
||||
qdel(toilet)
|
||||
|
||||
to_chat(user, span_notice("[user] attaches the flamethrower to the repurposed toilet."))
|
||||
|
||||
/datum/crafting_recipe/punching_bag
|
||||
name = "Punching Bag"
|
||||
result = /obj/structure/punching_bag
|
||||
|
||||
@@ -72,8 +72,6 @@
|
||||
/obj/item/stock_parts/power_store/cell = 1,
|
||||
)
|
||||
parts = list(
|
||||
/obj/item/stock_parts/servo = 2,
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
/obj/item/stock_parts/power_store/cell = 1,
|
||||
)
|
||||
tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
|
||||
@@ -88,9 +86,6 @@
|
||||
/obj/item/assembly/igniter/condenser = 1,
|
||||
/obj/item/electronics/airlock = 1,
|
||||
)
|
||||
parts = list(
|
||||
/obj/item/electronics/airlock = 1,
|
||||
)
|
||||
time = 5 SECONDS
|
||||
category = CAT_EQUIPMENT
|
||||
|
||||
@@ -112,9 +107,6 @@
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/obj/item/electronics/airlock = 1,
|
||||
)
|
||||
parts = list(
|
||||
/obj/item/electronics/airlock = 1,
|
||||
)
|
||||
time = 5 SECONDS
|
||||
category = CAT_EQUIPMENT
|
||||
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
/obj/item/shard = 1,
|
||||
/obj/item/stack/rods = 1,
|
||||
)
|
||||
parts = list(/obj/item/shard = 1)
|
||||
time = 4 SECONDS
|
||||
category = CAT_WEAPON_MELEE
|
||||
|
||||
|
||||
@@ -448,7 +448,6 @@
|
||||
/obj/item/grenade/chem_grenade = 2,
|
||||
/obj/item/assembly/signaler/anomaly/dimensional = 1,
|
||||
)
|
||||
parts = list(/obj/item/gibtonite = 1, /obj/item/grenade/chem_grenade = 2)
|
||||
tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WELDER)
|
||||
time = 12 SECONDS
|
||||
category = CAT_WEAPON_RANGED
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
/obj/item/assembly/prox_sensor = 1,
|
||||
/obj/item/bodypart/arm/right/robot = 1,
|
||||
)
|
||||
parts = list(/obj/item/reagent_containers/cup/bucket = 1)
|
||||
parts = list(/obj/item/reagent_containers/cup/bucket = 1) //cleanbot/Entered() handles bucket colors
|
||||
time = 4 SECONDS
|
||||
category = CAT_ROBOT
|
||||
|
||||
@@ -70,15 +70,6 @@
|
||||
time = 4 SECONDS
|
||||
category = CAT_ROBOT
|
||||
|
||||
/datum/crafting_recipe/medbot/on_craft_completion(mob/user, atom/result)
|
||||
var/mob/living/basic/bot/medbot/bot = result
|
||||
var/obj/item/storage/medkit/medkit = bot.contents[3]
|
||||
bot.medkit_type = medkit
|
||||
bot.health_analyzer = bot.contents[4]
|
||||
bot.skin = medkit.get_medbot_skin()
|
||||
bot.damage_type_healer = initial(medkit.damagetype_healed) ? initial(medkit.damagetype_healed) : BRUTE
|
||||
bot.update_appearance()
|
||||
|
||||
/datum/crafting_recipe/honkbot
|
||||
name = "Honkbot"
|
||||
result = /mob/living/basic/bot/honkbot
|
||||
@@ -151,7 +142,6 @@
|
||||
/obj/item/food/grown/potato = 1,
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
)
|
||||
parts = list(/obj/item/aicard = 1)
|
||||
category = CAT_ROBOT
|
||||
|
||||
/datum/crafting_recipe/aitater/aispook
|
||||
@@ -163,18 +153,6 @@
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
)
|
||||
|
||||
/datum/crafting_recipe/aitater/on_craft_completion(mob/user, atom/result)
|
||||
var/obj/item/aicard/new_card = result
|
||||
var/obj/item/aicard/base_card = result.contents[1]
|
||||
var/mob/living/silicon/ai = base_card.AI
|
||||
|
||||
if(ai)
|
||||
base_card.AI = null
|
||||
ai.forceMove(new_card)
|
||||
new_card.AI = ai
|
||||
new_card.update_appearance()
|
||||
qdel(base_card)
|
||||
|
||||
/datum/crafting_recipe/mod_core_standard
|
||||
name = "MOD core (Standard)"
|
||||
result = /obj/item/mod/core/standard
|
||||
@@ -213,6 +191,5 @@
|
||||
/obj/item/stack/sheet/glass = 1,
|
||||
/obj/item/soulstone = 1,
|
||||
)
|
||||
parts = list(/obj/item/soulstone = 1)
|
||||
category = CAT_ROBOT
|
||||
crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
name = "Bonfire"
|
||||
time = 6 SECONDS
|
||||
reqs = list(/obj/item/grown/log = 5)
|
||||
parts = list(/obj/item/grown/log = 5)
|
||||
parts = list(/obj/item/grown/log = 5) //Will be returned if the bonfire is dismantled
|
||||
blacklist = list(/obj/item/grown/log/steel)
|
||||
result = /obj/structure/bonfire
|
||||
category = CAT_TOOLS
|
||||
@@ -84,31 +84,29 @@
|
||||
result = /obj/item/shuttle_blueprints/crude
|
||||
reqs = list(
|
||||
/obj/item/paper = 1,
|
||||
/obj/item/toy/crayon = CRAFTING_INGREDIENT_USE,
|
||||
)
|
||||
tool_paths = list(/obj/item/toy/crayon)
|
||||
//we can't use a generic crayon so we spawn a blue one
|
||||
unit_test_spawn_extras = list(/obj/item/toy/crayon/blue = 1)
|
||||
steps = list(
|
||||
"You must use either a a blue crayon, a rainbow crayon, or a spray can.",
|
||||
"The crayon or spray can you use must have at least 10 uses remaining."
|
||||
)
|
||||
time = 10 SECONDS
|
||||
category = CAT_TOOLS
|
||||
var/static/list/valid_types = typecacheof(list(
|
||||
/obj/item/toy/crayon/blue,
|
||||
/obj/item/toy/crayon/rainbow,
|
||||
/obj/item/toy/crayon/spraycan,
|
||||
))
|
||||
|
||||
/datum/crafting_recipe/shuttle_blueprints/check_requirements(mob/user, list/collected_requirements)
|
||||
var/list/crayons = collected_requirements[/obj/item/toy/crayon]
|
||||
for(var/obj/item/toy/crayon/crayon as anything in crayons)
|
||||
if(!is_type_in_list(crayon, list(/obj/item/toy/crayon/blue, /obj/item/toy/crayon/rainbow, /obj/item/toy/crayon/spraycan)))
|
||||
/datum/crafting_recipe/shuttle_blueprints/check_tools(atom/user, list/collected_tools, final_check = FALSE)
|
||||
for(var/obj/item/toy/crayon/crayon in collected_tools)
|
||||
if(!is_type_in_typecache(crayon, valid_types))
|
||||
continue
|
||||
if(!crayon.check_empty(user, 10))
|
||||
if(final_check ? crayon.use_charges(user, 10) : crayon.check_empty(user, 10))
|
||||
return TRUE
|
||||
|
||||
/datum/crafting_recipe/shuttle_blueprints/on_craft_completion(mob/user, atom/result)
|
||||
var/static/list/valid_types = list(/obj/item/toy/crayon/blue, /obj/item/toy/crayon/rainbow, /obj/item/toy/crayon/spraycan)
|
||||
for(var/valid_type in valid_types)
|
||||
var/obj/item/toy/crayon/crayon = locate(valid_type) in range(1)
|
||||
if(!crayon)
|
||||
continue
|
||||
if(crayon.use_charges(user, 10))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
/datum/crafting_recipe/makeshift_radio_jammer
|
||||
name = "Makeshift Radio Jammer"
|
||||
@@ -119,3 +117,4 @@
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
)
|
||||
category = CAT_TOOLS
|
||||
|
||||
|
||||
@@ -76,10 +76,12 @@ Behavior that's still missing from this component that original food items had t
|
||||
/datum/component/edible/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, PROC_REF(UseByAnimal))
|
||||
RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, PROC_REF(OnCraft))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ON_CRAFT, PROC_REF(OnCraft))
|
||||
RegisterSignal(parent, COMSIG_OOZE_EAT_ATOM, PROC_REF(on_ooze_eat))
|
||||
RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, PROC_REF(edible_ingredient_added))
|
||||
RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(created_by_processing))
|
||||
RegisterSignal(parent, COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, PROC_REF(on_material_effects))
|
||||
RegisterSignal(parent, COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS, PROC_REF(on_remove_material_effects))
|
||||
|
||||
if(isturf(parent))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(on_entered))
|
||||
@@ -105,7 +107,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ATOM_ATTACK_ANIMAL,
|
||||
COMSIG_ATOM_ATTACK_HAND,
|
||||
COMSIG_ATOM_CHECKPARTS,
|
||||
COMSIG_ATOM_ON_CRAFT,
|
||||
COMSIG_ATOM_CREATEDBY_PROCESSING,
|
||||
COMSIG_ATOM_ENTERED,
|
||||
COMSIG_FOOD_INGREDIENT_ADDED,
|
||||
@@ -333,11 +335,11 @@ Behavior that's still missing from this component that original food items had t
|
||||
this_food.desc = "[original_atom.desc]"
|
||||
|
||||
///Called when food is crafted through a crafting recipe datum.
|
||||
/datum/component/edible/proc/OnCraft(datum/source, list/parts_list, datum/crafting_recipe/food/recipe)
|
||||
/datum/component/edible/proc/OnCraft(datum/source, list/components, datum/crafting_recipe/food/recipe)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/this_food = parent
|
||||
for(var/obj/item/food/crafted_part in parts_list)
|
||||
for(var/obj/item/food/crafted_part in components)
|
||||
if(!crafted_part.reagents)
|
||||
continue
|
||||
this_food.reagents.maximum_volume += crafted_part.reagents.maximum_volume
|
||||
@@ -742,4 +744,19 @@ Behavior that's still missing from this component that original food items had t
|
||||
qdel(food)
|
||||
return COMPONENT_ATOM_EATEN
|
||||
|
||||
#define REQUIRED_MAT_FLAGS (MATERIAL_EFFECTS|MATERIAL_NO_EDIBILITY)
|
||||
|
||||
///Calls on_edible_applied() for the main material composing the atom parent
|
||||
/datum/component/edible/proc/on_material_effects(atom/source, list/materials, datum/material/main_material)
|
||||
SIGNAL_HANDLER
|
||||
if((source.material_flags & REQUIRED_MAT_FLAGS) == REQUIRED_MAT_FLAGS)
|
||||
main_material.on_edible_applied(source, src)
|
||||
|
||||
///Calls on_edible_removed() for the main material no longer composing the atom parent
|
||||
/datum/component/edible/proc/on_remove_material_effects(atom/source, list/materials, datum/material/main_material)
|
||||
SIGNAL_HANDLER
|
||||
if((source.material_flags & REQUIRED_MAT_FLAGS) == REQUIRED_MAT_FLAGS)
|
||||
main_material.on_edible_removed(source, src)
|
||||
|
||||
#undef REQUIRED_MAT_FLAGS
|
||||
#undef DEFAULT_EDIBLE_VOLUME
|
||||
|
||||
@@ -139,8 +139,7 @@
|
||||
|
||||
else
|
||||
grilled_result = new cook_result(original_object.loc)
|
||||
if(original_object.custom_materials)
|
||||
grilled_result.set_custom_materials(original_object.custom_materials)
|
||||
grilled_result.set_custom_materials(original_object.custom_materials)
|
||||
|
||||
if(IsEdible(grilled_result) && positive_result)
|
||||
BLACKBOX_LOG_FOOD_MADE(grilled_result.type)
|
||||
|
||||
@@ -2,16 +2,14 @@
|
||||
* # Custom Atom Component
|
||||
*
|
||||
* When added to an atom, item ingredients can be put into that.
|
||||
* The sprite is updated and reagents are transferred.
|
||||
* The sprite is updated and reagents and custom materials are transferred.
|
||||
*
|
||||
* If the component is added to something that is processed, creating new objects (being cut, for example),
|
||||
* the replacement type needs to also have the component. The ingredients will be copied over. Reagents are not
|
||||
* copied over since other components already take care of that.
|
||||
*/
|
||||
/datum/component/customizable_reagent_holder
|
||||
/datum/component/ingredients_holder
|
||||
can_transfer = TRUE
|
||||
///List of item ingredients.
|
||||
var/list/obj/item/ingredients
|
||||
///Type path of replacement atom.
|
||||
var/replacement
|
||||
///Type of fill, can be [CUSTOM_INGREDIENT_ICON_NOCHANGE] for example.
|
||||
@@ -25,12 +23,19 @@
|
||||
/// Adds screentips for all items that call on this proc, defaults to "Add"
|
||||
var/screentip_verb
|
||||
|
||||
/datum/component/customizable_reagent_holder/Initialize(
|
||||
/// Stores the names of the ingredients used on the holder, to pass down if processed into new instances.
|
||||
var/list/ingredient_names
|
||||
///List of colors to be used for fillings, to pass down if processed into new instances.
|
||||
var/list/filling_colors
|
||||
/// The custom name attached to the original name of the holder, to pass down if processed into new instances.
|
||||
var/custom_name
|
||||
|
||||
/datum/component/ingredients_holder/Initialize(
|
||||
atom/replacement,
|
||||
fill_type,
|
||||
ingredient_type = CUSTOM_INGREDIENT_TYPE_EDIBLE,
|
||||
max_ingredients = MAX_ATOM_OVERLAYS - 3, // The cap is >= MAX_ATOM_OVERLAYS so we reserve 2 for top /bottom of item + 1 to stay under cap
|
||||
list/obj/item/initial_ingredients = null,
|
||||
datum/component/ingredients_holder/processed_holder, //when processing a holder, the results receive their own comps, but need the ingredient names and filling passed down
|
||||
screentip_verb = "Add",
|
||||
)
|
||||
if(!isatom(parent))
|
||||
@@ -48,30 +53,29 @@
|
||||
src.ingredient_type = ingredient_type
|
||||
src.screentip_verb = screentip_verb
|
||||
|
||||
if (initial_ingredients)
|
||||
for (var/_ingredient in initial_ingredients)
|
||||
var/obj/item/ingredient = _ingredient
|
||||
add_ingredient(ingredient)
|
||||
handle_fill(ingredient)
|
||||
if(!processed_holder || !length(processed_holder.ingredient_names))
|
||||
return
|
||||
|
||||
ingredient_names = processed_holder.ingredient_names
|
||||
custom_name = processed_holder.custom_name
|
||||
atom_parent.name = "[custom_adjective()] [custom_name] [atom_parent.name]"
|
||||
for(var/fillcol as anything in processed_holder.filling_colors)
|
||||
apply_fill(fillcol)
|
||||
|
||||
/datum/component/customizable_reagent_holder/Destroy(force)
|
||||
/datum/component/ingredients_holder/Destroy(force)
|
||||
QDEL_NULL(top_overlay)
|
||||
LAZYCLEARLIST(ingredients)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/component/customizable_reagent_holder/RegisterWithParent()
|
||||
/datum/component/ingredients_holder/RegisterWithParent()
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(customizable_attack))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(food_exited))
|
||||
RegisterSignal(parent, COMSIG_ATOM_PROCESSED, PROC_REF(on_processed))
|
||||
RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item))
|
||||
ADD_TRAIT(parent, TRAIT_CUSTOMIZABLE_REAGENT_HOLDER, REF(src))
|
||||
ADD_TRAIT(parent, TRAIT_INGREDIENTS_HOLDER, INNATE_TRAIT)
|
||||
|
||||
|
||||
/datum/component/customizable_reagent_holder/UnregisterFromParent()
|
||||
/datum/component/ingredients_holder/UnregisterFromParent()
|
||||
. = ..()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ATOM_ATTACKBY,
|
||||
@@ -80,9 +84,9 @@
|
||||
COMSIG_ATOM_PROCESSED,
|
||||
COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM,
|
||||
))
|
||||
REMOVE_TRAIT(parent, TRAIT_CUSTOMIZABLE_REAGENT_HOLDER, REF(src))
|
||||
REMOVE_TRAIT(parent, TRAIT_INGREDIENTS_HOLDER, INNATE_TRAIT)
|
||||
|
||||
/datum/component/customizable_reagent_holder/PostTransfer(datum/new_parent)
|
||||
/datum/component/ingredients_holder/PostTransfer(datum/new_parent)
|
||||
if(!isatom(new_parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/atom/atom_parent = new_parent
|
||||
@@ -90,21 +94,18 @@
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
///Handles when the customizable food is examined.
|
||||
/datum/component/customizable_reagent_holder/proc/on_examine(atom/A, mob/user, list/examine_list)
|
||||
/datum/component/ingredients_holder/proc/on_examine(atom/A, mob/user, list/examine_list)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/atom_parent = parent
|
||||
var/list/ingredients_listed = list()
|
||||
for(var/obj/item/ingredient as anything in ingredients)
|
||||
ingredients_listed += "\a [ingredient.name]"
|
||||
|
||||
examine_list += "It [LAZYLEN(ingredients) \
|
||||
? "contains [english_list(ingredients_listed)] making a [custom_adjective()]-sized [initial(atom_parent.name)]" \
|
||||
examine_list += "It [LAZYLEN(ingredient_names) \
|
||||
? "contains [english_list(ingredient_names)] making a [custom_adjective()]-sized [initial(atom_parent.name)]" \
|
||||
: "does not contain any ingredients"]."
|
||||
|
||||
//// Proc that checks if an ingredient is valid or not, returning false if it isnt and true if it is.
|
||||
/datum/component/customizable_reagent_holder/proc/valid_ingredient(obj/ingredient)
|
||||
if (HAS_TRAIT(ingredient, TRAIT_CUSTOMIZABLE_REAGENT_HOLDER))
|
||||
/datum/component/ingredients_holder/proc/valid_ingredient(obj/ingredient)
|
||||
if (HAS_TRAIT(ingredient, TRAIT_INGREDIENTS_HOLDER))
|
||||
return FALSE
|
||||
if(HAS_TRAIT(ingredient, TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT))
|
||||
return TRUE
|
||||
@@ -116,7 +117,7 @@
|
||||
return TRUE
|
||||
|
||||
///Handles when the customizable food is attacked by something.
|
||||
/datum/component/customizable_reagent_holder/proc/customizable_attack(datum/source, obj/ingredient, mob/attacker, silent = FALSE, force = FALSE)
|
||||
/datum/component/ingredients_holder/proc/customizable_attack(datum/source, obj/ingredient, mob/attacker, silent = FALSE, force = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (!valid_ingredient(ingredient))
|
||||
@@ -126,38 +127,34 @@
|
||||
attacker.balloon_alert(attacker, "doesn't go on that!")
|
||||
return
|
||||
|
||||
if (LAZYLEN(ingredients) >= max_ingredients)
|
||||
if (LAZYLEN(ingredient_names) >= max_ingredients)
|
||||
attacker.balloon_alert(attacker, "too full!")
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
var/atom/atom_parent = parent
|
||||
if(!attacker.transferItemToLoc(ingredient, atom_parent))
|
||||
if(!attacker.transferItemToLoc(ingredient, parent))
|
||||
return
|
||||
if (replacement)
|
||||
var/atom/replacement_parent = new replacement(atom_parent.drop_location())
|
||||
ingredient.forceMove(replacement_parent)
|
||||
replacement = null
|
||||
replacement_parent.TakeComponent(src)
|
||||
handle_reagents(atom_parent)
|
||||
qdel(atom_parent)
|
||||
handle_reagents(ingredient)
|
||||
add_ingredient(ingredient)
|
||||
handle_fill(ingredient)
|
||||
|
||||
|
||||
///Handles the icon update for a new ingredient.
|
||||
/datum/component/customizable_reagent_holder/proc/handle_fill(obj/item/ingredient)
|
||||
if (fill_type == CUSTOM_INGREDIENT_ICON_NOCHANGE)
|
||||
///Extract the filling color from the ingredient, than calls apply_fill()
|
||||
/datum/component/ingredients_holder/proc/get_fill(obj/item/ingredient)
|
||||
// get average color
|
||||
var/icon/icon = new(ingredient.icon, ingredient.icon_state)
|
||||
if(ingredient.color)
|
||||
icon.Blend(ingredient.color, ICON_MULTIPLY)
|
||||
icon.Scale(1, 1)
|
||||
var/fillcol = copytext(icon.GetPixel(1, 1), 1, 8) // remove opacity
|
||||
LAZYADD(filling_colors, fillcol)
|
||||
apply_fill(fillcol)
|
||||
|
||||
///Add a filling overlay to the parent atom.
|
||||
/datum/component/ingredients_holder/proc/apply_fill(fill_color)
|
||||
if(fill_type == CUSTOM_INGREDIENT_ICON_NOCHANGE)
|
||||
//don't bother doing the icon procs
|
||||
return
|
||||
var/atom/atom_parent = parent
|
||||
var/mutable_appearance/filling = mutable_appearance(atom_parent.icon, "[initial(atom_parent.icon_state)]_filling")
|
||||
// get average color
|
||||
var/icon/icon = new(ingredient.icon, ingredient.icon_state)
|
||||
icon.Scale(1, 1)
|
||||
var/fillcol = copytext(icon.GetPixel(1, 1), 1, 8) // remove opacity
|
||||
filling.color = fillcol
|
||||
|
||||
filling.color = fill_color
|
||||
switch(fill_type)
|
||||
if(CUSTOM_INGREDIENT_ICON_SCATTER)
|
||||
filling.pixel_w = rand(-1,1)
|
||||
@@ -165,18 +162,18 @@
|
||||
if(CUSTOM_INGREDIENT_ICON_STACK)
|
||||
filling.pixel_w = rand(-1,1)
|
||||
// we're gonna abuse position layering to ensure overlays render right
|
||||
filling.pixel_y = -LAZYLEN(ingredients)
|
||||
filling.pixel_z = 2 * LAZYLEN(ingredients) - 1 + LAZYLEN(ingredients)
|
||||
filling.pixel_y = -LAZYLEN(ingredient_names)
|
||||
filling.pixel_z = 3 * LAZYLEN(ingredient_names) - 1
|
||||
if(CUSTOM_INGREDIENT_ICON_STACKPLUSTOP)
|
||||
filling.pixel_w = rand(-1,1)
|
||||
// similar here
|
||||
filling.pixel_y = -LAZYLEN(ingredients)
|
||||
filling.pixel_z = 2 * LAZYLEN(ingredients) - 1 + LAZYLEN(ingredients)
|
||||
filling.pixel_y = -LAZYLEN(ingredient_names)
|
||||
filling.pixel_z = 3 * LAZYLEN(ingredient_names) - 1
|
||||
if (top_overlay) // delete old top if exists
|
||||
atom_parent.cut_overlay(top_overlay)
|
||||
top_overlay = mutable_appearance(atom_parent.icon, "[atom_parent.icon_state]_top")
|
||||
top_overlay.pixel_y = -(LAZYLEN(ingredients) + 1)
|
||||
top_overlay.pixel_z = 2 * LAZYLEN(ingredients) + 3 + LAZYLEN(ingredients) + 1
|
||||
top_overlay.pixel_y = -LAZYLEN(ingredient_names) - 1
|
||||
top_overlay.pixel_z = 3 * LAZYLEN(ingredient_names) + 4
|
||||
atom_parent.add_overlay(filling)
|
||||
atom_parent.add_overlay(top_overlay)
|
||||
return
|
||||
@@ -191,7 +188,7 @@
|
||||
|
||||
|
||||
///Takes the reagents from an ingredient.
|
||||
/datum/component/customizable_reagent_holder/proc/handle_reagents(obj/item/ingredient)
|
||||
/datum/component/ingredients_holder/proc/handle_reagents(obj/item/ingredient)
|
||||
var/atom/atom_parent = parent
|
||||
if (atom_parent.reagents && ingredient.reagents)
|
||||
atom_parent.reagents.maximum_volume += ingredient.reagents.maximum_volume // If we don't do this custom food starts voiding reagents past a certain point.
|
||||
@@ -200,21 +197,50 @@
|
||||
|
||||
|
||||
///Adds a new ingredient and updates the parent's name.
|
||||
/datum/component/customizable_reagent_holder/proc/add_ingredient(obj/item/ingredient)
|
||||
/datum/component/ingredients_holder/proc/add_ingredient(obj/item/ingredient)
|
||||
var/atom/atom_parent = parent
|
||||
LAZYADD(ingredients, ingredient)
|
||||
|
||||
if (replacement)
|
||||
var/atom/replacement_parent = new replacement(atom_parent.drop_location())
|
||||
ingredient.forceMove(replacement_parent)
|
||||
replacement = null
|
||||
replacement_parent.TakeComponent(src)
|
||||
atom_parent = parent
|
||||
handle_reagents(atom_parent)
|
||||
qdel(atom_parent)
|
||||
|
||||
handle_reagents(ingredient)
|
||||
|
||||
LAZYADD(ingredient_names, "\a [ingredient.name]")
|
||||
if(isitem(atom_parent))
|
||||
var/obj/item/item_parent = atom_parent
|
||||
if(ingredient.w_class > item_parent.w_class)
|
||||
item_parent.update_weight_class(ingredient.w_class)
|
||||
atom_parent.name = "[custom_adjective()] [custom_type()] [initial(atom_parent.name)]"
|
||||
if(!custom_name)
|
||||
set_custom_name(ingredient)
|
||||
atom_parent.name = "[custom_adjective()] [custom_name] [initial(atom_parent.name)]"
|
||||
SEND_SIGNAL(atom_parent, COMSIG_ATOM_CUSTOMIZED, ingredient)
|
||||
SEND_SIGNAL(ingredient, COMSIG_ITEM_USED_AS_INGREDIENT, atom_parent)
|
||||
|
||||
get_fill(ingredient)
|
||||
handle_materials(ingredient)
|
||||
|
||||
if(ingredient.loc != atom_parent)
|
||||
ingredient.forceMove(atom_parent)
|
||||
|
||||
///Rebuilds the custom materials the holder is composed of based on the materials of each ingredient
|
||||
/datum/component/ingredients_holder/proc/handle_materials(obj/item/ingredient, remove = FALSE)
|
||||
if(!ingredient.custom_materials)
|
||||
return
|
||||
var/atom/atom_parent = parent
|
||||
var/list/new_materials = atom_parent.custom_materials?.Copy() || list()
|
||||
for(var/mat in ingredient.custom_materials)
|
||||
new_materials[mat] += ingredient.custom_materials[mat] * (remove ? -1 : 1)
|
||||
atom_parent.set_custom_materials(new_materials)
|
||||
|
||||
///Gives an adjective to describe the size of the custom food.
|
||||
/datum/component/customizable_reagent_holder/proc/custom_adjective()
|
||||
switch(LAZYLEN(ingredients))
|
||||
/datum/component/ingredients_holder/proc/custom_adjective()
|
||||
switch(LAZYLEN(ingredient_names))
|
||||
if (0 to 2)
|
||||
return "small"
|
||||
if (3 to 5)
|
||||
@@ -228,44 +254,39 @@
|
||||
|
||||
|
||||
///Gives the type of custom food (based on what the first ingredient was).
|
||||
/datum/component/customizable_reagent_holder/proc/custom_type()
|
||||
var/custom_type = "empty"
|
||||
if (LAZYLEN(ingredients))
|
||||
var/obj/item/first_ingredient = ingredients[1]
|
||||
if (istype(first_ingredient, /obj/item/food/meat))
|
||||
var/obj/item/food/meat/meat = first_ingredient
|
||||
if (meat.subjectname)
|
||||
custom_type = meat.subjectname
|
||||
else if (meat.subjectjob)
|
||||
custom_type = meat.subjectjob
|
||||
if (custom_type == "empty" && first_ingredient.name)
|
||||
custom_type = first_ingredient.name
|
||||
return custom_type
|
||||
|
||||
/datum/component/ingredients_holder/proc/set_custom_name(obj/item/ingredient)
|
||||
if (istype(ingredient, /obj/item/food/meat))
|
||||
var/obj/item/food/meat/meat = ingredient
|
||||
if (meat.subjectname)
|
||||
custom_name = meat.subjectname
|
||||
return
|
||||
if (meat.subjectjob)
|
||||
custom_name = meat.subjectjob
|
||||
return
|
||||
custom_name = ingredient.name
|
||||
|
||||
///Returns the color of the input mixed with the top_overlay's color.
|
||||
/datum/component/customizable_reagent_holder/proc/mix_color(color)
|
||||
if(LAZYLEN(ingredients) == 1 || !top_overlay)
|
||||
/datum/component/ingredients_holder/proc/mix_color(color)
|
||||
if(length(filling_colors) == 1 || !top_overlay)
|
||||
return color
|
||||
else
|
||||
var/list/rgbcolor = list(0,0,0,0)
|
||||
var/customcolor = GetColors(color)
|
||||
var/ingcolor = GetColors(top_overlay.color)
|
||||
rgbcolor[1] = (customcolor[1]+ingcolor[1])/2
|
||||
rgbcolor[2] = (customcolor[2]+ingcolor[2])/2
|
||||
rgbcolor[3] = (customcolor[3]+ingcolor[3])/2
|
||||
rgbcolor[4] = (customcolor[4]+ingcolor[4])/2
|
||||
return rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3], rgbcolor[4])
|
||||
var/list/rgbcolor = list(0,0,0,0)
|
||||
var/customcolor = GetColors(color)
|
||||
var/ingcolor = GetColors(top_overlay.color)
|
||||
rgbcolor[1] = (customcolor[1]+ingcolor[1])/2
|
||||
rgbcolor[2] = (customcolor[2]+ingcolor[2])/2
|
||||
rgbcolor[3] = (customcolor[3]+ingcolor[3])/2
|
||||
rgbcolor[4] = (customcolor[4]+ingcolor[4])/2
|
||||
return rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3], rgbcolor[4])
|
||||
|
||||
|
||||
///Copies over the parent's ingredients to the processing results (such as slices when the parent is cut).
|
||||
/datum/component/customizable_reagent_holder/proc/on_processed(datum/source, mob/living/user, obj/item/ingredient, list/atom/results)
|
||||
///Copies over the parent's fillings and name of ingredients to the processing results (such as slices when the parent is cut).
|
||||
/datum/component/ingredients_holder/proc/on_processed(datum/source, mob/living/user, obj/item/ingredient, list/atom/results)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// Reagents are not transferred since that should be handled elsewhere.
|
||||
for (var/r in results)
|
||||
var/atom/result = r
|
||||
result.AddComponent(/datum/component/customizable_reagent_holder, null, fill_type, ingredient_type = ingredient_type, max_ingredients = max_ingredients, initial_ingredients = ingredients)
|
||||
// Reagents are not transferred since that should be handled elsewhere
|
||||
// while custom materials are already transferred evenly between results by atom/proc/StartProcessingAtom()
|
||||
for (var/atom/result as anything in results)
|
||||
result.AddComponent(/datum/component/ingredients_holder, null, fill_type, ingredient_type = ingredient_type, max_ingredients = max_ingredients, processed_holder = src)
|
||||
|
||||
/**
|
||||
* Adds context sensitivy directly to the customizable reagent holder file for screentips
|
||||
@@ -275,7 +296,7 @@
|
||||
* * held_item - refers to the item in your hand, which is hopefully an ingredient
|
||||
* * user - refers to user who will see the screentip when the proper context and tool are there
|
||||
*/
|
||||
/datum/component/customizable_reagent_holder/proc/on_requesting_context_from_item(datum/source, list/context, obj/item/held_item, mob/user)
|
||||
/datum/component/ingredients_holder/proc/on_requesting_context_from_item(datum/source, list/context, obj/item/held_item, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// only accept valid ingredients
|
||||
@@ -287,6 +308,7 @@
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/// Clear refs if our food "goes away" somehow
|
||||
/datum/component/customizable_reagent_holder/proc/food_exited(datum/source, atom/movable/gone)
|
||||
/datum/component/ingredients_holder/proc/food_exited(datum/source, atom/movable/gone)
|
||||
SIGNAL_HANDLER
|
||||
LAZYREMOVE(ingredients, gone)
|
||||
LAZYREMOVE(ingredient_names, "\a [gone.name]")
|
||||
handle_materials(gone, remove = TRUE)
|
||||
@@ -22,9 +22,10 @@
|
||||
|
||||
/datum/component/storm_hating/UnregisterFromParent()
|
||||
. = ..()
|
||||
on_area_exited(parent, get_area(parent))
|
||||
UnregisterSignal(parent, COMSIG_ENTER_AREA)
|
||||
RegisterSignal(parent, COMSIG_EXIT_AREA)
|
||||
UnregisterSignal(parent, list(COMSIG_ENTER_AREA, COMSIG_EXIT_AREA))
|
||||
var/area/old_area = get_area(parent)
|
||||
if(old_area)
|
||||
on_area_exited(parent, old_area)
|
||||
|
||||
/datum/component/storm_hating/proc/on_area_entered(atom/source, area/new_area)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -38,18 +38,15 @@
|
||||
apply_dried_status(resulting_atom, drying_user)
|
||||
qdel(source)
|
||||
return
|
||||
else if(istype(source, /obj/item/food) && ispath(dry_result, /obj/item/food))
|
||||
|
||||
var/obj/item/food/resulting_atom = new dry_result(source.loc)
|
||||
if(istype(source, /obj/item/food) && ispath(dry_result, /obj/item/food))
|
||||
var/obj/item/food/source_food = source
|
||||
var/obj/item/food/resulting_food = new dry_result(source.loc)
|
||||
resulting_food.reagents.clear_reagents()
|
||||
source_food.reagents.trans_to(resulting_food, source_food.reagents.total_volume)
|
||||
apply_dried_status(resulting_food, drying_user)
|
||||
qdel(source)
|
||||
return
|
||||
else
|
||||
var/atom/movable/resulting_atom = new dry_result(source.loc)
|
||||
apply_dried_status(resulting_atom, drying_user)
|
||||
qdel(source)
|
||||
resulting_atom.reagents.clear_reagents()
|
||||
source_food.reagents.trans_to(resulting_atom, source_food.reagents.total_volume)
|
||||
resulting_atom.set_custom_materials(source.custom_materials)
|
||||
apply_dried_status(resulting_atom, drying_user)
|
||||
qdel(source)
|
||||
|
||||
/datum/element/dryable/proc/apply_dried_status(atom/target, datum/weakref/drying_user)
|
||||
ADD_TRAIT(target, TRAIT_DRIED, ELEMENT_TRAIT(type))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Manages the elevation of the turf the source is on (can be the turf itself)
|
||||
* Manages the elevation of the turf the source is on
|
||||
* The atom with the highest pixel_shift gets to set the elevation of the turf to that value.
|
||||
*/
|
||||
/datum/element/elevation
|
||||
@@ -10,24 +10,17 @@
|
||||
|
||||
/datum/element/elevation/Attach(datum/target, pixel_shift)
|
||||
. = ..()
|
||||
if(!isatom(target) || isarea(target))
|
||||
if(!ismovable(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
ADD_TRAIT(target, TRAIT_ELEVATING_OBJECT, ref(src))
|
||||
|
||||
src.pixel_shift = pixel_shift
|
||||
|
||||
if(ismovable(target))
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
||||
|
||||
var/atom/atom_target = target
|
||||
if(isturf(atom_target.loc))
|
||||
var/turf/turf = atom_target.loc
|
||||
if(!HAS_TRAIT(turf, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift)))
|
||||
RegisterSignal(turf, COMSIG_TURF_RESET_ELEVATION, PROC_REF(check_elevation))
|
||||
RegisterSignal(turf, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf))
|
||||
reset_elevation(turf)
|
||||
ADD_TRAIT(turf, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), ref(target))
|
||||
register_turf(atom_target, atom_target.loc)
|
||||
|
||||
/datum/element/elevation/Detach(atom/movable/source)
|
||||
unregister_turf(source, source.loc)
|
||||
@@ -53,12 +46,16 @@
|
||||
/datum/element/elevation/proc/on_moved(atom/movable/source, atom/oldloc)
|
||||
SIGNAL_HANDLER
|
||||
unregister_turf(source, oldloc)
|
||||
if(isturf(source.loc))
|
||||
if(!HAS_TRAIT(source.loc, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift)))
|
||||
RegisterSignal(source.loc, COMSIG_TURF_RESET_ELEVATION, PROC_REF(check_elevation))
|
||||
RegisterSignal(source.loc, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf))
|
||||
reset_elevation(source.loc)
|
||||
ADD_TRAIT(source.loc, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), ref(source))
|
||||
register_turf(source, source.loc)
|
||||
|
||||
/datum/element/elevation/proc/register_turf(atom/movable/source, atom/location)
|
||||
if(!isturf(location))
|
||||
return
|
||||
if(!HAS_TRAIT(location, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift)))
|
||||
RegisterSignal(location, COMSIG_TURF_RESET_ELEVATION, PROC_REF(check_elevation))
|
||||
RegisterSignal(location, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf))
|
||||
reset_elevation(location)
|
||||
ADD_TRAIT(location, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), ref(source))
|
||||
|
||||
/datum/element/elevation/proc/unregister_turf(atom/movable/source, atom/location)
|
||||
if(!isturf(location))
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
result = new result_typepath(result_loc, stack_source.amount)
|
||||
else
|
||||
result = new result_typepath(result_loc)
|
||||
result.set_custom_materials(source.custom_materials)
|
||||
|
||||
var/efficiency = istype(used_microwave) ? used_microwave.efficiency : 1
|
||||
SEND_SIGNAL(result, COMSIG_ITEM_MICROWAVE_COOKED, source, efficiency)
|
||||
|
||||
@@ -152,6 +152,14 @@ Simple datum which is instanced once per type and is used for every object of sa
|
||||
if(beauty_modifier >= 0.15 && HAS_TRAIT(source, TRAIT_FISHING_BAIT))
|
||||
source.RemoveElement(/datum/element/shiny_bait)
|
||||
|
||||
////Called in `/datum/component/edible/proc/on_material_effects`
|
||||
/datum/material/proc/on_edible_applied(atom/source, datum/component/edible/edible)
|
||||
return
|
||||
|
||||
////Called in `/datum/component/edible/proc/on_remove_material_effects`
|
||||
/datum/material/proc/on_edible_removed(atom/source, datum/component/edible/edible)
|
||||
return
|
||||
|
||||
/**
|
||||
* This proc is called when the mat is found in an item that's consumed by accident. see /obj/item/proc/on_accidental_consumption.
|
||||
* Arguments
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
|
||||
/datum/material/meat/on_main_applied(atom/source, mat_amount, multiplier)
|
||||
. = ..()
|
||||
if(!IS_EDIBLE(source))
|
||||
make_edible(source, mat_amount, multiplier)
|
||||
make_edible(source, mat_amount, multiplier)
|
||||
ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //The rod itself is the bait... sorta.
|
||||
|
||||
/datum/material/meat/on_applied(atom/source, mat_amount, multiplier)
|
||||
@@ -37,21 +36,44 @@
|
||||
if(IS_EDIBLE(source))
|
||||
make_edible(source, mat_amount, multiplier)
|
||||
|
||||
/datum/material/meat/on_edible_applied(atom/source, datum/component/edible/edible)
|
||||
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment, /datum/reagent/consumable/nutriment/protein, keep_data = TRUE)
|
||||
var/datum/reagent/meaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment/protein)
|
||||
if(meaty_chem)
|
||||
LAZYSET(meaty_chem.data, "meat", length(meaty_chem.data) || 1) //adds meatiness to its tastes
|
||||
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment/fat/oil, /datum/reagent/consumable/nutriment/fat, include_source_subtypes = TRUE, keep_data = TRUE)
|
||||
meaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment/fat)
|
||||
if(meaty_chem)
|
||||
LAZYSET(meaty_chem.data, "meat", length(meaty_chem.data) || 1) //adds meatiness to its tastes
|
||||
source.AddComponentFrom(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible, foodtypes = MEAT)
|
||||
|
||||
/datum/material/meat/on_edible_removed(atom/source, datum/component/edible/edible)
|
||||
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment/protein, /datum/reagent/consumable/nutriment, keep_data = TRUE)
|
||||
var/datum/reagent/unmeaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment)
|
||||
if(unmeaty_chem)
|
||||
LAZYREMOVE(unmeaty_chem.data, "meat")
|
||||
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment/fat, /datum/reagent/consumable/nutriment/fat/oil, keep_data = TRUE)
|
||||
unmeaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment/fat/oil)
|
||||
if(unmeaty_chem)
|
||||
LAZYREMOVE(unmeaty_chem.data, "meat")
|
||||
//the edible source is removed by on_removed()
|
||||
|
||||
/datum/material/meat/proc/make_edible(atom/source, mat_amount, multiplier)
|
||||
if(source.material_flags & MATERIAL_NO_EDIBILITY)
|
||||
return
|
||||
var/protein_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
|
||||
var/fat_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
|
||||
|
||||
source.AddComponentFrom(
|
||||
source.AddComponentFrom( \
|
||||
SOURCE_EDIBLE_MEAT_MAT, \
|
||||
/datum/component/edible, \
|
||||
initial_reagents = list(/datum/reagent/consumable/nutriment/protein = protein_count, /datum/reagent/consumable/nutriment/fat = fat_count), \
|
||||
foodtypes = RAW | MEAT, \
|
||||
eat_time = 3 SECONDS, \
|
||||
tastes = list("meat"))
|
||||
tastes = list("meat" = 1))
|
||||
|
||||
source.AddComponent(
|
||||
/datum/component/bloody_spreader,\
|
||||
blood_left = (protein_count + fat_count) * 0.3,\
|
||||
blood_left = (protein_count + fat_count) * 0.3 * multiplier,\
|
||||
)
|
||||
|
||||
// Turfs can't handle the meaty goodness of blood walk.
|
||||
@@ -62,7 +84,7 @@
|
||||
/datum/component/blood_walk,\
|
||||
blood_type = /obj/effect/decal/cleanable/blood,\
|
||||
blood_spawn_chance = 35,\
|
||||
max_blood = (protein_count + fat_count) * 0.3,\
|
||||
max_blood = (protein_count + fat_count) * 0.3 * multiplier,\
|
||||
)
|
||||
|
||||
/datum/material/meat/on_removed(atom/source, mat_amount, multiplier)
|
||||
@@ -70,6 +92,7 @@
|
||||
source.RemoveComponentSource(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible)
|
||||
qdel(source.GetComponent(/datum/component/blood_walk))
|
||||
qdel(source.GetComponent(/datum/component/bloody_spreader))
|
||||
source.RemoveComponentSource(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible)
|
||||
|
||||
/datum/material/meat/on_main_removed(atom/source, mat_amount, multiplier)
|
||||
. = ..()
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
|
||||
/datum/material/pizza/on_main_applied(atom/source, mat_amount, multiplier)
|
||||
. = ..()
|
||||
if(!IS_EDIBLE(source))
|
||||
make_edible(source, mat_amount, multiplier)
|
||||
make_edible(source, mat_amount)
|
||||
ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //the fishing rod itself is the bait... sorta.
|
||||
|
||||
/datum/material/pizza/on_applied(atom/source, mat_amount, multiplier)
|
||||
@@ -36,16 +35,31 @@
|
||||
if(IS_EDIBLE(source))
|
||||
make_edible(source, mat_amount, multiplier)
|
||||
|
||||
/datum/material/pizza/proc/make_edible(atom/source, mat_amount, multiplier)
|
||||
var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
|
||||
var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
|
||||
source.AddComponentFrom(
|
||||
SOURCE_EDIBLE_PIZZA_MAT, \
|
||||
/datum/material/pizza/on_edible_applied(atom/source, datum/component/edible/edible)
|
||||
for(var/datum/reagent/consumable/nutriment/foodchem in source.reagents.reagent_list)
|
||||
var/list/margherita_tastes = /obj/item/food/pizza/margherita::tastes
|
||||
for(var/taste in margherita_tastes)
|
||||
LAZYSET(foodchem.data, taste, 1)
|
||||
source.AddComponentFrom(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible, foodtypes = GRAIN | DAIRY | VEGETABLES)
|
||||
|
||||
/datum/material/pizza/on_edible_removed(atom/source, datum/component/edible/edible)
|
||||
for(var/datum/reagent/consumable/nutriment/foodchem in source.reagents.reagent_list)
|
||||
var/list/margherita_tastes = /obj/item/food/pizza/margherita::tastes
|
||||
for(var/taste in margherita_tastes)
|
||||
LAZYREMOVE(foodchem.data, taste)
|
||||
//the edible source is removed by on_removed()
|
||||
|
||||
/datum/material/pizza/proc/make_edible(atom/source, mat_amount)
|
||||
if(source.material_flags & MATERIAL_NO_EDIBILITY)
|
||||
return
|
||||
var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT)
|
||||
var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT)
|
||||
source.AddComponentFrom(SOURCE_EDIBLE_PIZZA_MAT, \
|
||||
/datum/component/edible, \
|
||||
initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \
|
||||
foodtypes = GRAIN | DAIRY | VEGETABLES, \
|
||||
eat_time = 3 SECONDS, \
|
||||
tastes = list("crust", "tomato", "cheese"))
|
||||
tastes = /obj/item/food/pizza/margherita::tastes)
|
||||
|
||||
/datum/material/pizza/on_removed(atom/source, mat_amount, multiplier)
|
||||
. = ..()
|
||||
|
||||
@@ -334,33 +334,33 @@
|
||||
/**
|
||||
* Ensure a list of atoms/reagents exists inside this atom
|
||||
*
|
||||
* Goes throught he list of passed in parts, if they're reagents, adds them to our reagent holder
|
||||
* creating the reagent holder if it exists.
|
||||
*
|
||||
* If the part is a moveable atom and the previous location of the item was a mob/living,
|
||||
* it calls the inventory handler transferItemToLoc for that mob/living and transfers the part
|
||||
* to this atom
|
||||
*
|
||||
* Otherwise it simply forceMoves the atom into this atom
|
||||
* Cycles through the list of movables used up in the recipe and calls used_in_craft() for each of them
|
||||
* then it either moves them inside the object or deletes
|
||||
* them depending on whether they're in the list of parts for the recipe or not
|
||||
*/
|
||||
/atom/proc/CheckParts(list/parts_list, datum/crafting_recipe/current_recipe)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, current_recipe)
|
||||
if(!parts_list)
|
||||
return
|
||||
for(var/part in parts_list)
|
||||
if(istype(part, /datum/reagent))
|
||||
if(!reagents)
|
||||
reagents = new()
|
||||
reagents.reagent_list.Add(part)
|
||||
else if(ismovable(part))
|
||||
var/atom/movable/object = part
|
||||
if(isliving(object.loc))
|
||||
var/mob/living/living = object.loc
|
||||
living.transferItemToLoc(object, src)
|
||||
else
|
||||
object.forceMove(src)
|
||||
SEND_SIGNAL(object, COMSIG_ATOM_USED_IN_CRAFT, src)
|
||||
parts_list.Cut()
|
||||
/atom/proc/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_ON_CRAFT, components, current_recipe)
|
||||
var/list/remaining_parts = current_recipe?.parts?.Copy()
|
||||
var/list/parts_by_type = remaining_parts?.Copy()
|
||||
for(var/parttype in parts_by_type) //necessary for our is_type_in_list() call with the zebra arg set to true
|
||||
parts_by_type[parttype] = parttype
|
||||
for(var/obj/item/item in components) // machinery or structure objects in the list are guaranteed to be used up. We only check items.
|
||||
item.used_in_craft(src, current_recipe)
|
||||
var/matched_type = is_type_in_list(item, parts_by_type, zebra = TRUE)
|
||||
if(!matched_type)
|
||||
continue
|
||||
|
||||
if(isliving(item.loc))
|
||||
var/mob/living/living = item.loc
|
||||
living.transferItemToLoc(item, src)
|
||||
else
|
||||
item.forceMove(src)
|
||||
|
||||
if(matched_type)
|
||||
remaining_parts[matched_type] -= 1
|
||||
if(remaining_parts[matched_type] <= 0)
|
||||
remaining_parts -= matched_type
|
||||
|
||||
///Take air from the passed in gas mixture datum
|
||||
/atom/proc/assume_air(datum/gas_mixture/giver)
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
/// Sets the custom materials for an atom. This is what you want to call, since most of the ones below are mainly internal.
|
||||
/atom/proc/set_custom_materials(list/materials, multiplier = 1)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
if((custom_materials == materials) && multiplier == 1) //Easy way to know no changes are being made.
|
||||
return
|
||||
|
||||
var/replace_mats = length(materials)
|
||||
if(length(custom_materials))
|
||||
remove_material_effects(replace_mats)
|
||||
@@ -30,6 +33,7 @@
|
||||
for(var/current_material in materials)
|
||||
materials[current_material] *= multiplier
|
||||
|
||||
sortTim(materials, GLOBAL_PROC_REF(cmp_numeric_dsc), associative = TRUE)
|
||||
apply_material_effects(materials)
|
||||
|
||||
///proc responsible for applying material effects when setting materials.
|
||||
@@ -84,17 +88,13 @@
|
||||
var/total_alpha = 0
|
||||
var/list/colors = list()
|
||||
var/mat_length = length(materials)
|
||||
var/datum/material/main_material //the material with the highest amount (after calculations)
|
||||
var/main_mat_amount
|
||||
var/main_mat_mult
|
||||
var/datum/material/main_material = materials[1]//the material with the highest amount (after calculations)
|
||||
var/main_mat_amount = materials[main_material][MATERIAL_LIST_OPTIMAL_AMOUNT]
|
||||
var/main_mat_mult = materials[main_material][MATERIAL_LIST_MULTIPLIER]
|
||||
for(var/datum/material/custom_material as anything in materials)
|
||||
var/list/deets = materials[custom_material]
|
||||
var/mat_amount = deets[MATERIAL_LIST_OPTIMAL_AMOUNT]
|
||||
var/multiplier = deets[MATERIAL_LIST_MULTIPLIER]
|
||||
if(mat_amount > main_mat_amount)
|
||||
main_material = custom_material
|
||||
main_mat_amount = mat_amount
|
||||
main_mat_mult = multiplier
|
||||
|
||||
apply_single_mat_effect(custom_material, mat_amount, multiplier)
|
||||
custom_material.on_applied(src, mat_amount, multiplier)
|
||||
@@ -135,6 +135,8 @@
|
||||
var/prefixes = get_material_prefixes(materials)
|
||||
name = "[prefixes] [name]"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, materials, main_material)
|
||||
|
||||
/**
|
||||
* A proc used by both finalize_material_effects() and finalize_remove_material_effects() to get the colors
|
||||
* that will later be applied to or removed from the atom
|
||||
@@ -204,9 +206,14 @@
|
||||
return path
|
||||
|
||||
///Apply material effects of a single material.
|
||||
/atom/proc/apply_single_mat_effect(datum/material/custom_material, amount, multipier)
|
||||
/atom/proc/apply_single_mat_effect(datum/material/material, amount, multiplier)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
return
|
||||
if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !uses_integrity)
|
||||
return
|
||||
var/integrity_mod = GET_MATERIAL_MODIFIER(material.integrity_modifier, multiplier)
|
||||
modify_max_integrity(ceil(max_integrity * integrity_mod))
|
||||
var/list/armor_mods = material.get_armor_modifiers(multiplier)
|
||||
set_armor(get_armor().generate_new_with_multipliers(armor_mods))
|
||||
|
||||
///A proc for material effects that only the main material (which the atom's primarly composed of) should apply.
|
||||
/atom/proc/apply_main_material_effects(datum/material/main_material, amount, multipier)
|
||||
@@ -252,10 +259,17 @@
|
||||
if(material_flags & MATERIAL_ADD_PREFIX)
|
||||
name = initial(name)
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS, materials, main_material)
|
||||
|
||||
///Remove material effects of a single material.
|
||||
/atom/proc/remove_single_mat_effect(datum/material/custom_material, amount, multipier)
|
||||
/atom/proc/remove_single_mat_effect(datum/material/material, amount, multiplier)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
return
|
||||
if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !uses_integrity)
|
||||
return
|
||||
var/integrity_mod = GET_MATERIAL_MODIFIER(material.integrity_modifier, multiplier)
|
||||
modify_max_integrity(floor(max_integrity / integrity_mod))
|
||||
var/list/armor_mods = material.get_armor_modifiers(1 / multiplier)
|
||||
set_armor(get_armor().generate_new_with_multipliers(armor_mods))
|
||||
|
||||
///A proc to remove the material effects previously applied by the (ex-)main material
|
||||
/atom/proc/remove_main_material_effects(datum/material/main_material, amount, multipier)
|
||||
|
||||
@@ -1778,6 +1778,11 @@
|
||||
/atom/movable/proc/keybind_face_direction(direction)
|
||||
setDir(direction)
|
||||
|
||||
///This handles special behavior that happens when the movable is used in crafting (slapcrafting and UI, not sheets or lathes or processing with a tool)
|
||||
/atom/movable/proc/used_in_craft(atom/result, datum/crafting_recipe/current_recipe)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_USED_IN_CRAFT, result)
|
||||
|
||||
/**
|
||||
* Check if the other atom/movable has any factions the same as us. Defined at the atom/movable level so it can be defined for just about anything.
|
||||
*
|
||||
|
||||
@@ -836,8 +836,8 @@
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/CheckParts(list/parts_list)
|
||||
..()
|
||||
/obj/machinery/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/proc/RefreshParts()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
AddComponent(/datum/component/plumbing/simple_demand)
|
||||
AddComponent(/datum/component/simple_rotation)
|
||||
register_context()
|
||||
CheckParts()
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/medipen_refiller/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -30,6 +30,16 @@ Buildable meters
|
||||
///Initial direction of the created pipe (either made from the RPD or after unwrenching the pipe)
|
||||
var/p_init_dir = SOUTH
|
||||
|
||||
/obj/item/pipe/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
if(!istype(current_recipe, /datum/crafting_recipe/spec_pipe))
|
||||
return
|
||||
var/datum/crafting_recipe/spec_pipe/pipe_recipe = current_recipe
|
||||
pipe_type = pipe_recipe.pipe_type
|
||||
pipe_color = ATMOS_COLOR_OMNI
|
||||
setDir(crafter.dir)
|
||||
update()
|
||||
|
||||
/obj/item/pipe/directional
|
||||
RPD_type = PIPE_UNARY
|
||||
/obj/item/pipe/directional/he_junction
|
||||
|
||||
@@ -338,6 +338,18 @@
|
||||
. = ..()
|
||||
QDEL_NULL(beaker)
|
||||
|
||||
/obj/machinery/space_heater/improvised_chem_heater/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
if(!isliving(crafter))
|
||||
return
|
||||
var/mob/living/user = crafter
|
||||
var/obj/item/stock_parts/power_store/cell/cell = (locate() in range(1)) || user.is_holding_item_of_type(/obj/item/stock_parts/power_store/cell)
|
||||
if(!cell)
|
||||
return
|
||||
var/turf/turf = get_turf(cell)
|
||||
forceMove(turf)
|
||||
attackby(cell, user) //puts it into the heater
|
||||
|
||||
/obj/machinery/space_heater/improvised_chem_heater/heating_examine()
|
||||
. = ..()
|
||||
// Conducted energy per joule of thermal energy difference in a tick.
|
||||
|
||||
@@ -551,45 +551,42 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/bombcore/chemical/CheckParts(list/parts_list)
|
||||
..()
|
||||
/obj/item/bombcore/chemical/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
// Using different grenade casings, causes the payload to have different properties.
|
||||
var/obj/item/stock_parts/matter_bin/MB = locate(/obj/item/stock_parts/matter_bin) in src
|
||||
if(MB)
|
||||
max_beakers += MB.rating // max beakers = 2-5.
|
||||
qdel(MB)
|
||||
for(var/obj/item/grenade/chem_grenade/G in src)
|
||||
var/obj/item/stock_parts/matter_bin/bin = locate(/obj/item/stock_parts/matter_bin) in components
|
||||
if(bin)
|
||||
max_beakers += bin.rating // max beakers = 2-5.
|
||||
for(var/obj/item/grenade/chem_grenade/nade in components)
|
||||
|
||||
if(istype(G, /obj/item/grenade/chem_grenade/large))
|
||||
var/obj/item/grenade/chem_grenade/large/LG = G
|
||||
if(istype(nade, /obj/item/grenade/chem_grenade/large))
|
||||
max_beakers += 1 // Adding two large grenades only allows for a maximum of 7 beakers.
|
||||
spread_range += 2 // Extra range, reduced density.
|
||||
temp_boost += 50 // maximum of +150K blast using only large beakers. Not enough to self ignite.
|
||||
for(var/obj/item/slime_extract/S in LG.beakers) // And slime cores.
|
||||
for(var/obj/item/slime_extract/slime in nade.beakers) // And slime cores.
|
||||
if(beakers.len < max_beakers)
|
||||
beakers += S
|
||||
S.forceMove(src)
|
||||
beakers += slime
|
||||
slime.forceMove(src)
|
||||
else
|
||||
S.forceMove(drop_location())
|
||||
slime.forceMove(drop_location())
|
||||
|
||||
if(istype(G, /obj/item/grenade/chem_grenade/cryo))
|
||||
if(istype(nade, /obj/item/grenade/chem_grenade/cryo))
|
||||
spread_range -= 1 // Reduced range, but increased density.
|
||||
temp_boost -= 100 // minimum of -150K blast.
|
||||
|
||||
if(istype(G, /obj/item/grenade/chem_grenade/pyro))
|
||||
if(istype(nade, /obj/item/grenade/chem_grenade/pyro))
|
||||
temp_boost += 150 // maximum of +350K blast, which is enough to self ignite. Which means a self igniting bomb can't take advantage of other grenade casing properties. Sorry?
|
||||
|
||||
if(istype(G, /obj/item/grenade/chem_grenade/adv_release))
|
||||
time_release += 50 // A typical bomb, using basic beakers, will explode over 2-4 seconds. Using two will make the reaction last for less time, but it will be more dangerous overall.
|
||||
if(istype(nade, /obj/item/grenade/chem_grenade/adv_release))
|
||||
time_release += 5 SECONDS // A typical bomb, using basic beakers, will explode over 2-4 seconds. Using two will make the reaction last for less time, but it will be more dangerous overall.
|
||||
|
||||
for(var/obj/item/reagent_containers/cup/B in G)
|
||||
for(var/obj/item/reagent_containers/cup/beaker in nade)
|
||||
if(beakers.len < max_beakers)
|
||||
beakers += B
|
||||
B.forceMove(src)
|
||||
beakers += beaker
|
||||
beaker.forceMove(src)
|
||||
else
|
||||
B.forceMove(drop_location())
|
||||
beaker.forceMove(drop_location())
|
||||
|
||||
qdel(G)
|
||||
return ..()
|
||||
|
||||
/obj/item/bombcore/emp
|
||||
name = "EMP payload"
|
||||
@@ -618,22 +615,20 @@
|
||||
chosen_theme = null
|
||||
return ..()
|
||||
|
||||
/obj/item/bombcore/dimensional/CheckParts(list/parts_list)
|
||||
/obj/item/bombcore/dimensional/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
range_heavy = 13
|
||||
for(var/obj/item/grenade/chem_grenade/nade in src)
|
||||
for(var/obj/item/grenade/chem_grenade/nade in components)
|
||||
if(istype(nade, /obj/item/grenade/chem_grenade/large) || istype(nade, /obj/item/grenade/chem_grenade/adv_release))
|
||||
range_heavy += 1
|
||||
for(var/obj/item/thing as anything in nade.beakers) //remove beakers, then delete the grenade.
|
||||
thing.forceMove(drop_location())
|
||||
qdel(nade)
|
||||
var/obj/item/gibtonite/ore = locate() in src
|
||||
var/obj/item/gibtonite/ore = locate() in components
|
||||
switch(ore.quality)
|
||||
if(GIBTONITE_QUALITY_LOW)
|
||||
range_heavy -= 2
|
||||
if(GIBTONITE_QUALITY_HIGH)
|
||||
range_heavy += 4
|
||||
qdel(ore)
|
||||
|
||||
/obj/item/bombcore/dimensional/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/obj/effect/decal/cleanable/food
|
||||
icon = 'icons/effects/tomatodecal.dmi'
|
||||
gender = NEUTER
|
||||
|
||||
@@ -950,7 +950,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
|
||||
/obj/item/rollingpaper/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/cigarette/rollie, CUSTOM_INGREDIENT_ICON_NOCHANGE, ingredient_type=CUSTOM_INGREDIENT_TYPE_DRYABLE, max_ingredients=2)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/cigarette/rollie, CUSTOM_INGREDIENT_ICON_NOCHANGE, ingredient_type=CUSTOM_INGREDIENT_TYPE_DRYABLE, max_ingredients=2)
|
||||
|
||||
|
||||
///////////////
|
||||
|
||||
@@ -109,8 +109,8 @@
|
||||
if(!safety && emagged_state)
|
||||
. += emagged_state
|
||||
|
||||
/obj/item/defibrillator/CheckParts(list/parts_list)
|
||||
..()
|
||||
/obj/item/defibrillator/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
cell = locate(/obj/item/stock_parts/power_store) in contents
|
||||
update_power()
|
||||
|
||||
|
||||
@@ -160,3 +160,13 @@
|
||||
AI.updatehealth()
|
||||
sleep(0.5 SECONDS)
|
||||
flush = FALSE
|
||||
|
||||
/obj/item/aicard/used_in_craft(atom/result, datum/crafting_recipe/current_recipe)
|
||||
. = ..()
|
||||
if(!AI || !istype(result, /obj/item/aicard))
|
||||
return
|
||||
var/obj/item/aicard/new_card = result
|
||||
AI.forceMove(new_card)
|
||||
new_card.AI = AI
|
||||
new_card.update_appearance()
|
||||
AI = null
|
||||
|
||||
@@ -554,7 +554,7 @@
|
||||
randomize_fuel = FALSE
|
||||
trash_type = /obj/item/trash/candle
|
||||
can_be_extinguished = TRUE
|
||||
var/scented_type //SKYRAT EDIT ADDITION /// Pollutant type for scented candles
|
||||
custom_materials = null //candles are made of wax (which doesn't exists as a material type as of 2025) and not plastic
|
||||
/// The current wax level, used for drawing the correct icon
|
||||
var/current_wax_level = 1
|
||||
/// The previous wax level, remembered so we only have to make 3 update_appearance calls total as opposed to every tick
|
||||
|
||||
@@ -193,8 +193,8 @@
|
||||
set_light_on(lit)
|
||||
update_appearance()
|
||||
|
||||
/obj/item/flamethrower/CheckParts(list/parts_list)
|
||||
..()
|
||||
/obj/item/flamethrower/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. =..()
|
||||
weldtool = locate(/obj/item/weldingtool) in contents
|
||||
igniter = locate(/obj/item/assembly/igniter) in contents
|
||||
weldtool.status = FALSE
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
righthand_file = 'icons/mob/inhands/items/food_righthand.dmi'
|
||||
obj_flags = UNIQUE_RENAME
|
||||
grind_results = list()
|
||||
material_flags = MATERIAL_NO_EDIBILITY
|
||||
/**
|
||||
* A list of material paths. the main material in the custom_materials list is also added on init.
|
||||
*
|
||||
* If the food has materials and as long as the main one is in this list, effects and properties of materials are disabled
|
||||
* Food is coded mainly around reagents than materials, and the two may cause some issues if overlapped. For example, this
|
||||
* stops food *normally* containing meat from having redundant prefixes, an unfitting appearance and too much meatiness overall.
|
||||
* However, the same material effects will apply on a fruit or a vegetable.
|
||||
*/
|
||||
var/list/intrisic_food_materials
|
||||
///List of reagents this food gets on creation during reaction or map spawn
|
||||
var/list/food_reagents
|
||||
///Extra flags for things such as if the food is in a container or not
|
||||
@@ -54,7 +64,20 @@
|
||||
/obj/item/food/Initialize(mapload)
|
||||
if(food_reagents)
|
||||
food_reagents = string_assoc_list(food_reagents)
|
||||
|
||||
///This has to be done before set_custom_materials is called at atom level
|
||||
if(custom_materials)
|
||||
var/main_mat_type = null
|
||||
var/mat_amount = 0
|
||||
for(var/mat_type in custom_materials)
|
||||
if(custom_materials[mat_type] > mat_amount)
|
||||
main_mat_type = mat_type
|
||||
LAZYADD(intrisic_food_materials, main_mat_type)
|
||||
if(intrisic_food_materials)
|
||||
intrisic_food_materials = typecacheof(intrisic_food_materials)
|
||||
|
||||
. = ..()
|
||||
|
||||
if(tastes)
|
||||
tastes = string_assoc_list(tastes)
|
||||
if(eatverbs)
|
||||
@@ -70,6 +93,20 @@
|
||||
make_microwaveable()
|
||||
ADD_TRAIT(src, TRAIT_FISHING_BAIT, INNATE_TRAIT)
|
||||
|
||||
/obj/item/food/apply_material_effects(list/materials)
|
||||
if(!HAS_TRAIT(src, TRAIT_INGREDIENTS_HOLDER)) //ingredients holder handle prefixes and colors differently
|
||||
var/datum/material/main_material = materials[1] //The list is sorted by amount so the first of the list is the main mat
|
||||
if(!is_type_in_typecache(main_material, intrisic_food_materials))
|
||||
material_flags |= MATERIAL_EFFECTS|MATERIAL_AFFECT_STATISTICS|MATERIAL_ADD_PREFIX|MATERIAL_COLOR
|
||||
else
|
||||
//food items with the ingredients holders component are still affected by the materials stats and effects wise.
|
||||
material_flags |= MATERIAL_EFFECTS|MATERIAL_AFFECT_STATISTICS
|
||||
return ..()
|
||||
|
||||
/obj/item/food/remove_material_effects(replace_mats = TRUE)
|
||||
. = ..()
|
||||
material_flags &= ~(MATERIAL_EFFECTS|MATERIAL_AFFECT_STATISTICS|MATERIAL_ADD_PREFIX|MATERIAL_COLOR)
|
||||
|
||||
///This proc adds the edible component, overwrite this if you for some reason want to change some specific args like callbacks.
|
||||
/obj/item/food/proc/make_edible()
|
||||
AddComponentFrom(
|
||||
@@ -87,6 +124,12 @@
|
||||
reagent_purity = starting_reagent_purity,\
|
||||
)
|
||||
|
||||
/obj/item/food/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
var/mob/living/user = crafter
|
||||
if(istype(user) && !isnull(user.mind))
|
||||
ADD_TRAIT(src, TRAIT_FOOD_CHEF_MADE, REF(user.mind))
|
||||
|
||||
///This proc handles processable elements, overwrite this if you want to add behavior such as slicing, forking, spooning, whatever, to turn the item into something else
|
||||
/obj/item/food/proc/make_processable()
|
||||
return
|
||||
@@ -123,14 +166,14 @@
|
||||
if(!preserved_food)
|
||||
AddComponent(/datum/component/decomposition, mapload, decomp_req_handle, decomp_flags = foodtypes, decomp_result = decomp_type, ant_attracting = ant_attracting, custom_time = decomposition_time, stink_particles = decomposition_particles)
|
||||
|
||||
/obj/item/food/CheckParts(list/parts, datum/crafting_recipe/food/current_recipe)
|
||||
/obj/item/food/on_craft_completion(list/components, datum/crafting_recipe/food/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
if(!istype(current_recipe))
|
||||
return
|
||||
|
||||
var/made_with_food = FALSE
|
||||
var/final_foodtypes = current_recipe.added_foodtypes
|
||||
for(var/obj/item/food/ingredient in parts)
|
||||
for(var/obj/item/food/ingredient in components)
|
||||
made_with_food = TRUE
|
||||
final_foodtypes |= ingredient.foodtypes
|
||||
if(!made_with_food)
|
||||
|
||||
@@ -50,10 +50,9 @@
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
slice_type = /obj/item/food/breadslice/plain
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
|
||||
/obj/item/food/bread/plain/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/bread/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/bread/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
|
||||
/obj/item/food/breadslice/plain
|
||||
name = "bread slice"
|
||||
@@ -67,7 +66,7 @@
|
||||
|
||||
/obj/item/food/breadslice/plain/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
|
||||
/obj/item/food/breadslice/plain/make_grillable()
|
||||
AddComponent(/datum/component/grillable, /obj/item/food/griddle_toast, rand(15 SECONDS, 25 SECONDS), TRUE, TRUE)
|
||||
@@ -103,6 +102,7 @@
|
||||
/datum/reagent/consumable/nutriment/vitamin = 10,
|
||||
/datum/reagent/consumable/nutriment/protein = 12,
|
||||
)
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
tastes = list("bread" = 10, "meat" = 10)
|
||||
foodtypes = GRAIN | MEAT | DAIRY
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
@@ -135,6 +135,7 @@
|
||||
foodtypes = GRAIN | MEAT
|
||||
slice_type = /obj/item/food/breadslice/sausage
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/breadslice/sausage
|
||||
name = "sausagebread slice"
|
||||
@@ -153,6 +154,7 @@
|
||||
name = "xenomeatbread loaf"
|
||||
desc = "The culinary base of every self-respecting eloquen/tg/entleman. Extra Heretical."
|
||||
icon_state = "xenomeatbread"
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
food_reagents = list(
|
||||
/datum/reagent/consumable/nutriment = 20,
|
||||
/datum/reagent/consumable/nutriment/vitamin = 10,
|
||||
@@ -180,6 +182,7 @@
|
||||
name = "spider meat loaf"
|
||||
desc = "Reassuringly green meatloaf made from spider meat."
|
||||
icon_state = "spidermeatbread"
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
food_reagents = list(
|
||||
/datum/reagent/consumable/nutriment = 20,
|
||||
/datum/reagent/toxin = 15,
|
||||
@@ -327,7 +330,7 @@
|
||||
|
||||
/obj/item/food/breadslice/empty/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
|
||||
/obj/item/food/baguette
|
||||
name = "baguette"
|
||||
|
||||
@@ -26,18 +26,20 @@
|
||||
custom_price = PAYCHECK_CREW * 0.8
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/plain/Initialize(mapload)
|
||||
. = ..()
|
||||
if(prob(1))
|
||||
new/obj/effect/particle_effect/fluid/smoke(get_turf(src))
|
||||
playsound(src, 'sound/effects/smoke.ogg', 50, TRUE)
|
||||
visible_message(span_warning("Oh, ye gods! [src] is ruined! But what if...?"))
|
||||
name = "steamed ham"
|
||||
desc = pick("Ahh, Head of Personnel, welcome. I hope you're prepared for an unforgettable luncheon!",
|
||||
"And you call these steamed hams despite the fact that they are obviously microwaved?",
|
||||
"Aurora Station 13? At this time of shift, in this time of year, in this sector of space, localized entirely within your freezer?",
|
||||
"You know, these hamburgers taste quite similar to the ones they have at the Maltese Falcon.")
|
||||
if(!prob(1))
|
||||
return
|
||||
new/obj/effect/particle_effect/fluid/smoke(get_turf(src))
|
||||
playsound(src, 'sound/effects/smoke.ogg', 50, TRUE)
|
||||
visible_message(span_warning("Oh, ye gods! [src] is ruined! But what if...?"))
|
||||
name = "steamed ham"
|
||||
desc = pick("Ahh, Head of Personnel, welcome. I hope you're prepared for an unforgettable luncheon!",
|
||||
"And you call these steamed hams despite the fact that they are obviously microwaved?",
|
||||
"Aurora Station 13? At this time of shift, in this time of year, in this sector of space, localized entirely within your freezer?",
|
||||
"You know, these hamburgers taste quite similar to the ones they have at the Maltese Falcon.")
|
||||
|
||||
/obj/item/food/burger/human
|
||||
name = "human burger"
|
||||
@@ -51,11 +53,11 @@
|
||||
foodtypes = MEAT | GRAIN
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/human/CheckParts(list/parts_list)
|
||||
..()
|
||||
var/obj/item/food/patty/human/human_patty = locate(/obj/item/food/patty/human) in contents
|
||||
for(var/datum/material/meat/mob_meat/mob_meat_material in human_patty.custom_materials)
|
||||
/obj/item/food/burger/human/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
for(var/datum/material/meat/mob_meat/mob_meat_material in custom_materials)
|
||||
if(mob_meat_material.subjectname)
|
||||
name = "[mob_meat_material.subjectname] burger"
|
||||
else if(mob_meat_material.subjectjob)
|
||||
@@ -73,6 +75,7 @@
|
||||
foodtypes = GRAIN | MEAT
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/appendix
|
||||
name = "appendix burger"
|
||||
@@ -151,6 +154,7 @@
|
||||
foodtypes = GRAIN | MEAT
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/bearger
|
||||
name = "bearger"
|
||||
@@ -165,6 +169,7 @@
|
||||
foodtypes = GRAIN | MEAT
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/clown
|
||||
name = "clown burger"
|
||||
@@ -279,6 +284,7 @@
|
||||
tastes = list("bun" = 2, "red" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/orange
|
||||
name = "orange burger"
|
||||
@@ -294,6 +300,7 @@
|
||||
tastes = list("bun" = 2, "orange" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/yellow
|
||||
name = "yellow burger"
|
||||
@@ -309,6 +316,7 @@
|
||||
tastes = list("bun" = 2, "yellow" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/green
|
||||
name = "green burger"
|
||||
@@ -324,6 +332,7 @@
|
||||
tastes = list("bun" = 2, "green" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/blue
|
||||
name = "blue burger"
|
||||
@@ -339,6 +348,7 @@
|
||||
tastes = list("bun" = 2, "blue" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/purple
|
||||
name = "purple burger"
|
||||
@@ -354,6 +364,7 @@
|
||||
tastes = list("bun" = 2, "purple" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/black
|
||||
name = "black burger"
|
||||
@@ -369,6 +380,7 @@
|
||||
tastes = list("bun" = 2, "black" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/white
|
||||
name = "white burger"
|
||||
@@ -384,6 +396,7 @@
|
||||
tastes = list("bun" = 2, "white" = 2)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/spell
|
||||
name = "spell burger"
|
||||
@@ -413,6 +426,7 @@
|
||||
foodtypes = GRAIN | MEAT | DAIRY
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/jelly
|
||||
name = "jelly burger"
|
||||
@@ -455,6 +469,7 @@
|
||||
foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/superbite/suicide_act(mob/living/user)
|
||||
user.visible_message(span_suicide("[user] starts to eat [src] in one bite, it looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
@@ -477,6 +492,7 @@
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/rat
|
||||
name = "rat burger"
|
||||
@@ -506,6 +522,7 @@
|
||||
custom_price = PAYCHECK_CREW * 0.8
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = /obj/item/melee/baseball_bat::custom_materials
|
||||
|
||||
/obj/item/food/burger/baconburger
|
||||
name = "bacon burger"
|
||||
@@ -521,6 +538,7 @@
|
||||
custom_premium_price = PAYCHECK_CREW * 1.6
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/empoweredburger
|
||||
name = "empowered burger"
|
||||
@@ -549,6 +567,7 @@
|
||||
tastes = list("bun" = 4, "meat" = 2, "cat" = 2)
|
||||
foodtypes = GRAIN | MEAT | GORE
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/crab
|
||||
name = "crab burger"
|
||||
@@ -563,6 +582,7 @@
|
||||
foodtypes = GRAIN | SEAFOOD
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/soylent
|
||||
name = "soylent burger"
|
||||
@@ -577,6 +597,7 @@
|
||||
foodtypes = GRAIN | MEAT | DAIRY
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/rib
|
||||
name = "mcrib"
|
||||
@@ -592,6 +613,7 @@
|
||||
foodtypes = GRAIN | MEAT | SUGAR | VEGETABLES
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/mcguffin
|
||||
name = "mcguffin"
|
||||
@@ -607,6 +629,7 @@
|
||||
foodtypes = GRAIN | MEAT | BREAKFAST | FRIED
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/chicken
|
||||
name = "chicken sandwich"
|
||||
@@ -625,6 +648,7 @@
|
||||
foodtypes = GRAIN | MEAT
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/cheese
|
||||
name = "cheese burger"
|
||||
@@ -639,6 +663,7 @@
|
||||
foodtypes = GRAIN | MEAT | DAIRY
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/cheese/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -659,6 +684,7 @@
|
||||
tastes = list("bun" = 2, "beef patty" = 4, "cheese" = 2, "beef soaked in chili" = 3, "a smoking flare" = 2)
|
||||
foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2, /datum/material/plastic= SMALL_MATERIAL_AMOUNT * 0.5)
|
||||
|
||||
/obj/item/food/burger/crazy/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -691,3 +717,4 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
/obj/item/food/cake/plain/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/cake/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 16)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/cake/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 16)
|
||||
|
||||
/obj/item/food/cakeslice/plain
|
||||
name = "plain cake slice"
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
/obj/item/food/cakeslice/empty/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 16)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 16)
|
||||
|
||||
/obj/item/food/cake/carrot
|
||||
name = "carrot cake"
|
||||
@@ -485,6 +485,7 @@
|
||||
foodtypes = GRAIN|DAIRY|SUGAR|GROSS
|
||||
slice_type = /obj/item/food/cakeslice/hardware_cake_slice
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/glass = SHEET_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/cakeslice/hardware_cake_slice
|
||||
name = "hardware cake slice"
|
||||
|
||||
@@ -51,10 +51,12 @@
|
||||
foodtypes = MEAT|GRAIN
|
||||
tastes = list("meat" = 2, "dough" = 2, "comfiness" = 1)
|
||||
warm_type = /obj/item/food/donkpocket/warm/homemade
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/warm/homemade
|
||||
foodtypes = MEAT|GRAIN
|
||||
tastes = list("meat" = 2, "dough" = 2, "comfiness" = 1)
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/dank
|
||||
name = "\improper Dank-pocket"
|
||||
@@ -126,10 +128,12 @@
|
||||
tastes = list("meat" = 2, "dough" = 2, "spice" = 1)
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN
|
||||
warm_type = /obj/item/food/donkpocket/warm/spicy/homemade
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/warm/spicy/homemade
|
||||
tastes = list("meat" = 2, "dough" = 2, "weird spices" = 1)
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/teriyaki
|
||||
name = "\improper Teriyaki-pocket"
|
||||
@@ -167,10 +171,12 @@
|
||||
tastes = list("meat" = 2, "dough" = 2, "soy sauce" = 2)
|
||||
foodtypes = MEAT|GRAIN
|
||||
warm_type = /obj/item/food/donkpocket/warm/teriyaki/homemade
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/warm/teriyaki/homemade
|
||||
tastes = list("meat" = 2, "dough" = 2, "soy sauce" = 2)
|
||||
foodtypes = MEAT|GRAIN
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/pizza
|
||||
name = "\improper Pizza-pocket"
|
||||
@@ -220,6 +226,7 @@
|
||||
/datum/reagent/medicine/omnizine = 2,
|
||||
/datum/reagent/consumable/laughter = 6,
|
||||
)
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/donkpocket/honk/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, honk_added_reagents)
|
||||
@@ -240,6 +247,7 @@
|
||||
tastes = list("banana" = 2, "dough" = 2, "children's antibiotics" = 1)
|
||||
foodtypes = GRAIN|FRUIT|SUGAR
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/donkpocket/berry
|
||||
name = "\improper Berry-pocket"
|
||||
@@ -252,6 +260,7 @@
|
||||
tastes = list("dough" = 2, "jam" = 2)
|
||||
foodtypes = GRAIN|FRUIT|SUGAR
|
||||
warm_type = /obj/item/food/donkpocket/warm/berry
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/donkpocket/berry/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, child_added_reagents)
|
||||
@@ -270,6 +279,7 @@
|
||||
)
|
||||
tastes = list("dough" = 2, "warm jam" = 2)
|
||||
foodtypes = GRAIN|FRUIT|SUGAR
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/donkpocket/gondola
|
||||
name = "\improper Gondola-pocket"
|
||||
@@ -284,6 +294,7 @@
|
||||
foodtypes = GRAIN|MEAT
|
||||
|
||||
warm_type = /obj/item/food/donkpocket/warm/gondola
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
var/static/list/gondola_added_reagents = list(
|
||||
/datum/reagent/medicine/omnizine = 2,
|
||||
/datum/reagent/gondola_mutation_toxin = 5,
|
||||
@@ -307,6 +318,7 @@
|
||||
)
|
||||
tastes = list("meat" = 2, "dough" = 2, "inner peace" = 1)
|
||||
foodtypes = GRAIN|MEAT
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donkpocket/deluxe
|
||||
name = "\improper Donk-pocket Deluxe"
|
||||
@@ -326,6 +338,7 @@
|
||||
var/static/list/deluxe_added_reagents = list(
|
||||
/datum/reagent/medicine/omnizine = 8,
|
||||
)
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/donkpocket/deluxe/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, deluxe_added_reagents)
|
||||
@@ -345,6 +358,7 @@
|
||||
)
|
||||
tastes = list("quality meat" = 2, "dough" = 2, "fanciness" = 1)
|
||||
foodtypes = GRAIN|MEAT|VEGETABLES|FRIED
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/donkpocket/deluxe/nocarb
|
||||
name = "\improper Meat-pocket"
|
||||
@@ -359,6 +373,7 @@
|
||||
foodtypes = MEAT|RAW
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
warm_type = /obj/item/food/donkpocket/warm/deluxe/nocarb
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/donkpocket/deluxe/meat/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, deluxe_added_reagents)
|
||||
@@ -377,6 +392,7 @@
|
||||
)
|
||||
tastes = list("meat" = 2, "more meat" = 2, "no carbs" = 1)
|
||||
foodtypes = MEAT
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/donkpocket/deluxe/vegan
|
||||
name = "\improper Donk-roll"
|
||||
@@ -391,6 +407,7 @@
|
||||
foodtypes = GRAIN | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
warm_type = /obj/item/food/donkpocket/warm/deluxe/vegan
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/donkpocket/deluxe/vegan/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, deluxe_added_reagents)
|
||||
@@ -409,3 +426,4 @@
|
||||
)
|
||||
tastes = list("rice patty" = 2, "fried dough" = 2, "peppery kick" = 1)
|
||||
foodtypes = GRAIN | VEGETABLES | FRIED
|
||||
custom_materials = null
|
||||
|
||||
@@ -24,6 +24,14 @@
|
||||
if(prob(DONUT_SPRINKLE_CHANCE))
|
||||
decorate_donut()
|
||||
|
||||
// It is so stupid that we have to do this but because food crafting clears all reagents that got added during init,
|
||||
// here we are adding it again (but only for crafting, maploaded and spawned donuts work fine).
|
||||
// Until the issues with crafted items' reagents are resolved this will have to do
|
||||
/obj/item/food/donut/plain/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
if(is_decorated)
|
||||
reagents.add_reagent(/datum/reagent/consumable/sprinkles, 1)
|
||||
|
||||
///Override for checkliked callback
|
||||
/obj/item/food/donut/make_edible()
|
||||
. = ..()
|
||||
@@ -92,6 +100,7 @@
|
||||
foodtypes = GRAIN|DAIRY|JUNKFOOD|FRIED|BREAKFAST|MEAT|GORE
|
||||
is_decorated = TRUE
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/donut/berry
|
||||
name = "pink donut"
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
/obj/item/food/pizzabread/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/pizza, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 12)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/pizza, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 12)
|
||||
|
||||
/obj/item/food/doughslice
|
||||
name = "dough slice"
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
/obj/item/food/bun/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/burger/empty, CUSTOM_INGREDIENT_ICON_STACKPLUSTOP)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/burger/empty, CUSTOM_INGREDIENT_ICON_STACKPLUSTOP)
|
||||
|
||||
/obj/item/food/cakebatter
|
||||
name = "cake batter"
|
||||
|
||||
@@ -255,6 +255,7 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0)
|
||||
tastes = list("egg" = 4, "meat" = 4)
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/boiledegg/rotten
|
||||
food_reagents = list(/datum/reagent/consumable/eggrot = 10)
|
||||
@@ -315,6 +316,7 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0)
|
||||
foodtypes = MEAT|BREAKFAST|GRAIN|FRIED
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/eggwrap
|
||||
name = "egg wrap"
|
||||
|
||||
@@ -454,3 +454,4 @@
|
||||
overlay_state = "meatsicle"
|
||||
foodtypes = RAW | MEAT | SUGAR
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
foodtypes = MEAT|RAW
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/raw_tiziran_sausage/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -35,6 +36,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_price = PAYCHECK_CREW
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/raw_headcheese
|
||||
name = "raw headcheese block"
|
||||
@@ -49,6 +51,7 @@
|
||||
foodtypes = MEAT|RAW|GORE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/raw_headcheese/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -67,6 +70,7 @@
|
||||
foodtypes = MEAT | GORE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/headcheese/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/headcheese_slice, 5, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
|
||||
@@ -122,6 +126,7 @@
|
||||
foodtypes = MEAT|VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/moonfish_eggs
|
||||
name = "moonfish eggs"
|
||||
@@ -212,6 +217,7 @@
|
||||
foodtypes = MEAT|NUTS|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
//Why does like, every language on the planet besides English call them pommes? Who knows, who cares- the lizards call them it too, because funny.
|
||||
/obj/item/food/lizard_fries
|
||||
@@ -230,6 +236,7 @@
|
||||
foodtypes = MEAT | VEGETABLES | FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/brain_pate
|
||||
name = "eyeball-and-brain pate"
|
||||
@@ -349,6 +356,7 @@
|
||||
foodtypes = MEAT | SEAFOOD | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 3)
|
||||
|
||||
//Spaghetti Dishes
|
||||
|
||||
@@ -541,7 +549,7 @@
|
||||
|
||||
/obj/item/food/bread/root/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/bread/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/bread/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
|
||||
/obj/item/food/bread/root/egg
|
||||
foodtypes = parent_type::foodtypes | MEAT
|
||||
@@ -559,7 +567,7 @@
|
||||
|
||||
/obj/item/food/breadslice/root/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
|
||||
/obj/item/food/breadslice/root/egg
|
||||
foodtypes = parent_type::foodtypes | MEAT
|
||||
@@ -597,6 +605,7 @@
|
||||
foodtypes = VEGETABLES | NUTS | MEAT
|
||||
boxtag = "Italic Flatbread"
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/pizza/flatbread/imperial
|
||||
name = "\improper Imperial flatbread"
|
||||
@@ -611,6 +620,7 @@
|
||||
foodtypes = VEGETABLES | MEAT | NUTS | GORE
|
||||
boxtag = "Imperial Victory Flatbread"
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/pizza/flatbread/rawmeat
|
||||
name = "meatlovers flatbread"
|
||||
@@ -623,6 +633,7 @@
|
||||
tastes = list("bread" = 1, "meat" = 1)
|
||||
foodtypes = MEAT|VEGETABLES|RAW|NUTS
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pizza/flatbread/stinging
|
||||
name = "\improper Stinging flatbread"
|
||||
@@ -700,6 +711,7 @@
|
||||
food_flags = FOOD_FINGER_FOOD
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/honey_roll
|
||||
name = "honey sweetroll"
|
||||
@@ -926,6 +938,7 @@
|
||||
)
|
||||
foodtypes = MEAT|VEGETABLES|NUTS
|
||||
crafting_complexity = FOOD_COMPLEXITY_3 //Gotta make the dough, +1
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/rat/korta
|
||||
name = "rat rootburger"
|
||||
@@ -956,6 +969,7 @@
|
||||
foodtypes = NUTS | MEAT | BREAKFAST | VEGETABLES | FRIED
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/rootrib
|
||||
name = "rootrib"
|
||||
@@ -972,6 +986,7 @@
|
||||
foodtypes = NUTS | MEAT | VEGETABLES | SUGAR
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/burger/rootchicken
|
||||
name = "chicken rootwich"
|
||||
@@ -989,6 +1004,7 @@
|
||||
foodtypes = NUTS | MEAT | VEGETABLES
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/rootfish
|
||||
name = "Fish rootwich"
|
||||
@@ -1019,3 +1035,4 @@
|
||||
foodtypes = NUTS | MEAT | VEGETABLES
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
foodtypes = MEAT|FRIED|GRAIN
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/rice_dough
|
||||
name = "rice dough"
|
||||
@@ -213,6 +214,7 @@
|
||||
foodtypes = MEAT | GRAIN | PINEAPPLE | FRUIT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/ikareis
|
||||
name = "ikareis"
|
||||
@@ -229,6 +231,7 @@
|
||||
foodtypes = MEAT | GRAIN | SEAFOOD | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/hawaiian_fried_rice
|
||||
name = "\improper Hawaiian fried rice"
|
||||
@@ -260,6 +263,7 @@
|
||||
foodtypes = MEAT | GRAIN | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/mediterranean_fried_rice
|
||||
name = "mediterranean fried rice"
|
||||
@@ -275,6 +279,7 @@
|
||||
foodtypes = MEAT | GRAIN | VEGETABLES | DAIRY | FRUIT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/egg_fried_rice
|
||||
name = "egg fried rice"
|
||||
@@ -292,7 +297,7 @@
|
||||
|
||||
/obj/item/food/salad/egg_fried_rice/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
|
||||
/obj/item/food/salad/bibimbap
|
||||
name = "bibimbap"
|
||||
@@ -309,10 +314,11 @@
|
||||
foodtypes = MEAT | VEGETABLES | GRAIN
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/bibimbap/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
|
||||
// Noodles
|
||||
/obj/item/food/salad/bulgogi_noodles
|
||||
@@ -329,6 +335,7 @@
|
||||
foodtypes = MEAT | GRAIN | VEGETABLES | FRUIT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/yakisoba_katsu
|
||||
name = "yakisoba katsu"
|
||||
@@ -344,6 +351,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/martian_fried_noodles
|
||||
name = "\improper Martian fried noodles"
|
||||
@@ -359,6 +367,7 @@
|
||||
foodtypes = GRAIN | NUTS | MEAT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/simple_fried_noodles
|
||||
name = "simple fried noodles"
|
||||
@@ -377,7 +386,7 @@
|
||||
|
||||
/obj/item/food/salad/simple_fried_noodles/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
|
||||
// Curry
|
||||
/obj/item/food/salad/setagaya_curry //let me explain...
|
||||
@@ -395,6 +404,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|FRUIT|SUGAR
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_5 //Extensive and secretly guarded. Was previously 2 and I thought it was pathetic.
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
// Burgers and Sandwiches
|
||||
/obj/item/food/burger/big_blue
|
||||
@@ -411,6 +421,7 @@
|
||||
foodtypes = MEAT | GRAIN | DAIRY | VEGETABLES | FRUIT | PINEAPPLE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4 //It's THE big blue, Baby!
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/burger/chappy
|
||||
name = "\improper Chappy patty"
|
||||
@@ -441,6 +452,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/marte_cubano_sandwich
|
||||
name = "\improper Marte Cubano sandwich"
|
||||
@@ -456,6 +468,7 @@
|
||||
foodtypes = MEAT | DAIRY | VEGETABLES | GRAIN
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/little_shiro_sandwich
|
||||
name = "\improper Little Shiro sandwich"
|
||||
@@ -472,6 +485,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|DAIRY|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/croque_martienne
|
||||
name = "croque-martienne"
|
||||
@@ -487,6 +501,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRUIT|DAIRY|FRIED|PINEAPPLE|BREAKFAST
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/prospect_sunrise
|
||||
name = "\improper Prospect Sunrise"
|
||||
@@ -502,6 +517,7 @@
|
||||
foodtypes = MEAT | DAIRY | VEGETABLES | GRAIN | BREAKFAST
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
// Snacks
|
||||
/obj/item/food/takoyaki
|
||||
@@ -548,6 +564,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRIED|VEGETABLES|DAIRY|SEAFOOD
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4 //Batter AND Cargo ingredients.
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/okonomiyaki
|
||||
name = "okonomiyaki"
|
||||
@@ -566,7 +583,7 @@
|
||||
//hey, the name literally means "grilled how you like it", it'd be crazy to not make it customisable
|
||||
/obj/item/food/okonomiyaki/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_STACK)
|
||||
|
||||
/obj/item/food/brat_kimchi
|
||||
name = "brat-kimchi"
|
||||
@@ -583,6 +600,7 @@
|
||||
foodtypes = MEAT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/tonkatsuwurst
|
||||
name = "tonkatsuwurst"
|
||||
@@ -598,6 +616,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4 //Cargo ingredients and a few steps.
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/kebab/ti_hoeh_koe
|
||||
name = "ti hoeh koe skewer"
|
||||
@@ -642,6 +661,7 @@
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES | FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/roti_john
|
||||
name = "roti john"
|
||||
@@ -657,6 +677,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|BREAKFAST
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/izakaya_fries
|
||||
name = "izakaya fries"
|
||||
@@ -688,6 +709,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/loco_moco
|
||||
name = "loco moco"
|
||||
@@ -702,6 +724,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/wild_duck_fries
|
||||
name = "wild duck fries"
|
||||
@@ -718,6 +741,7 @@
|
||||
foodtypes = MEAT | VEGETABLES | FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4 //Requires a complex 3 as an ingredient.
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/little_hawaii_hotdog
|
||||
name = "\improper Little Hawaii hotdog"
|
||||
@@ -734,6 +758,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_price = PAYCHECK_CREW * 1.2
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salt_chilli_fries
|
||||
name = "salt n' chilli fries"
|
||||
@@ -778,6 +803,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|DAIRY|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/chapsilog
|
||||
name = "chapsilog"
|
||||
@@ -840,6 +866,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRUIT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/huoxing_tofu
|
||||
name = "\improper Huoxing tofu"
|
||||
@@ -856,6 +883,7 @@
|
||||
foodtypes = MEAT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/feizhou_ji
|
||||
name = "fēizhōu jī"
|
||||
@@ -871,7 +899,7 @@
|
||||
foodtypes = MEAT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/galinha_de_cabidela
|
||||
name = "galinha de cabidela"
|
||||
@@ -886,6 +914,7 @@
|
||||
foodtypes = MEAT | VEGETABLES | GRAIN
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/katsu_curry
|
||||
name = "katsu curry"
|
||||
@@ -900,6 +929,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/beef_bowl
|
||||
name = "beef bowl"
|
||||
@@ -915,6 +945,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|SEAFOOD
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/salt_chilli_bowl
|
||||
name = "salt n' chilli octopus bowl"
|
||||
@@ -996,6 +1027,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRUIT|SUGAR|ORANGES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
// Desserts
|
||||
/obj/item/food/cake/spekkoek
|
||||
@@ -1213,6 +1245,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|FRUIT|PINEAPPLE|SEAFOOD
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4 //Uses Sambal
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
custom_price = PAYCHECK_CREW * 2
|
||||
|
||||
/obj/item/food/frickles
|
||||
@@ -1277,6 +1310,7 @@
|
||||
foodtypes = MEAT | RAW
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/kebab/raw_ballpark_tsukune/make_grillable()
|
||||
AddComponent(/datum/component/grillable, /obj/item/food/kebab/ballpark_tsukune, rand(15 SECONDS, 25 SECONDS), TRUE, TRUE)
|
||||
|
||||
@@ -315,6 +315,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/fish_poke
|
||||
name = "fish poke"
|
||||
@@ -420,6 +421,7 @@
|
||||
foodtypes = MEAT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/bearsteak
|
||||
name = "Filet migrawr"
|
||||
@@ -436,12 +438,14 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/raw_meatball
|
||||
name = "raw meatball"
|
||||
desc = "A great meal all round. Not a cord of wood. Kinda raw"
|
||||
icon = 'icons/obj/food/meat.dmi'
|
||||
icon_state = "raw_meatball"
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment/protein = 2)
|
||||
tastes = list("meat" = 1)
|
||||
foodtypes = MEAT | RAW
|
||||
@@ -486,6 +490,7 @@
|
||||
icon = 'icons/obj/food/meat.dmi'
|
||||
icon_state = "meatball"
|
||||
inhand_icon_state = "meatball"
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment/protein = 2)
|
||||
tastes = list("meat" = 1)
|
||||
foodtypes = MEAT
|
||||
@@ -518,6 +523,7 @@
|
||||
desc = "I'm.....NOT REAAADDYY."
|
||||
icon = 'icons/obj/food/meat.dmi'
|
||||
icon_state = "raw_patty"
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment/protein = 2)
|
||||
tastes = list("meat" = 1)
|
||||
foodtypes = MEAT | RAW
|
||||
@@ -555,6 +561,7 @@
|
||||
desc = "The Nanotrasen patty is the patty for you and me!"
|
||||
icon = 'icons/obj/food/meat.dmi'
|
||||
icon_state = "patty"
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment/protein = 2)
|
||||
tastes = list("meat" = 1)
|
||||
foodtypes = MEAT
|
||||
@@ -597,6 +604,7 @@
|
||||
eatverbs = list("bite", "chew", "nibble", "deep throat", "gobble", "chomp")
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/raw_sausage/make_grillable()
|
||||
AddComponent(/datum/component/grillable, /obj/item/food/sausage, rand(60 SECONDS, 75 SECONDS), TRUE)
|
||||
@@ -618,6 +626,7 @@
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_price = PAYCHECK_CREW * 0.6
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/sausage/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/salami, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
|
||||
@@ -658,6 +667,7 @@
|
||||
foodtypes = MEAT|GRAIN|VEGETABLES
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/rawkhinkali/make_grillable()
|
||||
AddComponent(/datum/component/grillable, /obj/item/food/khinkali, rand(50 SECONDS, 60 SECONDS), TRUE)
|
||||
@@ -693,6 +703,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/stewedsoymeat
|
||||
name = "stewed soy meat"
|
||||
@@ -738,6 +749,7 @@
|
||||
foodtypes = MEAT|BUGS
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/sashimi
|
||||
name = "spider sashimi"
|
||||
@@ -777,6 +789,7 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
var/meat_source = "\"chicken\""
|
||||
|
||||
/obj/item/food/nugget/Initialize(mapload)
|
||||
@@ -808,6 +821,7 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_price = PAYCHECK_CREW
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/bbqribs
|
||||
name = "bbq ribs"
|
||||
@@ -823,6 +837,7 @@
|
||||
tastes = list("meat" = 3, "smokey sauce" = 1)
|
||||
foodtypes = MEAT | SUGAR
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/meatclown
|
||||
name = "meat clown"
|
||||
@@ -838,6 +853,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
foodtypes = MEAT | FRUIT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/meatclown/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -856,6 +872,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|DAIRY
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
//////////////////////////////////////////// KEBABS AND OTHER SKEWERS ////////////////////////////////////////////
|
||||
|
||||
@@ -879,6 +896,7 @@
|
||||
tastes = list("tender meat" = 3, "metal" = 1)
|
||||
foodtypes = MEAT | GORE
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/kebab/monkey
|
||||
name = "meat-kebab"
|
||||
@@ -890,6 +908,7 @@
|
||||
tastes = list("meat" = 3, "metal" = 1)
|
||||
foodtypes = MEAT
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/kebab/tofu
|
||||
name = "tofu-kebab"
|
||||
@@ -945,6 +964,7 @@
|
||||
tastes = list("tex-mex" = 3, "cumin" = 2)
|
||||
foodtypes = MEAT | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/fried_chicken
|
||||
name = "fried chicken"
|
||||
@@ -957,6 +977,7 @@
|
||||
junkiness = 25
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/fried_chicken/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -980,6 +1001,7 @@
|
||||
//basic ingredients, but a lot of them. just covering costs here
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/beef_wellington
|
||||
name = "beef wellington"
|
||||
@@ -995,6 +1017,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/beef_wellington/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/beef_wellington_slice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
@@ -1028,6 +1051,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/korta_wellington/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/korta_wellington_slice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
@@ -1061,6 +1085,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/roast_dinner/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/roast_slice, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
@@ -1094,6 +1119,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/roast_dinner_lizzy/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/roast_slice_lizzy, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
@@ -1160,6 +1186,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/raw_meatloaf
|
||||
name = "raw meatloaf"
|
||||
@@ -1175,6 +1202,7 @@
|
||||
foodtypes = MEAT | RAW | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/raw_meatloaf/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, /obj/item/food/meatloaf, rand(30 SECONDS, 40 SECONDS), TRUE, TRUE)
|
||||
@@ -1193,6 +1221,7 @@
|
||||
foodtypes = MEAT | VEGETABLES
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/meatloaf/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meatloaf_slice, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
@@ -1225,6 +1254,7 @@
|
||||
tastes = list("meat" = 5, "savory sauce" = 4, "tangy pineapple" = 3, "pepper" = 2)
|
||||
foodtypes = MEAT | VEGETABLES | FRUIT | PINEAPPLE
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/kebab/pineapple_skewer
|
||||
name = "pineapple skewer"
|
||||
@@ -1238,6 +1268,7 @@
|
||||
tastes = list("juicy meat" = 4, "pineapple" = 3)
|
||||
foodtypes = MEAT | FRUIT | PINEAPPLE
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/futomaki_sushi_roll
|
||||
name = "futomaki sushi roll"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/food/meat
|
||||
custom_materials = list(/datum/material/meat = SHEET_MATERIAL_AMOUNT * 4)
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/food/meat.dmi'
|
||||
var/subjectname = ""
|
||||
@@ -9,7 +9,7 @@
|
||||
/obj/item/food/meat/Initialize(mapload, blood_dna_list = list("meaty DNA" = get_blood_type(BLOOD_TYPE_MEAT)))
|
||||
. = ..()
|
||||
|
||||
if(!blood_decal_type)
|
||||
if(!blood_decal_type || !length(custom_materials))
|
||||
return
|
||||
|
||||
AddComponent(
|
||||
@@ -50,7 +50,7 @@
|
||||
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/plain, rand(30 SECONDS, 90 SECONDS), TRUE, TRUE) //Add medium rare later maybe?
|
||||
|
||||
/obj/item/food/meat/slab/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/plain, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/plain, MEATSLAB_PROCESSED_AMOUNT, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
|
||||
///////////////////////////////////// HUMAN MEATS //////////////////////////////////////////////////////
|
||||
|
||||
@@ -245,6 +245,7 @@
|
||||
desc = "A slice from a huge tomato."
|
||||
icon_state = "tomatomeat"
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 2)
|
||||
custom_materials = null
|
||||
tastes = list("tomato" = 1)
|
||||
foodtypes = FRUIT
|
||||
blood_decal_type = /obj/effect/decal/cleanable/food/tomato_smudge
|
||||
@@ -355,6 +356,7 @@
|
||||
desc = "A raw piece of bacon."
|
||||
icon_state = "bacon"
|
||||
bite_consumption = 2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(
|
||||
/datum/reagent/consumable/nutriment/protein = 2,
|
||||
/datum/reagent/consumable/nutriment/fat = 3,
|
||||
@@ -370,6 +372,7 @@
|
||||
name = "piece of bacon"
|
||||
desc = "A delicious piece of bacon."
|
||||
icon_state = "baconcooked"
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(
|
||||
/datum/reagent/consumable/nutriment/protein = 2,
|
||||
/datum/reagent/consumable/nutriment/vitamin = 1,
|
||||
@@ -605,6 +608,7 @@
|
||||
desc = "A raw meat cutlet."
|
||||
icon_state = "rawcutlet"
|
||||
bite_consumption = 2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment/protein = 2)
|
||||
tastes = list("meat" = 1)
|
||||
foodtypes = MEAT | RAW
|
||||
@@ -715,6 +719,7 @@
|
||||
desc = "A cooked meat cutlet."
|
||||
icon_state = "cutlet"
|
||||
bite_consumption = 2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment/protein = 2)
|
||||
tastes = list("meat" = 1)
|
||||
foodtypes = MEAT
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
venue_value = FOOD_PRICE_EXOTIC
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/fuegoburrito
|
||||
name = "fuego plasma burrito"
|
||||
@@ -142,6 +143,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/taco/plain
|
||||
name = "plain taco"
|
||||
@@ -164,6 +166,7 @@
|
||||
tastes = list("taco" = 4, "fish" = 2, "cheese" = 2, "cabbage" = 1)
|
||||
foodtypes = SEAFOOD | DAIRY | GRAIN | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/enchiladas
|
||||
name = "enchiladas"
|
||||
@@ -181,6 +184,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/stuffedlegion
|
||||
name = "stuffed legion"
|
||||
@@ -198,6 +202,7 @@
|
||||
venue_value = FOOD_PRICE_LEGENDARY
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
crafted_food_buff = /datum/status_effect/food/trait/ashstorm_immune
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/chipsandsalsa
|
||||
name = "chips and salsa"
|
||||
@@ -229,6 +234,7 @@
|
||||
foodtypes = MEAT | GRAIN | VEGETABLES | DAIRY | FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/vegetarian_chimichanga
|
||||
name = "vegetarian chimichanga"
|
||||
@@ -257,7 +263,7 @@
|
||||
|
||||
/obj/item/food/hard_taco_shell/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/hard_taco_shell/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/hard_taco_shell/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
|
||||
|
||||
// empty taco shell for custom tacos
|
||||
/obj/item/food/hard_taco_shell/empty
|
||||
@@ -282,6 +288,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|DAIRY|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/plain_hard_shell_taco
|
||||
name = "plain hard-shell taco"
|
||||
@@ -297,6 +304,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/refried_beans
|
||||
name = "refried beans"
|
||||
|
||||
@@ -297,14 +297,6 @@
|
||||
foodtypes = FRUIT | ALCOHOL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
|
||||
/obj/item/food/melonkeg/CheckParts(list/parts_list)
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in contents
|
||||
if(!bottle)
|
||||
return
|
||||
if(bottle.message_in_a_bottle)
|
||||
bottle.message_in_a_bottle.forceMove(drop_location())
|
||||
|
||||
/obj/item/food/honeybar
|
||||
name = "honey nut bar"
|
||||
desc = "Oats and nuts compressed together into a bar, held together with a honey glaze."
|
||||
@@ -342,6 +334,7 @@
|
||||
foodtypes = GRAIN | FRUIT | SUGAR
|
||||
food_flags = FOOD_FINGER_FOOD
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 3)
|
||||
|
||||
/obj/item/food/branrequests
|
||||
name = "bran requests cereal"
|
||||
@@ -444,6 +437,7 @@
|
||||
foodtypes = MEAT | DAIRY | GRAIN
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pesto
|
||||
name = "pesto"
|
||||
@@ -513,6 +507,7 @@
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/seaweedsheet
|
||||
name = "seaweed sheet"
|
||||
@@ -528,7 +523,7 @@
|
||||
|
||||
/obj/item/food/seaweedsheet/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/sushi/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/sushi/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
|
||||
|
||||
/obj/item/food/seaweedsheet/saltcane
|
||||
name = "dried saltcane sheathe"
|
||||
@@ -573,7 +568,7 @@
|
||||
|
||||
/obj/item/food/onigiri/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/onigiri/empty, CUSTOM_INGREDIENT_ICON_NOCHANGE, max_ingredients = 4)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/onigiri/empty, CUSTOM_INGREDIENT_ICON_NOCHANGE, max_ingredients = 4)
|
||||
|
||||
// empty onigiri for custom onigiri
|
||||
/obj/item/food/onigiri/empty
|
||||
@@ -664,6 +659,7 @@
|
||||
foodtypes = GRAIN | VEGETABLES | MEAT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/stuffed_eggplant
|
||||
name = "stuffed eggplant"
|
||||
@@ -678,6 +674,7 @@
|
||||
foodtypes = VEGETABLES | MEAT | DAIRY
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/moussaka
|
||||
name = "moussaka"
|
||||
@@ -691,6 +688,7 @@
|
||||
tastes = list("cooked eggplant" = 5, "potato" = 1, "baked veggies" = 2, "meat" = 4, "bechamel sauce" = 3)
|
||||
foodtypes = MEAT|VEGETABLES|GRAIN|DAIRY
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/moussaka/make_processable()
|
||||
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/moussaka_slice, 4, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
|
||||
@@ -800,6 +798,7 @@
|
||||
foodtypes = VEGETABLES | GRAIN | MEAT
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/vegetarian_gyro
|
||||
name = "vegetarian gyro"
|
||||
|
||||
@@ -472,6 +472,7 @@
|
||||
foodtypes = MEAT|GRAIN|FRIED
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/bowled/fried_eggplant_polenta
|
||||
name = "fried eggplant and polenta"
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
tastes = list("dog food" = 5, "狗肉" = 3)
|
||||
foodtypes = MEAT | GROSS
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/canned/envirochow/attack_animal(mob/living/simple_animal/user, list/modifiers)
|
||||
if(!check_buffability(user))
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
foodtypes = MEAT|GRAIN|DAIRY
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/soylenviridians
|
||||
name = "\improper Soylent Virdians"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/obj/item/food/pie/plain/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/pie/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/pie/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
|
||||
/obj/item/food/pie/empty
|
||||
name = "pie"
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
/obj/item/food/pieslice/empty/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 8)
|
||||
|
||||
/obj/item/food/pie/cream
|
||||
name = "banana cream pie"
|
||||
@@ -112,6 +112,7 @@
|
||||
tastes = list("pie" = 1, "meat" = 1, "salmon" = 1)
|
||||
foodtypes = GRAIN|DAIRY|SUGAR|MEAT|FRUIT
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pie/meatpie
|
||||
name = "meat-pie"
|
||||
@@ -127,6 +128,7 @@
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
slice_type = /obj/item/food/pieslice/meatpie
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pieslice/meatpie
|
||||
name = "meat-pie slice"
|
||||
@@ -210,6 +212,7 @@
|
||||
foodtypes = MEAT|GRAIN|DAIRY
|
||||
slice_type = /obj/item/food/pieslice/xemeatpie
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pieslice/xemeatpie
|
||||
name = "xeno-pie slice"
|
||||
@@ -464,6 +467,7 @@
|
||||
slice_type = /obj/item/food/pieslice/shepherds_pie
|
||||
yield = 4
|
||||
crafting_complexity = FOOD_COMPLEXITY_5
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pieslice/shepherds_pie
|
||||
name = "shepherds pie slice"
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
/obj/item/food/pizzaslice/margherita/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 12)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 12)
|
||||
|
||||
/obj/item/food/pizza/meat
|
||||
name = "meatpizza"
|
||||
@@ -194,6 +194,7 @@
|
||||
slice_type = /obj/item/food/pizzaslice/meat
|
||||
boxtag = "Meatlovers' Supreme"
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/pizza/meat/raw
|
||||
name = "raw meatpizza"
|
||||
@@ -301,6 +302,7 @@
|
||||
slice_type = /obj/item/food/pizzaslice/donkpocket
|
||||
boxtag = "Bangin' Donk"
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
intrisic_food_materials = list(/datum/material/meat) //default donkpockets do not contain meat but homemade ones do.
|
||||
|
||||
/obj/item/food/pizza/donkpocket/raw
|
||||
name = "raw donkpocket pizza"
|
||||
@@ -317,6 +319,7 @@
|
||||
icon_state = "donkpocketpizzaslice"
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "umami" = 1, "laziness" = 1)
|
||||
foodtypes = GRAIN|VEGETABLES|DAIRY|JUNKFOOD
|
||||
intrisic_food_materials = list(/datum/material/meat) //default donkpockets do not contain meat but homemade ones do.
|
||||
|
||||
/obj/item/food/pizza/dank
|
||||
name = "dank pizza"
|
||||
@@ -328,7 +331,7 @@
|
||||
/datum/reagent/consumable/tomatojuice = 6,
|
||||
/datum/reagent/consumable/nutriment/vitamin = 5,
|
||||
)
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1)
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "weed" = 1)
|
||||
foodtypes = GRAIN | VEGETABLES | DAIRY
|
||||
slice_type = /obj/item/food/pizzaslice/dank
|
||||
boxtag = "Fresh Herb"
|
||||
@@ -347,7 +350,7 @@
|
||||
name = "dank pizza slice"
|
||||
desc = "So good, man..."
|
||||
icon_state = "dankpizzaslice"
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1)
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "weed" = 1)
|
||||
foodtypes = GRAIN | VEGETABLES | DAIRY
|
||||
|
||||
/obj/item/food/pizza/sassysage
|
||||
@@ -365,6 +368,7 @@
|
||||
slice_type = /obj/item/food/pizzaslice/sassysage
|
||||
boxtag = "Sausage Lovers"
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pizza/sassysage/raw
|
||||
name = "raw sassysage pizza"
|
||||
@@ -399,6 +403,7 @@
|
||||
slice_type = /obj/item/food/pizzaslice/pineapple
|
||||
boxtag = "Honolulu Chew"
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/pizza/pineapple/raw
|
||||
name = "raw Hawaiian pizza"
|
||||
@@ -460,6 +465,7 @@
|
||||
boxtag = "9mm Pepperoni"
|
||||
foodtypes = MEAT|GRAIN|DAIRY|VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 4, /datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pizza/arnold/raw
|
||||
name = "raw Arnold pizza"
|
||||
@@ -543,6 +549,7 @@
|
||||
foodtypes = GRAIN|TOXIC
|
||||
boxtag = "24 Hour Energy"
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.4, /datum/material/glass = SMALL_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/pizza/energy/raw
|
||||
name = "raw energy pizza"
|
||||
@@ -574,6 +581,7 @@
|
||||
foodtypes = GRAIN|VEGETABLES|DAIRY|MEAT|RAW
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/raw_meat_calzone/make_bakeable()
|
||||
AddComponent(/datum/component/bakeable, /obj/item/food/meat_calzone, rand(20 SECONDS, 40 SECONDS), TRUE, TRUE)
|
||||
@@ -591,6 +599,7 @@
|
||||
foodtypes = GRAIN|VEGETABLES|DAIRY|MEAT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/raw_vegetarian_calzone
|
||||
name = "raw vegetarian calzone"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/doctor_delight = 8, /datum/reagent/consumable/nutriment/vitamin = 6)
|
||||
tastes = list("leaves" = 1, "potato" = 1, "meat" = 1, "valids" = 1)
|
||||
foodtypes = VEGETABLES | MEAT | FRIED
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/salad/fruit
|
||||
name = "fruit salad"
|
||||
@@ -119,6 +120,7 @@
|
||||
tastes = list("rice" = 1, "meat" = 1)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/salad/risotto
|
||||
name = "risotto"
|
||||
@@ -170,6 +172,7 @@
|
||||
tastes = list("building heat" = 2, "savory meat and vegtables" = 1)
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/reagent_containers/cup/bowl
|
||||
name = "bowl"
|
||||
@@ -192,7 +195,7 @@
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_ATOM_REAGENT_EXAMINE, PROC_REF(reagent_special_examine))
|
||||
AddElement(/datum/element/foodlike_drink)
|
||||
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/salad/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
|
||||
AddComponent(/datum/component/ingredients_holder, /obj/item/food/salad/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
|
||||
AddComponent( \
|
||||
/datum/component/takes_reagent_appearance, \
|
||||
on_icon_changed = CALLBACK(src, PROC_REF(on_cup_change)), \
|
||||
@@ -330,3 +333,4 @@
|
||||
tastes = list("lettuce" = 2, "salami" = 2, "mozzarella cheese" = 2, "tomatoes" = 2, "dressing" = 1)
|
||||
foodtypes = MEAT|VEGETABLES|FRUIT|DAIRY
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
food_flags = FOOD_FINGER_FOOD
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/sandwich/cheese
|
||||
name = "cheese sandwich"
|
||||
@@ -26,6 +27,7 @@
|
||||
foodtypes = GRAIN | DAIRY
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/sandwich/cheese/make_grillable()
|
||||
AddComponent(/datum/component/grillable, /obj/item/food/sandwich/cheese/grilled, rand(30 SECONDS, 60 SECONDS), TRUE)
|
||||
@@ -52,6 +54,7 @@
|
||||
tastes = list("bread" = 1, "jelly" = 1)
|
||||
foodtypes = GRAIN
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/sandwich/jelly/slime
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/toxin/slimejelly = 10, /datum/reagent/consumable/nutriment/vitamin = 4)
|
||||
@@ -72,6 +75,7 @@
|
||||
tastes = list("nothing suspicious" = 1)
|
||||
foodtypes = GRAIN | GROSS
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/griddle_toast
|
||||
name = "griddle toast"
|
||||
@@ -154,6 +158,7 @@
|
||||
venue_value = FOOD_PRICE_CHEAP
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_price = PAYCHECK_CREW * 0.7
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
// Used for unit tests, do not delete
|
||||
/obj/item/food/hotdog/debug
|
||||
@@ -177,6 +182,7 @@
|
||||
venue_value = FOOD_PRICE_NORMAL
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_price = PAYCHECK_CREW
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/sandwich/blt
|
||||
name = "\improper BLT"
|
||||
@@ -191,6 +197,7 @@
|
||||
tastes = list("bacon" = 3, "lettuce" = 2, "tomato" = 2, "bread" = 2)
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES | BREAKFAST
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/sandwich/peanut_butter_jelly
|
||||
name = "peanut butter and jelly sandwich"
|
||||
@@ -204,6 +211,7 @@
|
||||
tastes = list("peanut butter" = 1, "jelly" = 1, "bread" = 2)
|
||||
foodtypes = GRAIN | FRUIT | NUTS
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/sandwich/peanut_butter_banana
|
||||
name = "peanut butter and banana sandwich"
|
||||
@@ -218,6 +226,7 @@
|
||||
tastes = list("peanut butter" = 1, "banana" = 1, "bread" = 2)
|
||||
foodtypes = GRAIN | FRUIT | NUTS
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/sandwich/philly_cheesesteak
|
||||
name = "Philly cheesesteak"
|
||||
@@ -231,6 +240,7 @@
|
||||
tastes = list("bread" = 1, "juicy meat" = 1, "melted cheese" = 1, "onions" = 1)
|
||||
foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/sandwich/toast_sandwich
|
||||
name = "toast sandwich"
|
||||
@@ -244,6 +254,7 @@
|
||||
tastes = list("bread" = 2, "Britain" = 1, "butter" = 1, "toast" = 1)
|
||||
foodtypes = GRAIN|DAIRY
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = null
|
||||
|
||||
/obj/item/food/sandwich/death
|
||||
name = "death sandwich"
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
foodtypes = JUNKFOOD | MEAT | SUGAR
|
||||
crafting_complexity = FOOD_COMPLEXITY_1
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/sosjerky/healthy
|
||||
name = "homemade beef jerky"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
/obj/item/food/spaghetti/boiledspaghetti/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/customizable_reagent_holder, null, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 6)
|
||||
AddComponent(/datum/component/ingredients_holder, null, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 6)
|
||||
|
||||
/obj/item/food/spaghetti/pastatomato
|
||||
name = "spaghetti"
|
||||
@@ -100,6 +100,7 @@
|
||||
tastes = list("pasta" = 1, "meat" = 1)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/spaghetti/spesslaw
|
||||
name = "spesslaw"
|
||||
@@ -113,6 +114,7 @@
|
||||
tastes = list("pasta" = 1, "meat" = 1)
|
||||
foodtypes = GRAIN | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 4)
|
||||
|
||||
/obj/item/food/spaghetti/chowmein
|
||||
name = "chow mein"
|
||||
@@ -126,6 +128,7 @@
|
||||
tastes = list("noodle" = 1, "meat" = 1, "fried vegetables" = 1)
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/spaghetti/beefnoodle
|
||||
name = "beef noodle"
|
||||
@@ -141,6 +144,7 @@
|
||||
tastes = list("noodles" = 1, "meat" = 1)
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/spaghetti/butternoodles
|
||||
name = "butter noodles"
|
||||
@@ -179,6 +183,7 @@
|
||||
tastes = list("noodles" = 5, "meat" = 3, "egg" = 4, "dried seaweed" = 2)
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/spaghetti/kitakata_ramen
|
||||
name = "kitakata ramen"
|
||||
@@ -193,6 +198,7 @@
|
||||
tastes = list("noodles" = 5, "meat" = 4, "mushrooms" = 3, "onion" = 2)
|
||||
foodtypes = GRAIN | MEAT | VEGETABLES
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/spaghetti/kitsune_udon
|
||||
name = "kitsune udon"
|
||||
@@ -221,6 +227,7 @@
|
||||
tastes = list("noodles" = 5, "meat" = 4, "potato" = 3, "onion" = 2, "mixed veggies" = 2)
|
||||
foodtypes = GRAIN | VEGETABLES | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2)
|
||||
|
||||
/obj/item/food/spaghetti/pho
|
||||
name = "pho"
|
||||
@@ -235,6 +242,7 @@
|
||||
tastes = list("noodles" = 5, "meat" = 4, "cabbage" = 3, "onion" = 2, "herbs" = 2)
|
||||
foodtypes = GRAIN | VEGETABLES | MEAT
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/spaghetti/pad_thai
|
||||
name = "pad thai"
|
||||
@@ -262,6 +270,7 @@
|
||||
tastes = list("spaghetti" = 1, "parmigiano reggiano" = 1, "guanciale" = 1)
|
||||
foodtypes = GRAIN | MEAT | DAIRY
|
||||
crafting_complexity = FOOD_COMPLEXITY_4
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/food/spaghetti/carbonara/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
foodtypes = VEGETABLES | DAIRY | MEAT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
crafting_complexity = FOOD_COMPLEXITY_3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
|
||||
// Fries
|
||||
/obj/item/food/fries
|
||||
|
||||
@@ -77,8 +77,8 @@
|
||||
user.visible_message(span_suicide("[user] begins to sword-swallow \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/spear/CheckParts(list/parts_list)
|
||||
var/obj/item/shard/tip = locate() in parts_list
|
||||
/obj/item/spear/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
var/obj/item/shard/tip = locate() in components
|
||||
if(!tip)
|
||||
return ..()
|
||||
|
||||
@@ -116,8 +116,6 @@
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=force_unwielded, force_wielded=force_wielded, icon_wielded="[icon_prefix]1")
|
||||
|
||||
update_appearance()
|
||||
parts_list -= tip
|
||||
qdel(tip)
|
||||
return ..()
|
||||
|
||||
/obj/item/spear/explosive
|
||||
@@ -138,17 +136,14 @@
|
||||
explosive = G
|
||||
desc = "A makeshift spear with [G] attached to it"
|
||||
|
||||
/obj/item/spear/explosive/CheckParts(list/parts_list)
|
||||
var/obj/item/grenade/G = locate() in parts_list
|
||||
if(G)
|
||||
var/obj/item/spear/lancePart = locate() in parts_list
|
||||
/obj/item/spear/explosive/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
var/obj/item/grenade/nade = locate() in components
|
||||
if(nade)
|
||||
var/obj/item/spear/lancePart = locate() in components
|
||||
throwforce = lancePart.throwforce
|
||||
icon_prefix = lancePart.icon_prefix
|
||||
parts_list -= G
|
||||
parts_list -= lancePart
|
||||
set_explosive(G)
|
||||
qdel(lancePart)
|
||||
..()
|
||||
set_explosive(nade)
|
||||
return ..()
|
||||
|
||||
/obj/item/spear/explosive/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message(span_suicide("[user] begins to sword-swallow \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
|
||||
@@ -243,27 +243,26 @@
|
||||
|
||||
// MEAT MEAT MEAT MEAT MEAT
|
||||
|
||||
///This nullifies the force malus from the meat material while not touching other stats.
|
||||
#define INVERSE_MEAT_STRENTGH (1 / /datum/material/meat::strength_modifier)
|
||||
|
||||
/obj/item/storage/backpack/meat
|
||||
name = "\improper MEAT"
|
||||
desc = "MEAT MEAT MEAT MEAT MEAT MEAT"
|
||||
icon_state = "meatmeatmeat"
|
||||
inhand_icon_state = "meatmeatmeat"
|
||||
force = 15
|
||||
throwforce = 15
|
||||
force = 15 * INVERSE_MEAT_STRENTGH
|
||||
throwforce = 15 * INVERSE_MEAT_STRENTGH
|
||||
material_flags = MATERIAL_EFFECTS | MATERIAL_AFFECT_STATISTICS
|
||||
attack_verb_continuous = list("MEATS", "MEAT MEATS")
|
||||
attack_verb_simple = list("MEAT", "MEAT MEAT")
|
||||
custom_materials = list(/datum/material/meat = SHEET_MATERIAL_AMOUNT * 25) // MEAT
|
||||
custom_materials = list(/datum/material/meat = SHEET_MATERIAL_AMOUNT * 15) // MEAT
|
||||
///Sounds used in the squeak component
|
||||
var/list/meat_sounds = list('sound/effects/blob/blobattack.ogg' = 1)
|
||||
///Reagents added to the edible component, ingested when you EAT the MEAT
|
||||
///Reagents added to the edible component on top of the meat material, ingested when you EAT the MEAT
|
||||
var/list/meat_reagents = list(
|
||||
/datum/reagent/consumable/nutriment/protein = 10,
|
||||
/datum/reagent/consumable/nutriment/vitamin = 10,
|
||||
/datum/reagent/consumable/nutriment/vitamin = 15,
|
||||
)
|
||||
///The food types of the edible component
|
||||
var/foodtypes = MEAT | RAW
|
||||
///How our MEAT tastes. It tastes like MEAT
|
||||
var/list/tastes = list("MEAT" = 1)
|
||||
///Eating verbs when consuming the MEAT
|
||||
var/list/eatverbs = list("MEAT", "absorb", "gnaw", "consume")
|
||||
|
||||
@@ -273,21 +272,13 @@
|
||||
SOURCE_EDIBLE_INNATE, \
|
||||
/datum/component/edible,\
|
||||
initial_reagents = meat_reagents,\
|
||||
foodtypes = foodtypes,\
|
||||
tastes = tastes,\
|
||||
tastes = list("meat" = 1),\
|
||||
eatverbs = eatverbs,\
|
||||
)
|
||||
|
||||
AddComponent(/datum/component/squeak, meat_sounds)
|
||||
AddComponent(
|
||||
/datum/component/blood_walk,\
|
||||
blood_type = /obj/effect/decal/cleanable/blood,\
|
||||
blood_spawn_chance = 15,\
|
||||
max_blood = custom_materials[custom_materials[1]] / SHEET_MATERIAL_AMOUNT,\
|
||||
)
|
||||
AddComponent(
|
||||
/datum/component/bloody_spreader,\
|
||||
blood_left = custom_materials[custom_materials[1]] / SHEET_MATERIAL_AMOUNT,\
|
||||
)
|
||||
|
||||
#undef INVERSE_MEAT_STRENTGH
|
||||
|
||||
/*
|
||||
* Satchel Types
|
||||
|
||||
@@ -99,6 +99,12 @@
|
||||
/obj/item/storage/proc/get_types_to_preload()
|
||||
return
|
||||
|
||||
/obj/item/storage/used_in_craft(atom/result, datum/crafting_recipe/current_recipe)
|
||||
. = ..()
|
||||
// If we consumed in crafting, we should dump contents out before qdeling them.
|
||||
if(!is_type_in_list(src, current_recipe.parts))
|
||||
emptyStorage()
|
||||
|
||||
/// Removes an item or puts it in mouth from the contents, if any
|
||||
/obj/item/storage/proc/quick_remove_item(obj/item/grabbies, mob/user, equip_to_mouth = FALSE)
|
||||
var/obj/item/finger = locate(grabbies) in contents
|
||||
|
||||
@@ -326,28 +326,18 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag)
|
||||
. = ..()
|
||||
if(!(material_flags & MATERIAL_AFFECT_STATISTICS))
|
||||
return
|
||||
if(uses_integrity)
|
||||
var/integrity_mod = GET_MATERIAL_MODIFIER(material.integrity_modifier, multiplier)
|
||||
modify_max_integrity(ceil(max_integrity * integrity_mod))
|
||||
var/strength_mod = GET_MATERIAL_MODIFIER(material.strength_modifier, multiplier)
|
||||
force *= strength_mod
|
||||
throwforce *= strength_mod
|
||||
var/list/armor_mods = material.get_armor_modifiers(multiplier)
|
||||
set_armor(get_armor().generate_new_with_multipliers(armor_mods))
|
||||
|
||||
///This proc is called when the material is removed from an object specifically.
|
||||
/obj/remove_single_mat_effect(datum/material/material, mat_amount, multiplier)
|
||||
. = ..()
|
||||
if(!(material_flags & MATERIAL_AFFECT_STATISTICS))
|
||||
return
|
||||
if(uses_integrity)
|
||||
var/integrity_mod = GET_MATERIAL_MODIFIER(material.integrity_modifier, multiplier)
|
||||
modify_max_integrity(floor(max_integrity / integrity_mod))
|
||||
var/strength_mod = GET_MATERIAL_MODIFIER(material.strength_modifier, multiplier)
|
||||
force /= strength_mod
|
||||
throwforce /= strength_mod
|
||||
var/list/armor_mods = material.get_armor_modifiers(1 / multiplier)
|
||||
set_armor(get_armor().generate_new_with_multipliers(armor_mods))
|
||||
|
||||
/// Returns modifier to how much damage this object does to a target considered vulnerable to "demolition" (other objects, robots, etc)
|
||||
/obj/proc/get_demolition_modifier(obj/target)
|
||||
|
||||
@@ -77,3 +77,9 @@
|
||||
flying_mob.apply_damage(damage = rand(5, 15), damagetype = BRUTE, wound_bonus = 15, bare_wound_bonus = 25, sharpness = SHARP_EDGED, attack_direction = get_dir(src, oldloc))
|
||||
new /obj/effect/decal/cleanable/glass(get_step(flying_mob, flying_mob.dir))
|
||||
deconstruct(disassembled = FALSE)
|
||||
|
||||
/obj/structure/used_in_craft(atom/result, datum/crafting_recipe/current_recipe)
|
||||
. = ..()
|
||||
// If we consumed in crafting, we should dump contents out before qdeling them.
|
||||
if(!is_type_in_list(src, current_recipe.parts))
|
||||
dump_contents()
|
||||
|
||||
@@ -614,21 +614,22 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets)
|
||||
if(!broken)
|
||||
bust_open()
|
||||
|
||||
/obj/structure/closet/CheckParts(list/parts_list)
|
||||
var/obj/item/electronics/airlock/access_control = locate() in parts_list
|
||||
/obj/structure/closet/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
var/obj/item/electronics/airlock/access_control = locate() in components
|
||||
if(QDELETED(access_control))
|
||||
return
|
||||
return ..()
|
||||
|
||||
inherit_airlock_electronics_access(access_control)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/proc/inherit_airlock_electronics_access(obj/item/electronics/airlock/access_control)
|
||||
if (access_control.one_access)
|
||||
req_one_access = access_control.accesses
|
||||
req_access = null
|
||||
else
|
||||
req_access = access_control.accesses
|
||||
req_one_access = null
|
||||
access_control.moveToNullspace()
|
||||
|
||||
parts_list -= access_control
|
||||
qdel(access_control)
|
||||
|
||||
/obj/structure/closet/multitool_act(mob/living/user, obj/item/tool)
|
||||
if(!secure || !card_reader_installed || broken || locked || opened)
|
||||
@@ -742,7 +743,8 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets)
|
||||
if(!user.transferItemToLoc(weapon, src))
|
||||
return
|
||||
|
||||
CheckParts(list(weapon))
|
||||
inherit_airlock_electronics_access(weapon)
|
||||
qdel(weapon)
|
||||
secure = TRUE
|
||||
balloon_alert(user, "electronics installed")
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
/obj/structure/headpike/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
CheckParts()
|
||||
spear = new speartype(src)
|
||||
victim = new(src)
|
||||
victim.real_name = generate_random_name()
|
||||
pixel_x = rand(-8, 8)
|
||||
|
||||
/obj/structure/headpike/Destroy()
|
||||
@@ -32,16 +34,11 @@
|
||||
QDEL_NULL(spear)
|
||||
return ..()
|
||||
|
||||
/obj/structure/headpike/CheckParts(list/parts_list)
|
||||
victim = locate() in parts_list
|
||||
if(!victim) //likely a mapspawned one
|
||||
victim = new(src)
|
||||
victim.real_name = generate_random_name()
|
||||
spear = locate(speartype) in parts_list
|
||||
if(!spear)
|
||||
spear = new speartype(src)
|
||||
/obj/structure/headpike/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
victim = locate() in contents
|
||||
spear = locate(speartype) in contents
|
||||
update_appearance()
|
||||
return ..()
|
||||
|
||||
/obj/structure/headpike/update_name()
|
||||
name = "[victim.real_name] on a [spear.name]"
|
||||
|
||||
@@ -17,6 +17,21 @@
|
||||
weed_overlay = mutable_appearance('icons/obj/watercloset.dmi', "[base_icon_state]_overlay")
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/toiletbong/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
var/obj/structure/toilet/toilet = locate(/obj/structure/toilet) in components
|
||||
if(toilet)
|
||||
for(var/obj/item/cistern_item in toilet.contents)
|
||||
cistern_item.forceMove(crafter.drop_location())
|
||||
to_chat(crafter, span_warning("[cistern_item] falls out of the toilet!"))
|
||||
setDir(toilet.dir)
|
||||
forceMove(toilet.loc)
|
||||
|
||||
crafter.visible_message(
|
||||
span_notice("[crafter] attaches the flamethrower to the repurposed toilet."),
|
||||
span_notice("You attach the flamethrower to the repurposed toilet."),
|
||||
)
|
||||
return ..()
|
||||
|
||||
/obj/structure/toiletbong/update_overlays()
|
||||
. = ..()
|
||||
if (LAZYLEN(contents))
|
||||
|
||||
@@ -160,6 +160,7 @@
|
||||
icon = 'icons/obj/food/egg.dmi'
|
||||
icon_state = "scotchegg"
|
||||
bite_consumption = 3
|
||||
custom_materials = list(/datum/material/meat = MEATDISH_MATERIAL_AMOUNT)
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2)
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
foodtypes = MEAT
|
||||
|
||||
@@ -35,7 +35,7 @@ GLOBAL_LIST_INIT(fish_compatible_fluid_types, list(
|
||||
obj_flags = UNIQUE_RENAME
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
//we handle slowdowns internally, and the fish weight modifier from materials already contributes to it.
|
||||
material_flags = MATERIAL_EFFECTS|MATERIAL_AFFECT_STATISTICS|MATERIAL_COLOR|MATERIAL_ADD_PREFIX|MATERIAL_NO_SLOWDOWN
|
||||
material_flags = MATERIAL_EFFECTS|MATERIAL_AFFECT_STATISTICS|MATERIAL_COLOR|MATERIAL_ADD_PREFIX|MATERIAL_NO_SLOWDOWN|MATERIAL_NO_EDIBILITY
|
||||
|
||||
/// Flags for fish variables that would otherwise be TRUE/FALSE
|
||||
var/fish_flags = FISH_FLAG_SHOW_IN_CATALOG|FISH_DO_FLOP_ANIM|FISH_FLAG_EXPERIMENT_SCANNABLE
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
/datum/crafting_recipe/food
|
||||
mass_craftable = TRUE
|
||||
crafting_flags = parent_type::crafting_flags | CRAFT_TRANSFERS_REAGENTS | CRAFT_CLEARS_REAGENTS
|
||||
requirements_mats_blacklist = list(
|
||||
/obj/item/reagent_containers/cup/bowl,
|
||||
/obj/item/popsicle_stick,
|
||||
/obj/item/stack/rods,
|
||||
)
|
||||
crafting_flags = parent_type::crafting_flags | CRAFT_TRANSFERS_REAGENTS | CRAFT_CLEARS_REAGENTS | CRAFT_ENFORCE_MATERIALS_PARITY
|
||||
///The food types that are added to the result when the recipe is completed
|
||||
var/added_foodtypes = NONE
|
||||
///The food types that are removed to the result when the recipe is completed
|
||||
var/removed_foodtypes = NONE
|
||||
|
||||
/datum/crafting_recipe/food/on_craft_completion(mob/user, atom/result)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
. = ..()
|
||||
if(istype(result) && istype(user) && !isnull(user.mind))
|
||||
ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(user.mind))
|
||||
|
||||
/datum/crafting_recipe/food/New()
|
||||
. = ..()
|
||||
parts |= reqs
|
||||
|
||||
//rarely, but a few cooking recipes (cake cat & co) don't result food items.
|
||||
if(!PERFORM_ALL_TESTS(focus_only/check_foodtypes) || non_craftable || !ispath(result, /obj/item/food))
|
||||
return
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/obj/item/food/meat/slab/xeno,
|
||||
/obj/item/food/meat/slab/bear,
|
||||
/obj/item/food/meat/slab/chicken)
|
||||
food_multiplier = 3
|
||||
food_multiplier = MEATSLAB_PROCESSED_AMOUNT
|
||||
|
||||
/datum/food_processor_process/cutlet
|
||||
input = /obj/item/food/meat/cutlet/plain
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
/obj/item/food/bun = 1,
|
||||
/obj/item/food/patty/human = 1
|
||||
)
|
||||
parts = list(
|
||||
/obj/item/food/patty = 1
|
||||
)
|
||||
result = /obj/item/food/burger/human
|
||||
category = CAT_BURGER
|
||||
|
||||
@@ -304,7 +301,7 @@
|
||||
/obj/item/stack/sheet/mineral/plasma = 2,
|
||||
/obj/item/food/bun = 1
|
||||
)
|
||||
|
||||
requirements_mats_blacklist = list(/obj/item/stack/sheet/mineral/plasma)
|
||||
result = /obj/item/food/burger/empoweredburger
|
||||
added_foodtypes = TOXIC
|
||||
category = CAT_BURGER
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
|
||||
// This is the home of drink related tablecrafting recipes, I have opted to only let players bottle fancy boozes to reduce the number of entries.
|
||||
|
||||
///Abstract types for all drink recipes that use bottles and result in another bottle, so that the message_in_a_bottle item is properly transferred.
|
||||
/datum/crafting_recipe/bottled
|
||||
parts = list(/obj/item/reagent_containers/cup/glass/bottle = 1)
|
||||
|
||||
///////////////// Booze & Bottles ///////////////////
|
||||
|
||||
/datum/crafting_recipe/lizardwine
|
||||
@@ -18,7 +13,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/lizardwine
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/moonshinejug
|
||||
/datum/crafting_recipe/moonshinejug
|
||||
name = "Moonshine Jug"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -28,7 +23,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/moonshine
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/hoochbottle
|
||||
/datum/crafting_recipe/hoochbottle
|
||||
name = "Hooch Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -39,7 +34,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/hooch
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/blazaambottle
|
||||
/datum/crafting_recipe/blazaambottle
|
||||
name = "Blazaam Bottle"
|
||||
time = 20
|
||||
reqs = list(
|
||||
@@ -49,7 +44,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/blazaam
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/champagnebottle
|
||||
/datum/crafting_recipe/champagnebottle
|
||||
name = "Champagne Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -59,7 +54,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/champagne
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/trappistbottle
|
||||
/datum/crafting_recipe/trappistbottle
|
||||
name = "Trappist Bottle"
|
||||
time = 15
|
||||
reqs = list(
|
||||
@@ -69,7 +64,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/trappist
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/goldschlagerbottle
|
||||
/datum/crafting_recipe/goldschlagerbottle
|
||||
name = "Goldschlager Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -79,7 +74,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/goldschlager
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/patronbottle
|
||||
/datum/crafting_recipe/patronbottle
|
||||
name = "Patron Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -91,7 +86,7 @@
|
||||
|
||||
////////////////////// Non-alcoholic recipes ///////////////////
|
||||
|
||||
/datum/crafting_recipe/bottled/holybottle
|
||||
/datum/crafting_recipe/holybottle
|
||||
name = "Holy Water Flask"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -103,7 +98,7 @@
|
||||
|
||||
//flask of unholy water is a beaker for some reason, I will try making it a bottle and add it here once the antag freeze is over. t. kryson
|
||||
|
||||
/datum/crafting_recipe/bottled/nothingbottle
|
||||
/datum/crafting_recipe/nothingbottle
|
||||
name = "Nothing Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -120,7 +115,7 @@
|
||||
reqs = list(/obj/item/stack/sheet/cardboard = 1)
|
||||
category = CAT_CONTAINERS
|
||||
|
||||
/datum/crafting_recipe/bottled/candycornliquor
|
||||
/datum/crafting_recipe/candycornliquor
|
||||
name = "candy corn liquor"
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/candycornliquor
|
||||
time = 30
|
||||
@@ -129,7 +124,7 @@
|
||||
/obj/item/reagent_containers/cup/glass/bottle = 1)
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/bottled/kong
|
||||
/datum/crafting_recipe/kong
|
||||
name = "Kong"
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/kong
|
||||
time = 30
|
||||
@@ -143,8 +138,11 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/pruno
|
||||
time = 30
|
||||
reqs = list(/obj/item/storage/bag/trash = 1,
|
||||
/obj/item/food/breadslice/moldy = 1,
|
||||
/obj/item/food/grown = 4,
|
||||
/obj/item/food/candy_corn = 2,
|
||||
/datum/reagent/water = 15)
|
||||
/obj/item/food/breadslice/moldy = 1,
|
||||
/obj/item/food/grown = 4,
|
||||
/obj/item/food/candy_corn = 2,
|
||||
/datum/reagent/water = 15,
|
||||
)
|
||||
//We can't spawn the abstract food/grown path
|
||||
unit_test_spawn_extras = list(/obj/item/food/grown/banana = 4)
|
||||
category = CAT_DRINK
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
/datum/crafting_recipe/runed_metal
|
||||
reqs = list(/obj/item/stack/sheet/plasteel = 1)
|
||||
requirements_mats_blacklist = list(/obj/item/stack/sheet/plasteel) // runed metal has its own material
|
||||
result = /obj/item/stack/sheet/runed_metal
|
||||
category = CAT_CULT
|
||||
non_craftable = TRUE
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
blacklist = list(
|
||||
/obj/item/organ/lungs/cybernetic,
|
||||
)
|
||||
|
||||
result = /obj/item/food/shredded_lungs
|
||||
added_foodtypes = MEAT|GORE
|
||||
category = CAT_LIZARD
|
||||
|
||||
@@ -27,10 +27,8 @@
|
||||
|
||||
/datum/crafting_recipe/food/chococoin
|
||||
name = "Choco coin"
|
||||
reqs = list(
|
||||
/obj/item/coin = 1,
|
||||
/obj/item/food/chocolatebar = 1,
|
||||
)
|
||||
reqs = list(/obj/item/food/chocolatebar = 1)
|
||||
tool_paths = list(/obj/item/coin)
|
||||
result = /obj/item/food/chococoin
|
||||
category = CAT_MISCFOOD
|
||||
|
||||
@@ -97,7 +95,6 @@
|
||||
/obj/item/food/grown/holymelon = 1,
|
||||
/obj/item/reagent_containers/cup/glass/bottle/vodka = 1
|
||||
)
|
||||
parts = list(/obj/item/reagent_containers/cup/glass/bottle/vodka = 1)
|
||||
result = /obj/item/food/melonkeg
|
||||
added_foodtypes = ALCOHOL
|
||||
category = CAT_MISCFOOD
|
||||
|
||||
@@ -15,15 +15,6 @@
|
||||
removed_foodtypes = RAW
|
||||
category = CAT_PASTRY
|
||||
|
||||
// It is so stupid that we have to do this but because food crafting clears all reagents that got added during init,
|
||||
// here we are adding it again (but only for crafting, maploaded and spawned donuts work fine).
|
||||
// Until the issues with crafted items' reagents are resolved this will have to do
|
||||
/datum/crafting_recipe/food/donut/on_craft_completion(mob/user, atom/result)
|
||||
. = ..()
|
||||
var/obj/item/food/donut/donut_result = result
|
||||
if(donut_result.is_decorated)
|
||||
donut_result.reagents.add_reagent(/datum/reagent/consumable/sprinkles, 1)
|
||||
|
||||
/datum/crafting_recipe/food/donut/chaos
|
||||
name = "Chaos donut"
|
||||
reqs = list(
|
||||
|
||||
@@ -262,6 +262,7 @@
|
||||
/obj/item/food/pie/plain = 1,
|
||||
/obj/item/stock_parts/power_store/cell = 2,
|
||||
)
|
||||
requirements_mats_blacklist = list(/obj/item/stock_parts/power_store/cell)
|
||||
result = /obj/item/food/pie/bacid_pie
|
||||
added_foodtypes = TOXIC
|
||||
category = CAT_PIE
|
||||
|
||||
@@ -106,6 +106,9 @@
|
||||
if(istext(result))
|
||||
say("Crafting failed[result]")
|
||||
return
|
||||
if(isstack(result)) //it doesn't have hands to pick up stacks so let's try to merge them instead
|
||||
var/obj/item/stack/stack = result
|
||||
stack.merge_with_loc()
|
||||
var/list/diff = get_overfloor_objects() - prediff
|
||||
for(var/atom/movable/diff_result as anything in diff)
|
||||
if(iseffect(diff_result) || ismob(diff_result)) // PLEASE dont stuff cats (or other mobs) into the cat grinder 9000
|
||||
@@ -114,7 +117,6 @@
|
||||
diff_result.pixel_x += rand(-4, 4)
|
||||
diff_result.pixel_y += rand(-4, 4)
|
||||
withheld += WEAKREF(diff_result)
|
||||
recipe.on_craft_completion(src, diff_result)
|
||||
send_withheld()
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/cooker
|
||||
|
||||
@@ -162,6 +162,15 @@
|
||||
if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb)
|
||||
CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, src)
|
||||
|
||||
/mob/living/basic/bot/medbot/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
var/obj/item/storage/medkit/medkit = locate() in contents
|
||||
medkit_type = medkit
|
||||
health_analyzer = locate(/obj/item/healthanalyzer) in contents
|
||||
skin = medkit.get_medbot_skin()
|
||||
damage_type_healer = initial(medkit.damagetype_healed) ? initial(medkit.damagetype_healed) : BRUTE
|
||||
update_appearance()
|
||||
|
||||
/mob/living/basic/bot/medbot/update_icon_state()
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -193,6 +193,8 @@
|
||||
/obj/item/food/breadslice/plain = 1
|
||||
)
|
||||
collar_icon_state = null
|
||||
//just ensuring the mats contained by the cat when spawned are the same of when crafted
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 3)
|
||||
|
||||
/mob/living/basic/pet/cat/breadcat/add_cell_sample()
|
||||
return
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
death_sound = SFX_BODYFALL
|
||||
held_state = "cak"
|
||||
can_interact_with_stove = TRUE
|
||||
//just ensuring the mats contained by the cat when spawned are the same of when crafted
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 3)
|
||||
|
||||
/mob/living/basic/pet/cat/cak/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -38,7 +40,7 @@
|
||||
/mob/living/basic/pet/cat/cak/add_cell_sample()
|
||||
return
|
||||
|
||||
/mob/living/basic/pet/cat/cak/CheckParts(list/parts)
|
||||
/mob/living/basic/pet/cat/cak/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
var/obj/item/organ/brain/candidate = locate(/obj/item/organ/brain) in contents
|
||||
if(isnull(candidate?.brainmob?.mind))
|
||||
|
||||
@@ -98,8 +98,10 @@
|
||||
attacked_sound = 'sound/items/eatfood.ogg'
|
||||
held_state = "breaddog"
|
||||
worn_slot_flags = ITEM_SLOT_HEAD
|
||||
//just ensuring the mats contained by the dog when spawned are the same of when crafted
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 3)
|
||||
|
||||
/mob/living/basic/pet/dog/breaddog/CheckParts(list/parts)
|
||||
/mob/living/basic/pet/dog/breaddog/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
. = ..()
|
||||
var/obj/item/organ/brain/candidate = locate(/obj/item/organ/brain) in contents
|
||||
if(!candidate || !candidate.brainmob || !candidate.brainmob.mind)
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
attack_vis_effect = ATTACK_EFFECT_DISARM
|
||||
attack_verb_simple = "slap"
|
||||
attack_verb_continuous = "slaps"
|
||||
//just ensuring the mats contained by the bear when spawned are the same of when crafted
|
||||
custom_materials = list(/datum/material/meat = MEATSLAB_MATERIAL_AMOUNT * 5)
|
||||
|
||||
/mob/living/basic/bear/butter/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -159,7 +161,7 @@
|
||||
user.reagents.add_reagent(/datum/reagent/consumable/nutriment, 1)
|
||||
user.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.1)
|
||||
|
||||
/mob/living/basic/bear/butter/CheckParts(list/parts) //Borrowed code from Cak, allows the brain used to actually control the bear.
|
||||
/mob/living/basic/bear/butter/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter) //Borrowed code from Cak, allows the brain used to actually control the bear.
|
||||
. = ..()
|
||||
var/obj/item/organ/brain/candidate = locate(/obj/item/organ/brain) in contents
|
||||
if(!candidate || !candidate.brainmob || !candidate.brainmob.mind)
|
||||
|
||||
@@ -553,14 +553,12 @@
|
||||
greyscale_colors = "#00ff00"
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/core/soul/CheckParts(list/parts_list, datum/crafting_recipe/current_recipe)
|
||||
var/obj/item/soulstone/stone = locate() in parts_list
|
||||
/obj/item/mod/core/soul/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
var/obj/item/soulstone/stone = locate() in components
|
||||
set_theme(stone.theme)
|
||||
for(var/mob/living/basic/shade/shade in stone)
|
||||
shade.forceMove(get_turf(src))
|
||||
shade.visible_message(span_warning("[shade] is ejected from [stone] as it is inserted into [src]!"), span_warning("You are ejected from [stone] as it is inserted into [src]!"))
|
||||
parts_list -= stone
|
||||
qdel(stone)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/core/soul/proc/set_theme(new_theme)
|
||||
|
||||
@@ -339,7 +339,8 @@
|
||||
datum/reagent/source_reagent_typepath,
|
||||
datum/reagent/target_reagent_typepath,
|
||||
multiplier = 1,
|
||||
include_source_subtypes = FALSE
|
||||
include_source_subtypes = FALSE,
|
||||
keep_data = FALSE,
|
||||
)
|
||||
if(!ispath(source_reagent_typepath))
|
||||
stack_trace("invalid reagent path passed to convert reagent [source_reagent_typepath]")
|
||||
@@ -352,6 +353,8 @@
|
||||
var/weighted_purity = 0
|
||||
var/weighted_ph = 0
|
||||
var/reagent_volume = 0
|
||||
///Stores the data value of the reagent to be converted if keep_data is TRUE. Might not work well if include_source_subtypes is TRUE.
|
||||
var/list/reagent_data
|
||||
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/datum/reagent/cached_reagent as anything in cached_reagents)
|
||||
@@ -370,6 +373,8 @@
|
||||
|
||||
//zero the volume out so it gets removed
|
||||
cached_reagent.volume = 0
|
||||
if(keep_data)
|
||||
reagent_data = copy_data(cached_reagent)
|
||||
|
||||
//if we reached here means we have found our specific reagent type so break
|
||||
if(!include_source_subtypes)
|
||||
@@ -378,7 +383,14 @@
|
||||
//add the new target reagent with the averaged values from the source reagents
|
||||
if(weighted_volume > 0)
|
||||
update_total()
|
||||
add_reagent(target_reagent_typepath, weighted_volume * multiplier, reagtemp = chem_temp, added_purity = (weighted_purity / weighted_volume), added_ph = (weighted_ph / weighted_volume))
|
||||
add_reagent(
|
||||
target_reagent_typepath,
|
||||
weighted_volume * multiplier,
|
||||
data = reagent_data,
|
||||
reagtemp = chem_temp,
|
||||
added_purity = (weighted_purity / weighted_volume),
|
||||
added_ph = (weighted_ph / weighted_volume),
|
||||
)
|
||||
|
||||
/// Removes all reagents
|
||||
/datum/reagents/proc/clear_reagents()
|
||||
|
||||
@@ -342,3 +342,9 @@
|
||||
. = ..()
|
||||
if(!initial && (slot & ITEM_SLOT_HANDS) && reagent_container_liquid_sound && reagents.total_volume > 0)
|
||||
playsound(src, reagent_container_liquid_sound, LIQUID_SLOSHING_SOUND_VOLUME, vary = TRUE, ignore_walls = FALSE)
|
||||
|
||||
/obj/item/reagent_containers/used_in_craft(atom/result, datum/crafting_recipe/current_recipe)
|
||||
. = ..()
|
||||
// If consumed in crafting, we should dump contents out before qdeling them.
|
||||
if(!is_type_in_list(src, current_recipe.parts))
|
||||
reagents.expose(loc, TOUCH)
|
||||
|
||||
@@ -58,12 +58,9 @@
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/CheckParts(list/parts_list)
|
||||
/obj/item/reagent_containers/cup/glass/bottle/used_in_craft(atom/result, datum/crafting_recipe/current_recipe)
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in contents
|
||||
if(bottle.message_in_a_bottle)
|
||||
message_in_a_bottle = bottle.message_in_a_bottle
|
||||
bottle.message_in_a_bottle.forceMove(src)
|
||||
message_in_a_bottle?.forceMove(drop_location())
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -916,16 +913,16 @@
|
||||
/datum/reagent/toxin/spore_burning,
|
||||
)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/molotov/CheckParts(list/parts_list)
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in contents
|
||||
/obj/item/reagent_containers/cup/glass/bottle/molotov/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in components
|
||||
if(!bottle)
|
||||
return
|
||||
return ..()
|
||||
icon_state = bottle.icon_state
|
||||
bottle.reagents.copy_to(src, 100)
|
||||
if(istype(bottle, /obj/item/reagent_containers/cup/glass/bottle/juice))
|
||||
desc += " You're not sure if making this out of a carton was the brightest idea."
|
||||
isGlass = FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/molotov/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum, do_splash = FALSE)
|
||||
..(hit_atom, throwingdatum, do_splash = FALSE)
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
#include "confusion.dm"
|
||||
#include "connect_loc.dm"
|
||||
#include "container_sanity.dm"
|
||||
#include "crafting.dm"
|
||||
#include "crayons.dm"
|
||||
#include "create_and_destroy.dm"
|
||||
#include "damp_rag.dm"
|
||||
|
||||
199
code/modules/unit_tests/crafting.dm
Normal file
199
code/modules/unit_tests/crafting.dm
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* The accepted discrepancy between the amount of material between an item when crafted and the same item when spawned
|
||||
* so we don't have to be obnoxious about small portion of mats being lost for items that are processed in multiple other
|
||||
* results (eg. a slab of meat being cut in three cutlets, and each cutlet can be used to craft different things)
|
||||
* right now it's around 3 points per 100 units of a material.
|
||||
*/
|
||||
#define ACCEPTABLE_MATERIAL_DEVIATION 0.033
|
||||
|
||||
/**
|
||||
* Check if a generic atom (because both mobs and the crafter machinery can do it) can potentially craft all recipes,
|
||||
* with the exact same types required in the recipe, and also compare the materials of crafted result with one of the same type
|
||||
* to ansure they match if the recipe has the CRAFT_ENFORCE_MATERIALS_PARITY flag.
|
||||
*/
|
||||
/datum/unit_test/crafting
|
||||
|
||||
/datum/unit_test/crafting/Run()
|
||||
var/atom/movable/crafter = allocate(__IMPLIED_TYPE__)
|
||||
|
||||
///Clear the area around our crafting movable of objects that may mess with the unit test
|
||||
for(var/atom/movable/trash in (range(1, crafter) - crafter))
|
||||
qdel(trash)
|
||||
|
||||
var/turf/turf = crafter.loc
|
||||
var/old_turf_type = turf.type
|
||||
var/datum/component/personal_crafting/unit_test/craft_comp = crafter.AddComponent(__IMPLIED_TYPE__)
|
||||
var/obj/item/reagent_containers/cup/bottomless_cup = allocate_bottomless_cup()
|
||||
|
||||
var/list/tools = list()
|
||||
|
||||
var/list/all_recipes = GLOB.crafting_recipes + GLOB.cooking_recipes
|
||||
for(var/datum/crafting_recipe/recipe as anything in all_recipes)
|
||||
if(recipe.non_craftable)
|
||||
continue
|
||||
//split into a different proc, so if something fails it's both easier to track and doesn't halt the loop.
|
||||
process_recipe(crafter, craft_comp, recipe, bottomless_cup, tools)
|
||||
if(QDELETED(bottomless_cup) || bottomless_cup.loc != turf) //The cup itself was used in a recipe, rather than its contents.
|
||||
bottomless_cup = allocate_bottomless_cup()
|
||||
|
||||
// We have one or two recipes that generate turf (from stacks, like snow walls), which shouldn't be carried between tests
|
||||
if(turf.type != old_turf_type)
|
||||
turf.ChangeTurf(old_turf_type)
|
||||
|
||||
///Allocate a reagent container with infinite capacity and no reaction to use in crafting
|
||||
/datum/unit_test/crafting/proc/allocate_bottomless_cup()
|
||||
var/obj/item/reagent_containers/cup/bottomless_cup = allocate(__IMPLIED_TYPE__)
|
||||
bottomless_cup.reagents.flags |= NO_REACT|DRAINABLE
|
||||
bottomless_cup.reagents.maximum_volume = INFINITY
|
||||
return bottomless_cup
|
||||
|
||||
/datum/unit_test/crafting/proc/process_recipe(
|
||||
atom/crafter,
|
||||
datum/component/personal_crafting/unit_test/craft_comp,
|
||||
datum/crafting_recipe/recipe,
|
||||
obj/item/reagent_containers/bottomless_cup,
|
||||
list/tools
|
||||
)
|
||||
var/turf/turf = crafter.loc
|
||||
//Components that have to be deleted later so they don't mess up with other recipes
|
||||
var/list/spawned_components = list()
|
||||
//Warn if uncreatables were found in the recipe if it fails
|
||||
//If it doesn't fail, then it was already handled, maybe through `unit_test_spawn_extras`
|
||||
var/list/uncreatables_found
|
||||
|
||||
for(var/spawn_path in recipe.unit_test_spawn_extras)
|
||||
var/amount = recipe.unit_test_spawn_extras[spawn_path]
|
||||
if(ispath(spawn_path, /obj/item/stack))
|
||||
spawned_components += new spawn_path(turf, /*new_amount =*/ amount, /*merge =*/ FALSE)
|
||||
continue
|
||||
for(var/index in 1 to amount)
|
||||
spawned_components += new spawn_path(turf)
|
||||
|
||||
for(var/req_path in recipe.reqs) //spawn items and reagents
|
||||
var/amount = recipe.reqs[req_path]
|
||||
|
||||
if(ispath(req_path, /datum/reagent)) //it's a reagent
|
||||
if(!bottomless_cup.reagents.has_reagent(req_path, amount))
|
||||
bottomless_cup.reagents.add_reagent(req_path, amount + 1, no_react = TRUE)
|
||||
continue
|
||||
|
||||
if(req_path in uncreatables)
|
||||
LAZYADD(uncreatables_found, req_path)
|
||||
continue
|
||||
|
||||
if(ispath(req_path, /obj/item/stack)) //it's a stack
|
||||
spawned_components += new req_path(turf, /*new_amount =*/ amount, /*merge =*/ FALSE)
|
||||
continue
|
||||
|
||||
//it's any other item
|
||||
for(var/iteration in 1 to amount)
|
||||
spawned_components += new req_path(turf)
|
||||
|
||||
for(var/req_path in recipe.chem_catalysts) // spawn catalysts
|
||||
var/amount = recipe.chem_catalysts[req_path]
|
||||
if(!bottomless_cup.reagents.has_reagent(req_path, amount))
|
||||
bottomless_cup.reagents.add_reagent(req_path, amount + 1, no_react = TRUE)
|
||||
|
||||
var/list/bulky_objects = list()
|
||||
bulky_objects += recipe.structures + recipe.machinery //either structures and machinery could be null
|
||||
list_clear_nulls(bulky_objects) //so we clear the list
|
||||
for(var/req_path in bulky_objects) //spawn required machinery or structures
|
||||
if(req_path in uncreatables)
|
||||
LAZYADD(uncreatables_found, req_path)
|
||||
continue
|
||||
spawned_components += new req_path(turf)
|
||||
|
||||
var/list/needed_tools = list()
|
||||
needed_tools += recipe.tool_behaviors + recipe.tool_paths //either tool_behaviors and tool_paths could be null
|
||||
list_clear_nulls(needed_tools) //so we clear the list
|
||||
///tool instances which have been moved to the crafter loc, which are moved back to nullspace once the recipe is done
|
||||
var/list/summoned_tools = list()
|
||||
for(var/tooltype in needed_tools)
|
||||
var/obj/item/tool = tools[tooltype]
|
||||
if(!QDELETED(tool))
|
||||
tool.forceMove(turf)
|
||||
else
|
||||
var/is_behaviour = istext(tooltype)
|
||||
var/path_to_use = is_behaviour ? /obj/item : tooltype
|
||||
tool = allocate(path_to_use, turf) //we shouldn't delete the tools and allocate and keep them between recipes
|
||||
if(is_behaviour)
|
||||
tool.tool_behaviour = tooltype
|
||||
else if(tooltype in uncreatables)
|
||||
LAZYADD(uncreatables_found, tooltype)
|
||||
continue
|
||||
tools[tooltype] = tool
|
||||
summoned_tools |= tool
|
||||
|
||||
var/atom/result = craft_comp.construct_item(crafter, recipe)
|
||||
|
||||
for(var/atom/movable/tool as anything in summoned_tools)
|
||||
tool.moveToNullspace()
|
||||
|
||||
if(istext(result) || isnull(result)) //construct_item() returned a text string telling us why it failed.
|
||||
TEST_FAIL("[recipe.type] couldn't be crafted during unit test[result || ", result is null for some reason!"]")
|
||||
if(uncreatables_found)
|
||||
TEST_FAIL("The following objects that shouldn't initialize during unit tests were found in [recipe]: [english_list(uncreatables_found)]")
|
||||
delete_components(spawned_components)
|
||||
return
|
||||
//enforcing materials parity between crafted and spawned for turfs would be more trouble than worth right now
|
||||
if(isturf(result))
|
||||
delete_components(spawned_components)
|
||||
return
|
||||
|
||||
spawned_components += result
|
||||
|
||||
if(!(recipe.crafting_flags & CRAFT_ENFORCE_MATERIALS_PARITY))
|
||||
delete_components(spawned_components)
|
||||
return
|
||||
|
||||
var/atom/copycat = new result.type(turf)
|
||||
spawned_components += copycat
|
||||
|
||||
// SSmaterials caches the combinations so we don't have to run more complex checks
|
||||
if(result.custom_materials == copycat.custom_materials)
|
||||
delete_components(spawned_components)
|
||||
return
|
||||
var/comparison_failed = TRUE
|
||||
if(length(result.custom_materials) == length(copycat.custom_materials))
|
||||
comparison_failed = FALSE
|
||||
for(var/mat in result.custom_materials)
|
||||
var/enemy_amount = copycat.custom_materials[mat]
|
||||
if(!enemy_amount) //break the loop early, we cannot perform a division by zero anyway
|
||||
comparison_failed = TRUE
|
||||
break
|
||||
var/ratio_difference = abs((result.custom_materials[mat] / enemy_amount) - 1)
|
||||
if(ratio_difference > ACCEPTABLE_MATERIAL_DEVIATION)
|
||||
comparison_failed = TRUE
|
||||
if(comparison_failed)
|
||||
var/warning = "custom_materials of [result.type] when crafted and spawned don't match"
|
||||
var/what_it_should_be = "null"
|
||||
//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 = "\[list("
|
||||
var/index = 1
|
||||
var/mats_len = length(result.custom_materials)
|
||||
for(var/datum/material/mat as anything in result.custom_materials)
|
||||
what_it_should_be += "[mat.type] = [result.custom_materials[mat]]"
|
||||
if(index < mats_len)
|
||||
what_it_should_be += ", "
|
||||
index++
|
||||
what_it_should_be += ")\] (you can round values a bit)"
|
||||
TEST_FAIL("[warning]. custom_materials should be [what_it_should_be]. \
|
||||
Otherwise set the requirements_mats_blacklist variable for [recipe] \
|
||||
or remove the CRAFT_ENFORCE_MATERIALS_PARITY crafting flag from it")
|
||||
|
||||
delete_components(spawned_components)
|
||||
|
||||
/**
|
||||
* Clear the area of the components that have been spawned as either the requirements of a recipe or its result
|
||||
* so they don't mess up with recipes that come after it.
|
||||
*/
|
||||
/datum/unit_test/crafting/proc/delete_components(list/comps)
|
||||
for(var/atom/movable/used as anything in comps)
|
||||
if(!QDELETED(used))
|
||||
qdel(used)
|
||||
|
||||
/datum/component/personal_crafting/unit_test
|
||||
ignored_flags = CRAFT_MUST_BE_LEARNED|CRAFT_ONE_PER_TURF|CRAFT_CHECK_DIRECTION|CRAFT_CHECK_DENSITY|CRAFT_ON_SOLID_GROUND|CRAFT_IGNORE_DO_AFTER
|
||||
|
||||
#undef ACCEPTABLE_MATERIAL_DEVIATION
|
||||
@@ -317,8 +317,7 @@
|
||||
servo = new /obj/item/stock_parts/servo(src)
|
||||
update_part_values()
|
||||
|
||||
/obj/vehicle/sealed/mecha/CheckParts(list/parts_list)
|
||||
. = ..()
|
||||
/obj/vehicle/sealed/mecha/proc/locate_parts()
|
||||
cell = locate(/obj/item/stock_parts/power_store) in contents
|
||||
diag_hud_set_mechcell()
|
||||
scanmod = locate(/obj/item/stock_parts/scanning_module) in contents
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user