diff --git a/code/__DEFINES/construction/material.dm b/code/__DEFINES/construction/material.dm index 57d55ab8042..2764c0bbfaf 100644 --- a/code/__DEFINES/construction/material.dm +++ b/code/__DEFINES/construction/material.dm @@ -21,6 +21,14 @@ #define MAT_CATEGORY_RIGID "rigid material" /// Materials that can be used to craft items #define MAT_CATEGORY_ITEM_MATERIAL "item material" +/** + * Materials that can also be used to craft items for designs that require two custom mats. + * This is mainly a work around to the fact we can't (easily) have the same category show + * multiple times in a list with different values, because list access operator [] will fetch the + * top-most value. + */ +#define MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY "item material complementary" + /// Use this flag on TRUE if you want the basic recipes #define MAT_CATEGORY_BASE_RECIPES "basic recipes" @@ -87,3 +95,10 @@ #define MATERIAL_RARITY_RARE 3 /// Is this material only going to spawn once in ore vents? (6% of vents on lavaland) #define MATERIAL_RARITY_UNDISCOVERED 1 + +///The key to access the 'optimal' amount of a material key from its assoc value list. +#define MATERIAL_LIST_OPTIMAL_AMOUNT "optimal_amount" +///The key to access the multiplier used to selectively control effects and modifiers of a material. +#define MATERIAL_LIST_MULTIPLIER "multiplier" +///A macro that ensures some multiplicative modifiers higher than 1 don't become lower than 1 and viceversa because of the multiplier. +#define GET_MATERIAL_MODIFIER(modifier, multiplier) (modifier >= 1 ? 1 + ((modifier) - 1) * (multiplier) : (modifier)**(multiplier)) diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index 673414ea3c2..f5af2853b94 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -148,7 +148,7 @@ SUBSYSTEM_DEF(materials) /// Returns a list to be used as an object's custom_materials. Lists will be cached and re-used based on the parameters. -/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier) +/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier = 1) if(!LAZYLEN(materials_declaration)) return null // If we get a null we pass it right back, we don't want to generate stack traces just because something is clearing out its materials list. diff --git a/code/datums/components/material/material_container.dm b/code/datums/components/material/material_container.dm index 10544116ce5..912ae334116 100644 --- a/code/datums/components/material/material_container.dm +++ b/code/datums/components/material/material_container.dm @@ -725,7 +725,7 @@ "name" = material.name, "ref" = REF(material), "amount" = amount, - "color" = material.greyscale_colors + "color" = material.greyscale_color || material.color )) return data diff --git a/code/datums/greyscale/_greyscale_config.dm b/code/datums/greyscale/_greyscale_config.dm index 69f104d2f91..b922d2697d5 100644 --- a/code/datums/greyscale/_greyscale_config.dm +++ b/code/datums/greyscale/_greyscale_config.dm @@ -257,7 +257,7 @@ /datum/greyscale_config/proc/GenerateBundle(list/colors, list/render_steps, icon/last_external_icon) if(!istype(colors)) colors = SSgreyscale.ParseColorString(colors) - if(length(colors) != expected_colors) + if(length(colors) < expected_colors) CRASH("[DebugName()] expected [expected_colors] color arguments but only received [length(colors)]") var/list/generated_icons = list() diff --git a/code/datums/greyscale/json_configs/items/cleric_mace.json b/code/datums/greyscale/json_configs/items/cleric_mace.json index 781c790ea6a..5197ebc45a2 100644 --- a/code/datums/greyscale/json_configs/items/cleric_mace.json +++ b/code/datums/greyscale/json_configs/items/cleric_mace.json @@ -9,7 +9,8 @@ { "type": "icon_state", "icon_state": "handle", - "blend_mode": "overlay" + "blend_mode": "overlay", + "color_ids": [ 2 ] } ], "default_worn": [ @@ -22,7 +23,8 @@ { "type": "icon_state", "icon_state": "worn_handle", - "blend_mode": "overlay" + "blend_mode": "overlay", + "color_ids": [ 2 ] } ] } diff --git a/code/datums/greyscale/json_configs/items/cleric_mace_worn.json b/code/datums/greyscale/json_configs/items/cleric_mace_worn.json index c49a829aa2c..5725cfa689a 100644 --- a/code/datums/greyscale/json_configs/items/cleric_mace_worn.json +++ b/code/datums/greyscale/json_configs/items/cleric_mace_worn.json @@ -9,7 +9,8 @@ { "type": "icon_state", "icon_state": "worn_handle", - "blend_mode": "overlay" + "blend_mode": "overlay", + "color_ids": [ 2 ] } ] } diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 5dc8c26d0f6..cff0ea0e6d1 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -13,12 +13,20 @@ Simple datum which is instanced once per type and is used for every object of sa /// What the material is indexed by in the SSmaterials.materials list. Defaults to the type of the material. var/id - ///Base color of the material, is used for greyscale. Item isn't changed in color if this is null. - ///Deprecated, use greyscale_color instead. + /** + * Base color of the material, for items that don't have greyscale configs nor are made of multiple materials. Item isn't changed in color if this is null. + * This can be a RGB or color matrix, but it cannot be RGBA as alpha is automatically filled in. + */ var/color - ///Determines the color palette of the material. Formatted the same as atom/var/greyscale_colors - var/greyscale_colors - ///Base alpha of the material, is used for greyscale icons. + /** + * If the color is a color matrix and either the item uses greyscale configs or is made of multiple colored materials. This will be used instead because + * neither greyscale configs nor BlendRGB() support color matrices. + * Also this has to be RRGGBB, six characters, no alpha channel as it's automatically filled in. + * + * Basically, set this if the color is a color matrix (list) + */ + var/greyscale_color + /// Base alpha of the material var/alpha = 255 ///Starlight color of the material ///This is the color of light it'll emit if its turf is transparent and over space. Defaults to COLOR_STARLIGHT if not set @@ -67,6 +75,8 @@ Simple datum which is instanced once per type and is used for every object of sa var/mineral_rarity = MATERIAL_RARITY_COMMON /// How many points per units of ore does this grant? var/points_per_unit = 1 + /// The slowdown that is added to items. + var/added_slowdown = 0 /** Handles initializing the material. * @@ -85,84 +95,11 @@ Simple datum which is instanced once per type and is used for every object of sa return TRUE ///This proc is called when the material is added to an object. -/datum/material/proc/on_applied(atom/source, amount, material_flags) - if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example - if(color) //Do we have a custom color? - source.add_atom_colour(color, FIXED_COLOUR_PRIORITY) - if(alpha) - source.alpha = alpha - if(texture_layer_icon_state) - ADD_KEEP_TOGETHER(source, MATERIAL_SOURCE(src)) - source.add_filter("material_texture_[name]",1,layering_filter(icon=cached_texture_filter_icon,blend_mode=BLEND_INSET_OVERLAY)) - - if(material_flags & MATERIAL_GREYSCALE) - var/config_path = get_greyscale_config_for(source.greyscale_config) - source.set_greyscale(greyscale_colors, config_path) - - if(alpha < 255) - source.opacity = FALSE - if(material_flags & MATERIAL_ADD_PREFIX) - source.name = "[name] [source.name]" - - if(beauty_modifier) - source.AddElement(/datum/element/beauty, beauty_modifier * amount) - - if(isobj(source)) //objs - on_applied_obj(source, amount, material_flags) - - else if(istype(source, /turf)) //turfs - on_applied_turf(source, amount, material_flags) - - source.mat_update_desc(src) - -///This proc is called when a material updates an object's description -/atom/proc/mat_update_desc(datum/material/mat) +/datum/material/proc/on_applied(atom/source, mat_amount, multiplier) return -///This proc is called when the material is added to an object specifically. -/datum/material/proc/on_applied_obj(obj/o, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) - var/new_max_integrity = CEILING(o.max_integrity * integrity_modifier, 1) - o.modify_max_integrity(new_max_integrity) - o.force *= strength_modifier - o.throwforce *= strength_modifier - o.set_armor(o.get_armor().generate_new_with_multipliers(armor_modifiers)) - - if(!isitem(o)) - return - var/obj/item/item = o - - if(material_flags & MATERIAL_GREYSCALE) - var/worn_path = get_greyscale_config_for(item.greyscale_config_worn) - var/lefthand_path = get_greyscale_config_for(item.greyscale_config_inhand_left) - var/righthand_path = get_greyscale_config_for(item.greyscale_config_inhand_right) - item.set_greyscale( - new_worn_config = worn_path, - new_inhand_left = lefthand_path, - new_inhand_right = righthand_path - ) - - if(!item_sound_override) - return - item.hitsound = item_sound_override - item.usesound = item_sound_override - item.mob_throw_hit_sound = item_sound_override - item.equip_sound = item_sound_override - item.pickup_sound = item_sound_override - item.drop_sound = item_sound_override - -/datum/material/proc/on_applied_turf(turf/T, amount, material_flags) - if(isopenturf(T)) - if(turf_sound_override) - var/turf/open/O = T - O.footstep = turf_sound_override - O.barefootstep = turf_sound_override + "barefoot" - O.clawfootstep = turf_sound_override + "claw" - O.heavyfootstep = FOOTSTEP_GENERIC_HEAVY - if(alpha < 255) - T.AddElement(/datum/element/turf_z_transparency) - setup_glow(T) - T.rust_resistance = mat_rust_resistance +///This proc is called when the material becomes the one the object is composed of the most +/datum/material/proc/on_main_applied(atom/source, mat_amount, multiplier) return /datum/material/proc/setup_glow(turf/on) @@ -183,61 +120,13 @@ Simple datum which is instanced once per type and is used for every object of sa /datum/material/proc/lit_turf_deleted(turf/source) source.set_light(0, 0, null) -/datum/material/proc/get_greyscale_config_for(datum/greyscale_config/config_path) - if(!config_path) - return - for(var/datum/greyscale_config/path as anything in subtypesof(config_path)) - if(type != initial(path.material_skin)) - continue - return path - ///This proc is called when the material is removed from an object. /datum/material/proc/on_removed(atom/source, amount, material_flags) - if(material_flags & MATERIAL_COLOR) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example - if(color) - source.remove_atom_colour(FIXED_COLOUR_PRIORITY, color) - if(texture_layer_icon_state) - source.remove_filter("material_texture_[name]") - REMOVE_KEEP_TOGETHER(source, MATERIAL_SOURCE(src)) - source.alpha = initial(source.alpha) + return - if(material_flags & MATERIAL_GREYSCALE) - source.set_greyscale(initial(source.greyscale_colors), initial(source.greyscale_config)) - - if(material_flags & MATERIAL_ADD_PREFIX) - source.name = initial(source.name) - - if(beauty_modifier) - source.RemoveElement(/datum/element/beauty, beauty_modifier * amount) - - if(isobj(source)) //objs - on_removed_obj(source, amount, material_flags) - - if(istype(source, /turf)) //turfs - on_removed_turf(source, amount, material_flags) - -///This proc is called when the material is removed from an object specifically. -/datum/material/proc/on_removed_obj(obj/o, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) - var/new_max_integrity = initial(o.max_integrity) - o.modify_max_integrity(new_max_integrity) - o.force = initial(o.force) - o.throwforce = initial(o.throwforce) - - if(isitem(o) && (material_flags & MATERIAL_GREYSCALE)) - var/obj/item/item = o - item.set_greyscale( - new_worn_config = initial(item.greyscale_config_worn), - new_inhand_left = initial(item.greyscale_config_inhand_left), - new_inhand_right = initial(item.greyscale_config_inhand_right) - ) - -/datum/material/proc/on_removed_turf(turf/T, amount, material_flags) - if(alpha < 255) - T.RemoveElement(/datum/element/turf_z_transparency) - // yeets glow - T.UnregisterSignal(SSdcs, COMSIG_STARLIGHT_COLOR_CHANGED) - T.set_light(0, 0, null) +///This proc is called when the material is no longer the one the object is composed by the most +/datum/material/proc/on_main_removed(atom/source, mat_amount, multiplier) + 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. @@ -258,3 +147,11 @@ Simple datum which is instanced once per type and is used for every object of sa /datum/material/proc/return_composition(amount = 1) // Yes we need the parenthesis, without them BYOND stringifies src into "src" and things break. return list((src) = amount) + +///Returns the list of armor modifiers, with each element having its assoc value multiplied by the multiplier arg +/datum/material/proc/get_armor_modifiers(multiplier) + SHOULD_NOT_OVERRIDE(TRUE) + var/list/return_list = list() + for(var/armor in armor_modifiers) + return_list[armor] = return_list[armor] * multiplier + return return_list diff --git a/code/datums/materials/alloys.dm b/code/datums/materials/alloys.dm index 8bfdf0b58d9..d13a88c49c3 100644 --- a/code/datums/materials/alloys.dm +++ b/code/datums/materials/alloys.dm @@ -27,31 +27,21 @@ name = "plasteel" desc = "The heavy duty result of infusing iron with plasma." color = "#706374" - greyscale_colors = "#706374" init_flags = MATERIAL_INIT_MAPLOAD value_per_unit = 0.135 strength_modifier = 1.25 integrity_modifier = 1.5 // Heavy duty. armor_modifiers = list(MELEE = 1.4, BULLET = 1.4, LASER = 1.1, ENERGY = 1.1, BOMB = 1.5, BIO = 1, FIRE = 1.1, ACID = 1) sheet_type = /obj/item/stack/sheet/plasteel - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/iron=1, /datum/material/plasma=1) mat_rust_resistance = RUST_RESISTANCE_REINFORCED - -/datum/material/alloy/plasteel/on_applied_obj(obj/item/target_item, amount, material_flags) - . = ..() - if(!istype(target_item)) - return - - target_item.slowdown += MATERIAL_SLOWDOWN_PLASTEEL * amount / SHEET_MATERIAL_AMOUNT - -/datum/material/alloy/plasteel/on_removed_obj(obj/item/target_item, amount, material_flags) - . = ..() - - if(!istype(target_item)) - return - - target_item.slowdown -= MATERIAL_SLOWDOWN_PLASTEEL * amount / SHEET_MATERIAL_AMOUNT + added_slowdown = 0.05 /** Plastitanium * @@ -61,14 +51,18 @@ name = "plastitanium" desc = "The extremely heat resistant result of infusing titanium with plasma." color = "#3a313a" - greyscale_colors = "#3a313a" init_flags = MATERIAL_INIT_MAPLOAD value_per_unit = 0.225 strength_modifier = 0.9 // It's a lightweight alloy. integrity_modifier = 1.3 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.4, ENERGY = 1.4, BOMB = 1.1, BIO = 1.2, FIRE = 1.5, ACID = 1) sheet_type = /obj/item/stack/sheet/mineral/plastitanium - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/titanium=1, /datum/material/plasma=1) mat_rust_resistance = RUST_RESISTANCE_TITANIUM @@ -80,7 +74,6 @@ name = "plasmaglass" desc = "Plasma-infused silicate. It is much more durable and heat resistant than either of its component materials." color = "#ff80f4" - greyscale_colors = "#ff80f496" alpha = 150 starlight_color = COLOR_STRONG_MAGENTA init_flags = MATERIAL_INIT_MAPLOAD @@ -90,7 +83,12 @@ shard_type = /obj/item/shard/plasma debris_type = /obj/effect/decal/cleanable/glass/plasma value_per_unit = 0.075 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/glass=1, /datum/material/plasma=0.5) /** Titaniumglass @@ -101,7 +99,6 @@ name = "titanium glass" desc = "A specialized silicate-titanium alloy that is commonly used in shuttle windows." color = "#cfbee0" - greyscale_colors = "#cfbee096" alpha = 150 starlight_color = COLOR_COMMAND_BLUE init_flags = MATERIAL_INIT_MAPLOAD @@ -110,7 +107,12 @@ shard_type = /obj/item/shard/titanium debris_type = /obj/effect/decal/cleanable/glass/titanium value_per_unit = 0.04 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/glass=1, /datum/material/titanium=0.5) /** Plastitanium Glass @@ -121,7 +123,6 @@ name = "plastitanium glass" desc = "A specialized silicate-plastitanium alloy." color = "#5d3369" - greyscale_colors = "#5d336996" starlight_color = COLOR_CENTCOM_BLUE alpha = 150 init_flags = MATERIAL_INIT_MAPLOAD @@ -131,7 +132,12 @@ shard_type = /obj/item/shard/plastitanium debris_type = /obj/effect/decal/cleanable/glass/plastitanium value_per_unit = 0.125 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/glass=1, /datum/material/alloy/plastitanium=0.5) /** Alien Alloy @@ -144,30 +150,27 @@ name = "alien alloy" desc = "An extremely dense alloy similar to plasteel in composition. It requires exotic metallurgical processes to create." color = "#6041aa" - greyscale_colors = "#6041aa" init_flags = MATERIAL_INIT_MAPLOAD strength_modifier = 1.5 // It's twice the density of plasteel and just as durable. Getting hit with it is going to HURT. integrity_modifier = 1.5 armor_modifiers = list(MELEE = 1.4, BULLET = 1.4, LASER = 1.2, ENERGY = 1.2, BOMB = 1.5, BIO = 1.2, FIRE = 1.2, ACID = 1.2) sheet_type = /obj/item/stack/sheet/mineral/abductor value_per_unit = 0.4 - categories = list(MAT_CATEGORY_RIGID=TRUE, MAT_CATEGORY_BASE_RECIPES=TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) composition = list(/datum/material/iron=2, /datum/material/plasma=2) + added_slowdown = 0.1 -/datum/material/alloy/alien/on_applied_obj(obj/item/target_item, amount, material_flags) +/datum/material/alloy/alien/on_applied(atom/target, mat_amount, multiplier) . = ..() + if(isobj(target)) + target.AddElement(/datum/element/obj_regen, _rate=0.02) // 2% regen per tick. - target_item.AddElement(/datum/element/obj_regen, _rate=0.02) // 2% regen per tick. - if(!istype(target_item)) - return - - target_item.slowdown += MATERIAL_SLOWDOWN_ALIEN_ALLOY * amount / SHEET_MATERIAL_AMOUNT - -/datum/material/alloy/alien/on_removed_obj(obj/item/target_item, amount, material_flags) +/datum/material/alloy/alien/on_removed(atom/target, mat_amount, multiplier) . = ..() - - target_item.RemoveElement(/datum/element/obj_regen, _rate=0.02) - if(!istype(target_item)) - return - - target_item.slowdown -= MATERIAL_SLOWDOWN_ALIEN_ALLOY * amount / SHEET_MATERIAL_AMOUNT + if(isobj(target)) + target.RemoveElement(/datum/element/obj_regen, _rate=0.02) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 66f4bccbd6f..76d44c1f164 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -3,8 +3,13 @@ name = "iron" desc = "Common iron ore often found in sedimentary and igneous layers of the crust." color = "#B6BEC2" - greyscale_colors = "#B6BEC2" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/iron ore_type = /obj/item/stack/ore/iron value_per_unit = 5 / SHEET_MATERIAL_AMOUNT @@ -24,9 +29,14 @@ name = "glass" desc = "Glass forged by melting sand." color = "#6292AF" - greyscale_colors = "#6292AF" alpha = 150 - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) integrity_modifier = 0.1 sheet_type = /obj/item/stack/sheet/glass ore_type = /obj/item/stack/ore/glass/basalt @@ -46,15 +56,15 @@ victim.apply_damage(10, BRUTE, BODY_ZONE_HEAD, wound_bonus = 5, sharpness = TRUE) //cronch return TRUE -/datum/material/glass/on_applied_obj(atom/source, amount, material_flags) +/datum/material/glass/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(!isstack(source)) - source.AddElement(/datum/element/can_shatter, shard_type, round(amount / SHEET_MATERIAL_AMOUNT), SFX_SHATTER) + if(isobj(source) && !isstack(source)) + source.AddElement(/datum/element/can_shatter, shard_type, round(mat_amount / SHEET_MATERIAL_AMOUNT * multiplier), SFX_SHATTER) -/datum/material/glass/on_removed(atom/source, amount, material_flags) +/datum/material/glass/on_main_removed(atom/source, mat_amount, multiplier) . = ..() - - source.RemoveElement(/datum/element/can_shatter, shard_type) + if(isobj(source) && !isstack(source)) + source.RemoveElement(/datum/element/can_shatter, shard_type, round(mat_amount / SHEET_MATERIAL_AMOUNT * multiplier), SFX_SHATTER) /* Color matrices are like regular colors but unlike with normal colors, you can go over 255 on a channel. @@ -66,8 +76,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "silver" desc = "Silver" color = "#B5BCBB" - greyscale_colors = "#B5BCBB" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/silver ore_type = /obj/item/stack/ore/silver value_per_unit = 50 / SHEET_MATERIAL_AMOUNT @@ -87,9 +102,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "gold" desc = "Gold" color = "#E6BB45" - greyscale_colors = "#E6BB45" strength_modifier = 1.2 - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/gold ore_type = /obj/item/stack/ore/gold value_per_unit = 125 / SHEET_MATERIAL_AMOUNT @@ -110,8 +130,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "diamond" desc = "Highly pressurized carbon" color = "#C9D8F2" - greyscale_colors = "#C9D8F2" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/diamond ore_type = /obj/item/stack/ore/diamond alpha = 132 @@ -133,8 +158,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "uranium" desc = "Uranium" color = "#2C992C" - greyscale_colors = "#2C992C" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/uranium ore_type = /obj/item/stack/ore/uranium value_per_unit = 100 / SHEET_MATERIAL_AMOUNT @@ -145,7 +175,7 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_SEMIPRECIOUS points_per_unit = 30 / SHEET_MATERIAL_AMOUNT -/datum/material/uranium/on_applied(atom/source, amount, material_flags) +/datum/material/uranium/on_applied(atom/source, mat_amount, multiplier) . = ..() // Uranium structures should irradiate, but not items, because item irradiation is a lot more annoying. @@ -153,15 +183,15 @@ Unless you know what you're doing, only use the first three numbers. They're in if (isitem(source)) return - source.AddElement(/datum/element/radioactive) + source.AddElement(/datum/element/radioactive, chance = URANIUM_IRRADIATION_CHANCE * multiplier) -/datum/material/uranium/on_removed(atom/source, amount, material_flags) +/datum/material/uranium/on_removed(atom/source, mat_amount, multiplier) . = ..() if (isitem(source)) return - source.RemoveElement(/datum/element/radioactive) + source.RemoveElement(/datum/element/radioactive, chance = URANIUM_IRRADIATION_CHANCE * multiplier) /datum/material/uranium/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) victim.reagents.add_reagent(/datum/reagent/uranium, rand(4, 6)) @@ -173,8 +203,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "plasma" desc = "Isn't plasma a state of matter? Oh whatever." color = "#BA3692" - greyscale_colors = "#BA3692" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/plasma ore_type = /obj/item/stack/ore/plasma value_per_unit = 200 / SHEET_MATERIAL_AMOUNT @@ -183,15 +218,15 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_PRECIOUS points_per_unit = 15 / SHEET_MATERIAL_AMOUNT -/datum/material/plasma/on_applied(atom/source, amount, material_flags) +/datum/material/plasma/on_applied(atom/source, mat_amount, multiplier) . = ..() if(ismovable(source)) - source.AddElement(/datum/element/firestacker, amount=1) - source.AddComponent(/datum/component/combustible_flooder, "plasma", amount*0.05) //Empty temp arg, fully dependent on whatever ignited it. + source.AddElement(/datum/element/firestacker, 1 * multiplier) + source.AddComponent(/datum/component/combustible_flooder, "plasma", mat_amount * 0.05 * multiplier) //Empty temp arg, fully dependent on whatever ignited it. -/datum/material/plasma/on_removed(atom/source, amount, material_flags) +/datum/material/plasma/on_removed(atom/source, mat_amount, multiplier) . = ..() - source.RemoveElement(/datum/element/firestacker, amount=1) + source.RemoveElement(/datum/element/firestacker, mat_amount = 1 * multiplier) qdel(source.GetComponent(/datum/component/combustible_flooder)) qdel(source.GetComponent(/datum/component/explodable)) @@ -205,10 +240,15 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bluespace crystal" desc = "Crystals with bluespace properties" color = "#2E50B7" - greyscale_colors = "#2E50B7" alpha = 200 starlight_color = COLOR_BLUE - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_ITEM_MATERIAL = TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) beauty_modifier = 0.5 sheet_type = /obj/item/stack/sheet/bluespace_crystal ore_type = /obj/item/stack/ore/bluespace_crystal @@ -229,8 +269,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bananium" desc = "Material with hilarious properties" color = list(460/255, 464/255, 0, 0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //obnoxiously bright yellow //It's literally perfect I can't change it - greyscale_colors = "#FFF269" - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + greyscale_color = "#FFF269" + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/bananium ore_type = /obj/item/stack/ore/bananium value_per_unit = 1000 / SHEET_MATERIAL_AMOUNT @@ -239,12 +285,12 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_UNDISCOVERED points_per_unit = 60 / SHEET_MATERIAL_AMOUNT -/datum/material/bananium/on_applied(atom/source, amount, material_flags) +/datum/material/bananium/on_applied(atom/source, mat_amount, multiplier) . = ..() - source.LoadComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50, falloff_exponent = 20) - source.AddComponent(/datum/component/slippery, min(amount / 10, 80)) + source.LoadComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50 * multiplier, falloff_exponent = 20) + source.AddComponent(/datum/component/slippery, min(mat_amount / 10 * multiplier, 80 * multiplier)) -/datum/material/bananium/on_removed(atom/source, amount, material_flags) +/datum/material/bananium/on_removed(atom/source, mat_amount, multiplier) . = ..() qdel(source.GetComponent(/datum/component/slippery)) qdel(source.GetComponent(/datum/component/squeak)) @@ -259,9 +305,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "titanium" desc = "Titanium" color = "#EFEFEF" - greyscale_colors = "#EFEFEF" strength_modifier = 1.3 - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/titanium ore_type = /obj/item/stack/ore/titanium value_per_unit = 125 / SHEET_MATERIAL_AMOUNT @@ -281,9 +332,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "runite" desc = "Runite" color = "#526F77" - greyscale_colors = "#526F77" strength_modifier = 1.3 - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/runite value_per_unit = 600 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.5 @@ -300,11 +355,16 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "plastic" desc = "Plastic" color = "#BFB9AC" - greyscale_colors = "#BFB9AC" strength_modifier = 0.85 sheet_type = /obj/item/stack/sheet/plastic ore_type = /obj/item/stack/ore/slag //No plastic or coal ore, so we use slag. - categories = list(MAT_CATEGORY_SILO = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_SILO = TRUE, + MAT_CATEGORY_RIGID=TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) value_per_unit = 25 / SHEET_MATERIAL_AMOUNT beauty_modifier = -0.01 armor_modifiers = list(MELEE = 1.5, BULLET = 1.1, LASER = 0.3, ENERGY = 0.5, BOMB = 1, BIO = 1, FIRE = 1.1, ACID = 1) @@ -319,9 +379,8 @@ Unless you know what you're doing, only use the first three numbers. They're in ///Force decrease and mushy sound effect. (Not yet implemented) /datum/material/biomass name = "biomass" - desc = "Organic matter" + desc = "Organic matter." color = "#735b4d" - greyscale_colors = "#735b4d" strength_modifier = 0.8 value_per_unit = 50 / SHEET_MATERIAL_AMOUNT @@ -329,24 +388,28 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "wood" desc = "Flexible, durable, but flamable. Hard to come across in space." color = "#855932" - greyscale_colors = "#855932" strength_modifier = 0.5 sheet_type = /obj/item/stack/sheet/mineral/wood - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) value_per_unit = 20 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.1 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 0.4, ENERGY = 0.4, BOMB = 1, BIO = 0.2, ACID = 0.3) texture_layer_icon_state = "woodgrain" -/datum/material/wood/on_applied_obj(obj/source, amount, material_flags) +/datum/material/wood/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(source.material_flags & MATERIAL_AFFECT_STATISTICS && isobj(source)) var/obj/wooden = source wooden.resistance_flags |= FLAMMABLE -/datum/material/wood/on_removed_obj(obj/source, amount, material_flags) +/datum/material/wood/on_main_removed(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(source.material_flags & MATERIAL_AFFECT_STATISTICS && isobj(source)) var/obj/wooden = source wooden.resistance_flags &= ~FLAMMABLE @@ -362,9 +425,13 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "adamantine" desc = "A powerful material made out of magic, I mean science!" color = "#2B7A74" - greyscale_colors = "#2B7A74" strength_modifier = 1.5 - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/adamantine value_per_unit = 500 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.4 @@ -381,8 +448,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "mythril" desc = "How this even exists is byond me" color = "#f2d5d7" - greyscale_colors = "#f2d5d7" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/mythril value_per_unit = 1500 / SHEET_MATERIAL_AMOUNT strength_modifier = 1.2 @@ -391,13 +462,13 @@ Unless you know what you're doing, only use the first three numbers. They're in mineral_rarity = MATERIAL_RARITY_UNDISCOVERED //Doesn't naturally spawn on lavaland. points_per_unit = 100 / SHEET_MATERIAL_AMOUNT -/datum/material/mythril/on_applied_obj(atom/source, amount, material_flags) +/datum/material/mythril/on_applied(atom/source, mat_amount, multiplier) . = ..() if(isitem(source)) source.AddComponent(/datum/component/fantasy) ADD_TRAIT(source, TRAIT_INNATELY_FANTASTICAL_ITEM, REF(src)) // DO THIS LAST OR WE WILL NEVER GET OUR BONUSES!!! -/datum/material/mythril/on_removed_obj(atom/source, amount, material_flags) +/datum/material/mythril/on_removed(atom/source, mat_amount, multiplier) . = ..() if(isitem(source)) REMOVE_TRAIT(source, TRAIT_INNATELY_FANTASTICAL_ITEM, REF(src)) // DO THIS FIRST OR WE WILL NEVER GET OUR BONUSES DELETED!!! @@ -412,19 +483,23 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "hot ice" desc = "A weird kind of ice, feels warm to the touch" color = "#88cdf1" - greyscale_colors = "#88cdf196" alpha = 150 starlight_color = COLOR_BLUE_LIGHT - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/hot_ice value_per_unit = 400 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.2 -/datum/material/hot_ice/on_applied(atom/source, amount, material_flags) +/datum/material/hot_ice/on_applied(atom/source, mat_amount, multiplier) . = ..() - source.AddComponent(/datum/component/combustible_flooder, "plasma", amount*1.5, amount*0.2+300) + source.AddComponent(/datum/component/combustible_flooder, "plasma", mat_amount * 1.5 * multiplier, (mat_amount * 0.2 + 300) * multiplier) -/datum/material/hot_ice/on_removed(atom/source, amount, material_flags) +/datum/material/hot_ice/on_removed(atom/source, mat_amount, multiplier) qdel(source.GetComponent(/datum/component/combustible_flooder)) return ..() @@ -438,10 +513,14 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "Metal Hydrogen" desc = "Solid metallic hydrogen. Some say it should be impossible" color = "#62708A" - greyscale_colors = "#62708A" alpha = 150 starlight_color = COLOR_MODERATE_BLUE - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/metal_hydrogen value_per_unit = 700 / SHEET_MATERIAL_AMOUNT beauty_modifier = 0.35 @@ -457,8 +536,11 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "sand" desc = "You know, it's amazing just how structurally sound sand can be." color = "#EDC9AF" - greyscale_colors = "#EDC9AF" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/sandblock value_per_unit = 2 / SHEET_MATERIAL_AMOUNT strength_modifier = 0.5 @@ -477,8 +559,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "sandstone" desc = "Bialtaakid 'ant taerif ma hdha." color = "#ECD5A8" - greyscale_colors = "#ECD5A8" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/sandstone value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 1.25, ENERGY = 0.5, BOMB = 0.5, BIO = 0.25, FIRE = 1.5, ACID = 1.5) @@ -490,8 +576,11 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "snow" desc = "There's no business like snow business." color = COLOR_WHITE - greyscale_colors = COLOR_WHITE - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/snow value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, FIRE = 0.25, ACID = 1.5) @@ -507,8 +596,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "runed metal" desc = "Mir'ntrath barhah Nar'sie." color = "#504742" - greyscale_colors = "#504742" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/runed_metal value_per_unit = 1500 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 1.2, BULLET = 1.2, LASER = 1, ENERGY = 1, BOMB = 1.2, BIO = 1.2, FIRE = 1.5, ACID = 1.5) @@ -524,8 +617,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bronze" desc = "Clock Cult? Never heard of it." color = "#876223" - greyscale_colors = "#876223" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/bronze value_per_unit = 50 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, FIRE = 1.5, ACID = 1.5) @@ -535,8 +632,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "paper" desc = "Ten thousand folds of pure starchy power." color = "#E5DCD5" - greyscale_colors = "#E5DCD5" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/paperframes value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.1, BULLET = 0.1, LASER = 0.1, ENERGY = 0.1, BOMB = 0.1, BIO = 0.1, ACID = 1.5) @@ -544,15 +645,15 @@ Unless you know what you're doing, only use the first three numbers. They're in turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "paper" -/datum/material/paper/on_applied_obj(obj/source, amount, material_flags) +/datum/material/paper/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/paper = source paper.resistance_flags |= FLAMMABLE paper.obj_flags |= UNIQUE_RENAME -/datum/material/paper/on_removed_obj(obj/source, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) +/datum/material/paper/on_main_removed(atom/source, mat_amount, multiplier) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/paper = source paper.resistance_flags &= ~FLAMMABLE return ..() @@ -561,22 +662,26 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "cardboard" desc = "They say cardboard is used by hobos to make incredible things." color = "#5F625C" - greyscale_colors = "#5F625C" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/cardboard value_per_unit = 6 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, ACID = 1.5) beauty_modifier = -0.1 -/datum/material/cardboard/on_applied_obj(obj/source, amount, material_flags) +/datum/material/cardboard/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - if(material_flags & MATERIAL_AFFECT_STATISTICS) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/cardboard = source cardboard.resistance_flags |= FLAMMABLE cardboard.obj_flags |= UNIQUE_RENAME -/datum/material/cardboard/on_removed_obj(obj/source, amount, material_flags) - if(material_flags & MATERIAL_AFFECT_STATISTICS) +/datum/material/cardboard/on_main_removed(atom/source, mat_amount, multiplier) + if(isobj(source) && source.material_flags & MATERIAL_AFFECT_STATISTICS) var/obj/cardboard = source cardboard.resistance_flags &= ~FLAMMABLE return ..() @@ -585,8 +690,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bone" desc = "Man, building with this will make you the coolest caveman on the block." color = "#e3dac9" - greyscale_colors = "#e3dac9" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/bone value_per_unit = 100 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 1.2, BULLET = 0.75, LASER = 0.75, ENERGY = 1.2, BOMB = 1, BIO = 1, FIRE = 1.5, ACID = 1.5) @@ -596,8 +705,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bamboo" desc = "If it's good enough for pandas, it's good enough for you." color = "#87a852" - greyscale_colors = "#87a852" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/bamboo value_per_unit = 5 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 0.5, ENERGY = 0.5, BOMB = 0.5, BIO = 0.51, FIRE = 0.5, ACID = 1.5) @@ -609,8 +722,12 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "zaukerite" desc = "A light absorbing crystal" color = COLOR_ALMOST_BLACK - greyscale_colors = COLOR_ALMOST_BLACK - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/mineral/zaukerite value_per_unit = 900 / SHEET_MATERIAL_AMOUNT armor_modifiers = list(MELEE = 0.9, BULLET = 0.9, LASER = 1.75, ENERGY = 1.75, BOMB = 0.5, BIO = 1, FIRE = 0.1, ACID = 1) diff --git a/code/datums/materials/hauntium.dm b/code/datums/materials/hauntium.dm index 79e25441720..b8eee26a08f 100644 --- a/code/datums/materials/hauntium.dm +++ b/code/datums/materials/hauntium.dm @@ -2,10 +2,15 @@ name = "hauntium" desc = "very scary!" color = list(460/255, 464/255, 460/255, 0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - greyscale_colors = "#FFFFFF64" + greyscale_color = "#FFFFFF" alpha = 100 starlight_color = COLOR_ALMOST_BLACK - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/hauntium value_per_unit = 0.05 beauty_modifier = 0.25 @@ -13,10 +18,14 @@ strength_modifier = 1.2 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.15, ENERGY = 1.15, BOMB = 1, BIO = 1, FIRE = 1, ACID = 0.7) -/datum/material/hauntium/on_applied_obj(obj/o, amount, material_flags) +/datum/material/hauntium/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - o.make_haunted(INNATE_TRAIT, "#f8f8ff") + if(isobj(source)) + var/obj/obj = source + obj.make_haunted(INNATE_TRAIT, "#f8f8ff") -/datum/material/hauntium/on_removed_obj(obj/o, amount, material_flags) +/datum/material/hauntium/on_main_removed(atom/source, mat_amount, multiplier) . = ..() - o.remove_haunted(INNATE_TRAIT) + if(isobj(source)) + var/obj/obj = source + obj.remove_haunted(INNATE_TRAIT) diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 552fa7a84cd..008099a526e 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -4,8 +4,12 @@ desc = "Meat" id = /datum/material/meat // So the bespoke versions are categorized under this color = rgb(214, 67, 67) - greyscale_colors = rgb(214, 67, 67) - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/meat value_per_unit = 0.05 beauty_modifier = -0.3 @@ -15,33 +19,28 @@ turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "meat" -/datum/material/meat/on_removed(atom/source, amount, material_flags) +/datum/material/meat/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - qdel(source.GetComponent(/datum/component/edible)) - qdel(source.GetComponent(/datum/component/blood_walk)) - qdel(source.GetComponent(/datum/component/bloody_spreader)) + if(!IS_EDIBLE(source)) + make_edible(source, mat_amount, multiplier) -/datum/material/meat/on_applied_obj(obj/O, amount, material_flags) +/datum/material/meat/on_applied(atom/source, mat_amount, multiplier) . = ..() - make_meaty(O, amount, material_flags) + if(IS_EDIBLE(source)) + make_edible(source, mat_amount, multiplier) -/datum/material/meat/on_applied_turf(turf/T, amount, material_flags) - . = ..() - make_meaty(T, amount, material_flags) - -/datum/material/meat/proc/make_meaty(atom/source, amount, material_flags) - var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT) - var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT) +/datum/material/meat/proc/make_edible(atom/source, mat_amount, multiplier) + var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) + var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) source.AddComponent(/datum/component/edible, \ initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \ foodtypes = RAW | MEAT | GROSS, \ eat_time = 3 SECONDS, \ tastes = list("Meaty")) - source.AddComponent( /datum/component/bloody_spreader,\ - blood_left = (nutriment_count + oil_count) * 0.3,\ + blood_left = (nutriment_count + oil_count) * 0.3 * multiplier,\ blood_dna = list("meaty DNA" = "MT-"),\ diseases = null,\ ) @@ -54,9 +53,18 @@ /datum/component/blood_walk,\ blood_type = /obj/effect/decal/cleanable/blood,\ blood_spawn_chance = 35,\ - max_blood = (nutriment_count + oil_count) * 0.3,\ + max_blood = (nutriment_count + oil_count) * 0.3 * multiplier,\ ) +/datum/material/meat/on_removed(atom/source, mat_amount, multiplier) + . = ..() + qdel(source.GetComponent(/datum/component/blood_walk)) + qdel(source.GetComponent(/datum/component/bloody_spreader)) + +/datum/material/meat/on_main_removed(atom/source, mat_amount, multiplier) + . = ..() + qdel(source.GetComponent(/datum/component/edible)) + /datum/material/meat/mob_meat init_flags = MATERIAL_INIT_BESPOKE var/subjectname = "" diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 588018576be..1906e5786d2 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -2,8 +2,12 @@ name = "pizza" desc = "~Jamme, jamme, n'coppa, jamme ja! Jamme, jamme, n'coppa jamme ja, funi-culi funi-cala funi-culi funi-cala!! Jamme jamme ja funiculi funicula!~" color = "#FF9F23" - greyscale_colors = "#FF9F23" - categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) + categories = list( + MAT_CATEGORY_RIGID = TRUE, + MAT_CATEGORY_BASE_RECIPES = TRUE, + MAT_CATEGORY_ITEM_MATERIAL = TRUE, + MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = TRUE, + ) sheet_type = /obj/item/stack/sheet/pizza value_per_unit = 0.05 beauty_modifier = 0.1 @@ -13,23 +17,25 @@ turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "pizza" -/datum/material/pizza/on_removed(atom/source, amount, material_flags) +/datum/material/pizza/on_main_applied(atom/source, mat_amount, multiplier) . = ..() - qdel(source.GetComponent(/datum/component/edible)) + if(!IS_EDIBLE(source)) + make_edible(source, mat_amount) -/datum/material/pizza/on_applied_obj(obj/O, amount, material_flags) +/datum/material/pizza/on_applied(atom/source, mat_amount, multiplier) . = ..() - make_edible(O, amount, material_flags) + if(IS_EDIBLE(source)) + make_edible(source, mat_amount) -/datum/material/pizza/on_applied_turf(turf/T, amount, material_flags) - . = ..() - make_edible(T, amount, material_flags) - -/datum/material/pizza/proc/make_edible(atom/source, amount, material_flags) - var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT) - var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT) +/datum/material/pizza/proc/make_edible(atom/source, mat_amount) + var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) + var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) source.AddComponent(/datum/component/edible, \ initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \ foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES, \ eat_time = 3 SECONDS, \ tastes = list("crust", "tomato", "cheese", "meat")) + +/datum/material/pizza/on_main_removed(atom/source, mat_amount, multiplier) + . = ..() + qdel(source.GetComponent(/datum/component/edible)) diff --git a/code/game/atom/atom_materials.dm b/code/game/atom/atom_materials.dm index 345a8486dd6..31ac1992a9b 100644 --- a/code/game/atom/atom_materials.dm +++ b/code/game/atom/atom_materials.dm @@ -7,23 +7,274 @@ ///Modifier that raises/lowers the effect of the amount of a material, prevents small and easy to get items from being death machines. var/material_modifier = 1 -/// Sets the custom materials for an item. +/// 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) - if(custom_materials && material_flags & MATERIAL_EFFECTS) //Only runs if custom materials existed at first and affected src. - for(var/current_material in custom_materials) - var/datum/material/custom_material = GET_MATERIAL_REF(current_material) - custom_material.on_removed(src, OPTIMAL_COST(custom_materials[current_material] * material_modifier), material_flags) //Remove the current materials + SHOULD_NOT_OVERRIDE(TRUE) + if(length(custom_materials)) + remove_material_effects() if(!length(materials)) custom_materials = null return - if(material_flags & MATERIAL_EFFECTS) - for(var/current_material in materials) - var/datum/material/custom_material = GET_MATERIAL_REF(current_material) - custom_material.on_applied(src, OPTIMAL_COST(materials[current_material] * multiplier * material_modifier), material_flags) + initialize_materials(materials, multiplier) - custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials, multiplier) +/** + * The second part of set_custom_materials(), which handles applying the new materials + * It is a separate proc because Initialize calls may make use of this since they should've no prior materials to remove. + */ +/atom/proc/initialize_materials(list/materials, multiplier = 1) + SHOULD_NOT_OVERRIDE(TRUE) + if(multiplier != 1) + materials = materials.Copy() //avoid editing the list that was originally used as argument if it's ever going to be used again. + for(var/current_material in materials) + materials[current_material] *= multiplier + + apply_material_effects(materials) + custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials) + +///proc responsible for applying material effects when setting materials. +/atom/proc/apply_material_effects(list/materials) + SHOULD_CALL_PARENT(TRUE) + if(!materials || !(material_flags & MATERIAL_EFFECTS)) + return + var/list/material_effects = get_material_effects_list(materials) + finalize_material_effects(material_effects) + +/// Proc responsible for removing material effects when setting materials. +/atom/proc/remove_material_effects() + SHOULD_CALL_PARENT(TRUE) + //Only runs if custom materials existed at first and affected src. + if(!custom_materials || !(material_flags & MATERIAL_EFFECTS)) + return + var/list/material_effects = get_material_effects_list(custom_materials) + finalize_remove_material_effects(material_effects) + +/atom/proc/get_material_effects_list(list/materials) + SHOULD_NOT_OVERRIDE(TRUE) + var/list/material_effects = list() + var/index = 1 + for(var/current_material in materials) + var/datum/material/material = GET_MATERIAL_REF(current_material) + material_effects[material] = list( + MATERIAL_LIST_OPTIMAL_AMOUNT = OPTIMAL_COST(materials[current_material] * material_modifier), + MATERIAL_LIST_MULTIPLIER = get_material_multiplier(material, materials, index), + ) + index++ + return material_effects + +/** + * A proc that can be used to selectively control the statistics and affects from a material without affecting the others + * For example, we can have items made of two different materials, with the primary contributing a good 1.2 multiplier + * and the second a meager 0.3. + * The GET_MATERIAL_MODIFIER macro will handles some modifiers where the minimum should be 1 if above 1 and the maximum + * 1 if below 1, so you shouldn't worry about returning values between 0 and 1. Be ware about returning negative values tho. + */ +/atom/proc/get_material_multiplier(datum/material/custom_material, list/materials, index) + return 1 + +///Called by apply_material_effects(). It ACTUALLY handles applying effects common to all atoms (depending on material flags) +/atom/proc/finalize_material_effects(list/materials) + SHOULD_CALL_PARENT(TRUE) + 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 + 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) + + //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example + if(material_flags & (MATERIAL_COLOR|MATERIAL_GREYSCALE)) + gather_material_color(custom_material, colors, mat_amount, multicolor = mat_length > 1) + var/added_alpha = custom_material.alpha * (custom_material.alpha / 255) + total_alpha += GET_MATERIAL_MODIFIER(added_alpha, multiplier) + if(custom_material.beauty_modifier) + AddElement(/datum/element/beauty, custom_material.beauty_modifier * mat_amount) + + apply_main_material_effects(main_material, main_mat_amount, main_mat_mult) + + if(material_flags & (MATERIAL_COLOR|MATERIAL_GREYSCALE)) + var/init_alpha = initial(alpha) + var/alpha_value = (total_alpha / length(materials)) * init_alpha + + if(alpha_value < init_alpha * 0.9) + opacity = FALSE + + if(material_flags & MATERIAL_GREYSCALE) + var/config_path = get_material_greyscale_config(main_material.type, greyscale_config) + //Make sure that we've no less than the expected amount + //expected_colors is zero for paths, the value is assigned when reading the json files. + var/datum/greyscale_config/config = SSgreyscale.configurations["[config_path || greyscale_config]"] + var/colors_len = length(colors) + if(config.expected_colors > colors_len) + var/list/filled_colors = colors.Copy() + for(var/index in colors_len to config.expected_colors - 1) + filled_colors += pick(colors) + colors = filled_colors + set_greyscale(colors, config_path) + else if(length(colors)) + mix_material_colors(colors) + + if(material_flags & MATERIAL_ADD_PREFIX) + var/prefixes = get_material_prefixes(materials) + name = "[prefixes] [name]" + +/** + * 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 + */ +/atom/proc/gather_material_color(datum/material/material, list/colors, amount, multicolor = FALSE) + SHOULD_CALL_PARENT(TRUE) + if(!material.color) //the material has no color. Nevermind + return + var/color_to_add = material.color + var/istext = istext(color_to_add) + if(istext) + if(material.alpha != 255) + color_to_add += num2hex(material.alpha, 2) + else + if(multicolor || material_flags & MATERIAL_GREYSCALE) + color_to_add = material.greyscale_color || color_matrix2color_hex(material.color) + if(material.greyscale_color) + color_to_add += num2hex(material.alpha, 2) + else + color_to_add = color_to_full_rgba_matrix(color_to_add) + color_to_add[20] *= (material.alpha / 255) // multiply the constant alpha of the color matrix + + colors[color_to_add] += amount + +/// Manages mixing, adding or removing the material colors from the atom in absence of the MATERIAL_GREYSCALE flag. +/atom/proc/mix_material_colors(list/colors, remove = FALSE) + SHOULD_NOT_OVERRIDE(TRUE) + var/color_len = length(colors) + if(!color_len) + return + var/mixcolor = colors[1] + var/amount_divisor = colors[mixcolor] + for(var/i in 2 to length(colors)) + var/color_to_add = colors[i] + if(islist(color_to_add)) + color_to_add = color_matrix2color_hex(color_to_add) + var/mix_amount = colors[color_to_add] + amount_divisor += mix_amount + mixcolor = BlendRGB(mixcolor, color_to_add, mix_amount/amount_divisor) + if(remove) + remove_atom_colour(FIXED_COLOUR_PRIORITY, mixcolor) + else + add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) + +///Returns the prefixes to attach to the atom when setting materials, from a list argument. +/atom/proc/get_material_prefixes(list/materials) + var/list/mat_names = list() + for(var/datum/material/material as anything in materials) + mat_names |= material.name + return mat_names.Join("-") + +///Returns a string like "plasma, paper and glass" from a list of materials +/atom/proc/get_material_english_list(list/materials) + var/list/mat_names = list() + for(var/datum/material/material as anything in materials) + mat_names += material.name + return english_list(mat_names) + +///Searches for a subtype of config_type that is to be used in its place for specific materials (like shimmering gold for cleric maces) +/atom/proc/get_material_greyscale_config(mat_type, config_type) + SHOULD_NOT_OVERRIDE(TRUE) + if(!config_type) + return + for(var/datum/greyscale_config/path as anything in subtypesof(config_type)) + if(mat_type != initial(path.material_skin)) + continue + return path + +///Apply material effects of a single material. +/atom/proc/apply_single_mat_effect(datum/material/custom_material, amount, multipier) + SHOULD_CALL_PARENT(TRUE) + return + +///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) + SHOULD_CALL_PARENT(TRUE) + if(main_material.texture_layer_icon_state && material_flags & MATERIAL_COLOR) + ADD_KEEP_TOGETHER(src, MATERIAL_SOURCE(main_material)) + add_filter("material_texture_[main_material.name]", 1, layering_filter(icon = main_material.cached_texture_filter_icon, blend_mode = BLEND_INSET_OVERLAY)) + + main_material.on_main_applied(src, amount, multipier) + +///Called by remove_material_effects(). It ACTUALLY handles removing effects common to all atoms (depending on material flags) +/atom/proc/finalize_remove_material_effects(list/materials) + var/list/colors = list() + var/datum/material/main_material = get_master_material() + var/mat_length = length(materials) + var/main_mat_amount + var/main_mat_mult + 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(custom_material == main_material) + main_mat_amount = mat_amount + main_mat_mult = multiplier + + remove_single_mat_effect(custom_material, mat_amount, multiplier) + custom_material.on_removed(src, mat_amount, multiplier) + if(material_flags & MATERIAL_COLOR) + gather_material_color(custom_material, colors, mat_amount, multicolor = mat_length > 1) + if(custom_material.beauty_modifier) + RemoveElement(/datum/element/beauty, custom_material.beauty_modifier * mat_amount) + + remove_main_material_effects(main_material, main_mat_amount, main_mat_mult) + + if(material_flags & (MATERIAL_GREYSCALE|MATERIAL_COLOR)) + if(material_flags & MATERIAL_COLOR) + mix_material_colors(colors, remove = TRUE) + else + set_greyscale(initial(greyscale_colors), initial(greyscale_config)) + alpha = initial(alpha) + opacity = initial(opacity) + + if(material_flags & MATERIAL_ADD_PREFIX) + name = initial(name) + +///Remove material effects of a single material. +/atom/proc/remove_single_mat_effect(datum/material/custom_material, amount, multipier) + SHOULD_CALL_PARENT(TRUE) + return + +///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) + SHOULD_CALL_PARENT(TRUE) + if(main_material.texture_layer_icon_state) + remove_filter("material_texture_[main_material.name]") + REMOVE_KEEP_TOGETHER(src, MATERIAL_SOURCE(main_material)) + main_material.on_main_removed(src, amount, multipier) + +///Remove the old effects, change the material_modifier variable, and then reapply all the effects. +/atom/proc/change_material_modifier(new_value) + SHOULD_NOT_OVERRIDE(TRUE) + remove_material_effects() + material_modifier = new_value + apply_material_effects(custom_materials) + +///For enabling and disabling material effects from an item (mainly VV) +/atom/proc/toggle_material_flags(new_flags) + SHOULD_NOT_OVERRIDE(TRUE) + if(material_flags & MATERIAL_EFFECTS && !(new_flags & MATERIAL_EFFECTS)) + remove_material_effects() + else if(!(material_flags & MATERIAL_EFFECTS) && new_flags & MATERIAL_EFFECTS) + apply_material_effects() + material_flags = new_flags /** * Returns the material composition of the atom. diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 10a6cbff24a..7a7dc8d3a87 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -270,6 +270,12 @@ if(NAMEOF(src, base_pixel_y)) set_base_pixel_y(var_value) . = TRUE + if(NAMEOF(src, material_flags)) + toggle_material_flags(var_value) + . = TRUE + if(NAMEOF(src, material_modifier)) + change_material_modifier(var_value) + . = TRUE light_flags = old_light_flags if(!isnull(.)) diff --git a/code/game/atom/atoms_initializing_EXPENSIVE.dm b/code/game/atom/atoms_initializing_EXPENSIVE.dm index 4d539786537..3a8eaac4a45 100644 --- a/code/game/atom/atoms_initializing_EXPENSIVE.dm +++ b/code/game/atom/atoms_initializing_EXPENSIVE.dm @@ -141,7 +141,8 @@ // This MUST come after atom_integrity is set above, as if old materials get removed, // atom_integrity is checked against max_integrity and can BREAK the atom. // The integrity to max_integrity ratio is still preserved. - set_custom_materials(custom_materials) + if(custom_materials) + initialize_materials(custom_materials) if(ispath(ai_controller)) ai_controller = new ai_controller(src) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 0a89c4e8b5b..06c88f4749e 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -112,7 +112,7 @@ highest_mat = present_mat highest_mat_ref = mat - flick_overlay_view(material_insertion_animation(highest_mat_ref.greyscale_colors), 1 SECONDS) + flick_overlay_view(material_insertion_animation(highest_mat_ref), 1 SECONDS) /obj/machinery/autolathe/ui_interact(mob/user, datum/tgui/ui) if(!is_operational) @@ -255,7 +255,7 @@ if(istext(material)) // category var/list/choices = list() for(var/datum/material/valid_candidate as anything in SSmaterials.materials_by_category[material]) - if(materials.get_material_amount(valid_candidate) < amount_needed) + if(materials.get_material_amount(valid_candidate) < (amount_needed + materials_needed[material])) continue choices[valid_candidate.name] = valid_candidate if(!length(choices)) @@ -274,7 +274,7 @@ if(isnull(material)) stack_trace("got passed an invalid material id: [material]") return - materials_needed[material] = amount_needed + materials_needed[material] += amount_needed //checks for available materials var/material_cost_coefficient = ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency diff --git a/code/game/machinery/flatpacker.dm b/code/game/machinery/flatpacker.dm index 56fcc8a8ae7..6c90e45e4f6 100644 --- a/code/game/machinery/flatpacker.dm +++ b/code/game/machinery/flatpacker.dm @@ -124,7 +124,7 @@ highest_mat = present_mat highest_mat_ref = mat - flick_overlay_view(material_insertion_animation(highest_mat_ref.greyscale_colors), 1 SECONDS) + flick_overlay_view(material_insertion_animation(highest_mat_ref), 1 SECONDS) /** * Attempts to find the total material cost of a typepath (including our creation efficiency), modifying a list diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm index 2d92eaabb92..8f10717c771 100644 --- a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm +++ b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm @@ -36,7 +36,7 @@ /datum/dimension_theme/New() if (material) var/datum/material/using_mat = GET_MATERIAL_REF(material) - window_colour = using_mat.greyscale_colors + window_colour = using_mat.color /** * Applies themed transformation to the provided turf. diff --git a/code/game/objects/effects/material_insert.dm b/code/game/objects/effects/material_insert.dm index 9ca86226b24..3dcdd904a01 100644 --- a/code/game/objects/effects/material_insert.dm +++ b/code/game/objects/effects/material_insert.dm @@ -2,21 +2,18 @@ * Creates a mutable appearance with the material color applied for its insertion animation into an autolathe or techfab * Arguments * - * * color - the material color that will be applied + * * material - the material used to generate the overlay */ -/proc/material_insertion_animation(color) +/proc/material_insertion_animation(datum/material/material) RETURN_TYPE(/mutable_appearance) var/static/list/mutable_appearance/apps = list() - var/mutable_appearance/cached_app = apps[color] + var/mutable_appearance/cached_app = apps[material] if(isnull(cached_app)) - var/icon/modified_icon = icon('icons/obj/machines/research.dmi', "material_insertion") + cached_app = mutable_appearance('icons/obj/machines/research.dmi', "material_insertion") + cached_app.color = material.color + cached_app.alpha = material.alpha - //assuming most of the icon is white we find what ratio to scale the intensity of each part roughly - var/list/rgb_list = rgb2num(color) - modified_icon.SetIntensity(rgb_list[1] / 255, rgb_list[2] / 255, rgb_list[3] / 255) - cached_app = mutable_appearance(modified_icon, "material_insertion") - - apps[color] = cached_app + apps[material] = cached_app return cached_app diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f9edb7952eb..f00c3d11fc5 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1872,6 +1872,56 @@ embed_data = ispath(embed) ? get_embed_by_type(embed) : embed SEND_SIGNAL(src, COMSIG_ITEM_EMBEDDING_UPDATE) +/obj/item/apply_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(material_flags & MATERIAL_GREYSCALE) + var/main_mat_type = main_material.type + var/worn_path = get_material_greyscale_config(main_mat_type, greyscale_config_worn) + var/lefthand_path = get_material_greyscale_config(main_mat_type, greyscale_config_inhand_left) + var/righthand_path = get_material_greyscale_config(main_mat_type, greyscale_config_inhand_right) + set_greyscale( + new_worn_config = worn_path, + new_inhand_left = lefthand_path, + new_inhand_right = righthand_path + ) + if(!main_material.item_sound_override) + return + hitsound = main_material.item_sound_override + usesound = main_material.item_sound_override + mob_throw_hit_sound = main_material.item_sound_override + equip_sound = main_material.item_sound_override + pickup_sound = main_material.item_sound_override + drop_sound = main_material.item_sound_override + +/obj/item/remove_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(material_flags & MATERIAL_GREYSCALE) + set_greyscale( + new_worn_config = initial(greyscale_config_worn), + new_inhand_left = initial(greyscale_config_inhand_left), + new_inhand_right = initial(greyscale_config_inhand_right) + ) + if(!main_material.item_sound_override) + return + hitsound = initial(hitsound) + usesound = initial(usesound) + mob_throw_hit_sound = initial(mob_throw_hit_sound) + equip_sound = initial(equip_sound) + pickup_sound = initial(pickup_sound) + drop_sound = initial(drop_sound) + +/obj/item/apply_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !slowdown) + return + slowdown += GET_MATERIAL_MODIFIER(material.added_slowdown * mat_amount, multiplier) + +/obj/item/remove_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !slowdown) + return + slowdown -= GET_MATERIAL_MODIFIER(material.added_slowdown * mat_amount, multiplier) + /** * Returns the atom(either itself or an internal module) that will interact/attack the target on behalf of us * For example an object can have different `tool_behaviours` (e.g borg omni tool) but will return an internal reference of that tool to attack for us diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 7703160bfdb..29df25d179c 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -514,10 +514,10 @@ greyscale_config_inhand_left = /datum/greyscale_config/cleric_mace_lefthand greyscale_config_inhand_right = /datum/greyscale_config/cleric_mace_righthand greyscale_config_worn = /datum/greyscale_config/cleric_mace - greyscale_colors = COLOR_WHITE + greyscale_colors = COLOR_WHITE + COLOR_BROWN material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_AFFECT_STATISTICS //Material type changes the prefix as well as the color. - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*6) //Defaults to an Iron Mace. + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 4.5, /datum/material/wood = SHEET_MATERIAL_AMOUNT * 1.5) //Defaults to an Iron Mace. slot_flags = ITEM_SLOT_BELT force = 14 w_class = WEIGHT_CLASS_BULKY @@ -528,6 +528,26 @@ attack_verb_continuous = list("smacks", "strikes", "cracks", "beats") attack_verb_simple = list("smack", "strike", "crack", "beat") +///Cleric maces are made of two custom materials: one is handle, and the other is the mace itself. +/obj/item/melee/cleric_mace/get_material_multiplier(datum/material/custom_material, list/materials, index) + if(length(materials) < 1) + return 1.2 + if(index == 1) + return 1 + else + return 0.3 + +/obj/item/melee/cleric_mace/get_material_prefixes(list/materials) + var/datum/material/material = materials[1] + return material.name //It only inherits the name of the main material it's made of. The secondary is in the description. + +/obj/item/melee/cleric_mace/finalize_material_effects(list/materials) + . = ..() + if(length(materials) == 1) + return + var/datum/material/material = materials[2] + desc = "[initial(desc)] Its handle is made of [material.name]." + /obj/item/melee/cleric_mace/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) if(attack_type == PROJECTILE_ATTACK || attack_type == LEAP_ATTACK) final_block_chance = 0 //Don't bring a...mace to a gunfight, and also you aren't going to really block someone full body tackling you with a mace diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index b5aa0a30c3c..0e995120c00 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -77,18 +77,19 @@ amount = new_amount while(amount > max_amount) amount -= max_amount - new type(loc, max_amount, FALSE) + new type(loc, max_amount, FALSE, mat_override, mat_amt) if(!merge_type) merge_type = type - if(LAZYLEN(mat_override)) - set_mats_per_unit(mat_override, mat_amt) - else if(LAZYLEN(mats_per_unit)) - set_mats_per_unit(mats_per_unit, 1) - else if(LAZYLEN(custom_materials)) - set_mats_per_unit(custom_materials, amount ? 1/amount : 1) - . = ..() + + var/materials_mult = amount + if(LAZYLEN(mat_override)) + materials_mult *= mat_amt + mats_per_unit = mat_override + if(LAZYLEN(mats_per_unit)) + initialize_materials(mats_per_unit, materials_mult) + if(merge) for(var/obj/item/stack/item_stack in loc) if(item_stack == src) @@ -118,26 +119,15 @@ if(is_path_in_list(merge_type, GLOB.golem_stack_food_directory)) AddComponent(/datum/component/golem_food, golem_food_key = merge_type) -/** Sets the amount of materials per unit for this stack. - * - * Arguments: - * - [mats][/list]: The value to set the mats per unit to. - * - multiplier: The amount to multiply the mats per unit by. Defaults to 1. - */ -/obj/item/stack/proc/set_mats_per_unit(list/mats, multiplier=1) - mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(mats, multiplier) - update_custom_materials() - -/** Updates the custom materials list of this stack. - */ +///Called to lazily update the materials of the item whenever the used or if more is added /obj/item/stack/proc/update_custom_materials() - set_custom_materials(mats_per_unit, amount, is_update=TRUE) + if(length(mats_per_unit)) + set_custom_materials(mats_per_unit, amount) -/** - * Override to make things like metalgen accurately set custom materials - */ -/obj/item/stack/set_custom_materials(list/materials, multiplier=1, is_update=FALSE) - return is_update ? ..() : set_mats_per_unit(materials, multiplier/(amount || 1)) +/obj/item/stack/apply_material_effects(list/materials) + . = ..() + if(amount) + mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(materials, 1/amount) /obj/item/stack/blend_requirements() if(is_cyborg) @@ -440,7 +430,7 @@ if((recipe.crafting_flags & CRAFT_APPLIES_MATS) && LAZYLEN(mats_per_unit)) if(isstack(created)) var/obj/item/stack/crafted_stack = created - crafted_stack.set_mats_per_unit(mats_per_unit, recipe.req_amount / recipe.res_amount) + crafted_stack.set_custom_materials(mats_per_unit, (recipe.req_amount / recipe.res_amount) * crafted_stack.amount) else created.set_custom_materials(mats_per_unit, recipe.req_amount / recipe.res_amount) @@ -543,8 +533,7 @@ amount -= used if(check && is_zero_amount(delete_if_zero = TRUE)) return TRUE - if(length(mats_per_unit)) - update_custom_materials() + update_custom_materials() update_appearance() update_weight() return TRUE @@ -591,8 +580,7 @@ source.add_charge(_amount * cost) else amount += _amount - if(length(mats_per_unit)) - update_custom_materials() + update_custom_materials() update_appearance() update_weight() diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 56aef2176f8..bf1b37f0d98 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -19,7 +19,7 @@ hitsound = 'sound/items/weapons/smash.ogg' drop_sound = 'sound/items/handling/toolbox/toolbox_drop.ogg' pickup_sound = 'sound/items/handling/toolbox/toolbox_pickup.ogg' - material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS var/latches = "single_latch" var/has_latches = TRUE wound_bonus = 5 diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 0a88aade697..c51adf91b3b 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -291,3 +291,28 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) pixel_z = anchored_tabletop_offset else pixel_z = initial(pixel_z) + +/obj/apply_single_mat_effect(datum/material/material, mat_amount, multiplier) + . = ..() + if(!(material_flags & MATERIAL_AFFECT_STATISTICS)) + return + 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 + 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)) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index a4d35f02e0c..5c2f1972c33 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -392,8 +392,9 @@ var/datum/material/material_datum = material new material_datum.sheet_type(loc, FLOOR(custom_materials[material_datum] / SHEET_MATERIAL_AMOUNT, 1)) -/obj/structure/falsewall/material/mat_update_desc(mat) - desc = "A huge chunk of [mat] used to separate rooms." +/obj/structure/falsewall/material/finalize_material_effects(list/materials) + . = ..() + desc = "A huge chunk of [get_material_english_list(materials)] used to separate rooms." /obj/structure/falsewall/material/toggle_open() if(!QDELETED(src)) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 72a3d861016..20164d3072f 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -361,13 +361,10 @@ material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS buildstack = null //No buildstack, so generate from mat datums -/obj/structure/table/greyscale/set_custom_materials(list/materials, multiplier) +/obj/structure/table/greyscale/finalize_material_effects(list/materials) . = ..() - var/list/materials_list = list() - for(var/custom_material in custom_materials) - var/datum/material/current_material = GET_MATERIAL_REF(custom_material) - materials_list += "[current_material.name]" - desc = "A square [(materials_list.len > 1) ? "amalgamation" : "piece"] of [english_list(materials_list)] on four legs. It can not move." + var/english_list = get_material_english_list(materials) + desc = "A square [(length(materials) > 1) ? "amalgamation" : "piece"] of [english_list] on four legs. It can not move." ///Table on wheels /obj/structure/table/rolling diff --git a/code/game/turfs/closed/wall/material_walls.dm b/code/game/turfs/closed/wall/material_walls.dm index 5f16a68584f..f8f9d58c220 100644 --- a/code/game/turfs/closed/wall/material_walls.dm +++ b/code/game/turfs/closed/wall/material_walls.dm @@ -22,6 +22,7 @@ var/datum/material/M = i new M.sheet_type(src, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1)) -/turf/closed/wall/material/mat_update_desc(mat) - desc = "A huge chunk of [mat] used to separate rooms." +/turf/closed/wall/material/finalize_material_effects(list/materials) + . = ..() + desc = "A huge chunk of [get_material_english_list(materials)] used to separate rooms." diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index 68c3c1a1c77..a841db9265e 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -494,6 +494,15 @@ playsound(src, 'sound/items/weapons/genhit.ogg', 50, TRUE) new used_tiles.tile_type(src) +/turf/open/apply_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(!main_material.turf_sound_override) + return + footstep = main_material.turf_sound_override + barefootstep = main_material.turf_sound_override + "barefoot" + clawfootstep = main_material.turf_sound_override + "claw" + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + /// Very similar to build_with_rods, this exists to allow building transport/tram girders on openspace /turf/open/proc/build_with_titanium(obj/item/stack/sheet/mineral/titanium/used_stack, user) var/obj/structure/transport/linear/platform = locate(/obj/structure/transport/linear, src) diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index dad46fd8de6..c3ea3694043 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -382,4 +382,4 @@ . = ..() if(.) var/obj/item/stack/tile = . - tile.set_mats_per_unit(custom_materials, 1) + tile.set_custom_materials(custom_materials) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index c9256f2e0c8..db185ba38ec 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -772,6 +772,23 @@ GLOBAL_LIST_EMPTY(station_turfs) inherent_explosive_resistance = explosion_block explosive_resistance += get_explosive_block() +/turf/apply_main_material_effects(datum/material/main_material, amount, multipier) + . = ..() + if(alpha < 255) + AddElement(/datum/element/turf_z_transparency) + main_material.setup_glow(src) + rust_resistance = main_material.mat_rust_resistance + +/turf/remove_main_material_effects(datum/material/custom_material, amount, multipier) + . = ..() + rust_resistance = initial(rust_resistance) + if(alpha == 255) + return + RemoveElement(/datum/element/turf_z_transparency) + // yeets glow + UnregisterSignal(SSdcs, COMSIG_STARLIGHT_COLOR_CHANGED) + set_light(0, 0, null) + /// Returns whether it is safe for an atom to move across this turf /turf/proc/can_cross_safely(atom/movable/crossing) return TRUE diff --git a/code/modules/atmospherics/machinery/components/tank.dm b/code/modules/atmospherics/machinery/components/tank.dm index f76f3dc470f..6aa23f84e93 100644 --- a/code/modules/atmospherics/machinery/components/tank.dm +++ b/code/modules/atmospherics/machinery/components/tank.dm @@ -88,7 +88,6 @@ air_contents = new air_contents.temperature = T20C air_contents.volume = volume - refresh_pressure_limit() if(gas_type) fill_to_pressure(gas_type) @@ -121,7 +120,7 @@ . += span_notice("The pipe port can be moved or closed with a [wrench_hint].") . += span_notice("A holographic sticker on it says that its maximum safe pressure is: [siunit_pressure(max_pressure, 0)].") -/obj/machinery/atmospherics/components/tank/set_custom_materials(list/materials, multiplier) +/obj/machinery/atmospherics/components/tank/finalize_material_effects(list/materials) . = ..() refresh_pressure_limit() diff --git a/code/modules/cargo/materials_market.dm b/code/modules/cargo/materials_market.dm index 4037a51c691..dd3093a0aaf 100644 --- a/code/modules/cargo/materials_market.dm +++ b/code/modules/cargo/materials_market.dm @@ -143,7 +143,7 @@ trend_string = "down" //get mat color - var/initial_colors = initial(traded_mat.greyscale_colors) + var/initial_colors = initial(traded_mat.greyscale_color) || initial(traded_mat.color) if(initial_colors) color_string = splicetext(initial_colors, 7, length(initial_colors), "") //slice it to a standard 6 char hex else diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 7ad08083df3..0b051248a39 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -442,14 +442,13 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ pixel_x = base_pixel_x + rand(0, 16) - 8 pixel_y = base_pixel_y + rand(0, 8) - 8 -/obj/item/coin/set_custom_materials(list/materials, multiplier = 1) +/obj/item/coin/finalize_material_effects(list/materials) . = ..() if(override_material_worth) return value = 0 - for(var/i in custom_materials) - var/datum/material/M = i - value += M.value_per_unit * custom_materials[M] + for(var/datum/material/material as anything in materials) + value += material.value_per_unit * materials[material][MATERIAL_LIST_OPTIMAL_AMOUNT] /obj/item/coin/get_item_credit_value() return value diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 13ac09c9a52..b1758086444 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2709,7 +2709,7 @@ taste_mult = 0 // oderless and tasteless chemical_flags = REAGENT_NO_RANDOM_RECIPE /// The material flags used to apply the transmuted materials - var/applied_material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR + var/applied_material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS /// The amount of materials to apply to the transmuted objects if they don't contain materials var/default_material_amount = 100 diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index f0e0978a607..ebda0f1e3b4 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -434,7 +434,7 @@ desc = "A mace fit for a cleric. Useful for bypassing plate armor, but too bulky for much else." id = "cleric_mace" build_type = AUTOLATHE - materials = list(MAT_CATEGORY_ITEM_MATERIAL = SHEET_MATERIAL_AMOUNT * 6) + materials = list(MAT_CATEGORY_ITEM_MATERIAL = SHEET_MATERIAL_AMOUNT * 4.5, MAT_CATEGORY_ITEM_MATERIAL_COMPLEMENTARY = SHEET_MATERIAL_AMOUNT * 1.5) build_path = /obj/item/melee/cleric_mace category = list(RND_CATEGORY_IMPORTED) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index 40725c6f198..57044fd831f 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -174,7 +174,7 @@ SHOULD_CALL_PARENT(FALSE) //first play the insertion animation - flick_overlay_view(material_insertion_animation(mat_ref.greyscale_colors), 1 SECONDS) + flick_overlay_view(material_insertion_animation(mat_ref), 1 SECONDS) //now play the progress bar animation flick_overlay_view(mutable_appearance('icons/obj/machines/research.dmi', "protolathe_progress"), 1 SECONDS) diff --git a/icons/obj/weapons/cleric_mace.dmi b/icons/obj/weapons/cleric_mace.dmi index 3dc90bf10c4..ad7fdbc09a2 100644 Binary files a/icons/obj/weapons/cleric_mace.dmi and b/icons/obj/weapons/cleric_mace.dmi differ