From 93ea8085cb70edb4b5e39f229572f6c95a272ca0 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 11 Apr 2026 01:15:07 +0200 Subject: [PATCH] Datumizes material effects, slots, and material spears (#95341) --- _maps/RandomZLevels/heretic.dmm | 2 +- code/__DEFINES/construction/material.dm | 13 + .../dcs/signals/signals_materials.dm | 10 + code/controllers/subsystem/materials.dm | 8 +- .../components/crafting/melee_weapon.dm | 10 + .../components/material_turf_tracking.dm | 203 +++++++++++++++ code/datums/components/twohanded.dm | 17 ++ code/datums/elements/elevation.dm | 14 +- code/datums/elements/loomable.dm | 18 +- code/datums/materials/_material.dm | 168 +++++++++++- code/datums/materials/alloys.dm | 44 ++-- code/datums/materials/basemats.dm | 84 ++++-- code/datums/materials/material_slots/_slot.dm | 19 ++ .../materials/material_slots/generic.dm | 210 +++++++++++++++ code/datums/materials/meat.dm | 6 +- code/datums/materials/pizza.dm | 6 +- .../materials/properties/_properties.dm | 4 + code/datums/materials/properties/derived.dm | 11 + code/datums/materials/properties/optional.dm | 131 +++++++++- .../materials/requirements/_requirement.dm | 3 + code/game/atom/atom_examine.dm | 3 +- code/game/atom/atom_materials.dm | 237 ++++++++++++++--- code/game/machinery/autolathe.dm | 33 ++- code/game/objects/items.dm | 52 ++-- code/game/objects/items/stacks/bscrystal.dm | 40 +-- code/game/objects/items/stacks/rods.dm | 2 +- .../objects/items/stacks/sheets/leather.dm | 14 +- .../items/stacks/sheets/sheet_types.dm | 4 +- .../objects/items/stacks/sheets/sheets.dm | 3 +- code/game/objects/items/stacks/telecrystal.dm | 34 ++- .../objects/items/weaponry/melee/baton.dm | 1 + .../game/objects/items/weaponry/melee/misc.dm | 35 ++- .../objects/items/weaponry/melee/spear.dm | 246 +++++++++++++----- code/game/objects/objs.dm | 10 +- code/modules/fishing/fish/fish_traits.dm | 2 +- code/modules/manufactorio/machines/lathe.dm | 21 +- .../projectiles/guns/ballistic/pistol.dm | 2 +- .../chemistry/reagents/other_reagents.dm | 6 + code/modules/research/designs.dm | 2 +- .../research/designs/weapon_designs.dm | 2 +- .../research/xenobiology/xenobiology.dm | 2 +- .../mob/inhands/weapons/polearms_lefthand.dmi | Bin 12851 -> 12139 bytes .../inhands/weapons/polearms_righthand.dmi | Bin 14090 -> 12291 bytes icons/obj/stack_objects.dmi | Bin 51131 -> 51412 bytes icons/obj/weapons/spear.dmi | Bin 5909 -> 5388 bytes icons/turf/composite.dmi | Bin 3333 -> 3864 bytes tgstation.dme | 3 + 47 files changed, 1441 insertions(+), 294 deletions(-) create mode 100644 code/datums/components/material_turf_tracking.dm create mode 100644 code/datums/materials/material_slots/_slot.dm create mode 100644 code/datums/materials/material_slots/generic.dm diff --git a/_maps/RandomZLevels/heretic.dmm b/_maps/RandomZLevels/heretic.dmm index 831b608268a..69266c7c2e3 100644 --- a/_maps/RandomZLevels/heretic.dmm +++ b/_maps/RandomZLevels/heretic.dmm @@ -7777,7 +7777,7 @@ /obj/effect/decal/cleanable/blood/tracks/xeno, /obj/item/organ/tail/xeno, /obj/item/stack/sheet/animalhide/xeno, -/obj/item/stack/sheet/xenochitin, +/obj/item/stack/sheet/animalhide/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body, /obj/effect/decal/remains/xeno, /obj/effect/light_emitter, diff --git a/code/__DEFINES/construction/material.dm b/code/__DEFINES/construction/material.dm index 310ebc4d02d..7e5c6d6263a 100644 --- a/code/__DEFINES/construction/material.dm +++ b/code/__DEFINES/construction/material.dm @@ -74,10 +74,21 @@ GLOBAL_LIST_INIT(material_flags_to_string, alist( // Optional material property IDs #define MATERIAL_FLAMMABILITY "flammability" #define MATERIAL_RADIOACTIVITY "radioactivity" +#define MATERIAL_FIRESTACKER "firestacker" +#define MATERIAL_VAMPIRES_BANE "vampires_bane" +#define MATERIAL_TELEPORTING "teleporting" +#define MATERIAL_PENETRATING "penetrating" // Derived material property IDs #define MATERIAL_INTEGRITY "integrity" #define MATERIAL_BEAUTY "beauty" +#define MATERIAL_INSULATION "insulation" + +// Flags for signal tracking on materials +/// Send COMSIG_MATERIAL_EFFECT_X whenever a mob steps onto a material atom/is shoved into this material wall +#define MATERIAL_TRACK_CONTACT (1 << 0) +/// Send COMSIG_MATERIAL_EFFECT_X whenever a mob is hit by/hits/catches the material atom +#define MATERIAL_TRACK_IMPACT (1 << 1) /// Maximum value for a core material property #define MATERIAL_PROPERTY_MAX 10 @@ -170,5 +181,7 @@ GLOBAL_LIST_INIT(material_flags_to_string, alist( #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" +/// Key controlling which material slots a material is assigned to +#define MATERIAL_LIST_SLOTS "slot" /// A macro that ensures some multiplicative modifiers higher than 1 don't become lower than 1 and vice-versa because of the multiplier. #define GET_MATERIAL_MODIFIER(modifier, multiplier) (modifier >= 1 ? 1 + ((modifier) - 1) * (multiplier) : (modifier)**(multiplier)) diff --git a/code/__DEFINES/dcs/signals/signals_materials.dm b/code/__DEFINES/dcs/signals/signals_materials.dm index 2eefb523548..c99b8f1f56c 100644 --- a/code/__DEFINES/dcs/signals/signals_materials.dm +++ b/code/__DEFINES/dcs/signals/signals_materials.dm @@ -8,3 +8,13 @@ #define COMSIG_MATERIAL_REMOVED "material_removed" /// from /datum/material/proc/on_main_removed(source, mat_amount, multiplier): (atom/old_atom, mat_amount, multiplier) #define COMSIG_MATERIAL_MAIN_REMOVED "material_main_removed" + +// Material property effect triggers +/// When a material is touched by an atom: (datum/material/source, atom/object, atom/target, mob/living/initiator, def_zone, skin_contact) +#define COMSIG_MATERIAL_EFFECT_TOUCH "material_effect_touch" +/// When a material is stepped onto: (datum/material/source, atom/object, atom/target, mob/living/initiator, def_zone, skin_contact) +#define COMSIG_MATERIAL_EFFECT_STEP "material_effect_step" +/// When a material hits something: (datum/material/source, atom/object, atom/target, mob/living/user, def_zone, skin_contact) +#define COMSIG_MATERIAL_EFFECT_HIT "material_effect_hit" +/// When a material hits something when thrown: (datum/material/source, atom/object, atom/target, mob/living/thrower, def_zone, skin_contact) +#define COMSIG_MATERIAL_EFFECT_THROW_IMPACT "material_effect_throw_impact" diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index 0bbeb16fbe3..b4bf65a501c 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -35,6 +35,8 @@ SUBSYSTEM_DEF(materials) var/list/datum/material_property/properties /// A typepath -> instance list of material requirements var/list/datum/material_requirement/requirements + /// A typepath -> instance list of material slots + var/list/datum/material_slot/material_slots ///Ran on initialize, populated the materials and material dictionaries with their appropriate vars (See these variables for more info) /datum/controller/subsystem/materials/proc/initialize_materials() @@ -51,6 +53,10 @@ SUBSYSTEM_DEF(materials) for(var/datum/material_requirement/requirement_type as anything in valid_subtypesof(/datum/material_requirement)) requirements[requirement_type] = new requirement_type() + material_slots = list() + for(var/datum/material_slot/slot_type as anything in valid_subtypesof(/datum/material_slot)) + material_slots[slot_type] = new slot_type() + for(var/datum/material/mat_type as anything in valid_subtypesof(/datum/material)) if(initial(mat_type.init_flags) & MATERIAL_INIT_MAPLOAD) initialize_material(mat_type) @@ -188,7 +194,7 @@ SUBSYSTEM_DEF(materials) if(!combo) combo = list() for(var/mat in materials_declaration) - combo[SSmaterials.get_material(mat)] = OPTIMAL_COST(materials_declaration[mat] * multiplier) + combo[get_material(mat)] = OPTIMAL_COST(materials_declaration[mat] * multiplier) material_combos[combo_index] = combo return combo diff --git a/code/datums/components/crafting/melee_weapon.dm b/code/datums/components/crafting/melee_weapon.dm index 9f0fab50964..00ced214f81 100644 --- a/code/datums/components/crafting/melee_weapon.dm +++ b/code/datums/components/crafting/melee_weapon.dm @@ -145,6 +145,16 @@ time = 4 SECONDS category = CAT_WEAPON_MELEE +/datum/crafting_recipe/wireprod + name = "Wireprod assembly" + result = /obj/item/wireprod + reqs = list( + /obj/item/restraints/handcuffs/cable = 1, + /obj/item/stack/rods = 1, + ) + time = 2 SECONDS + category = CAT_WEAPON_MELEE + /datum/crafting_recipe/toysword name = "Toy Sword" reqs = list( diff --git a/code/datums/components/material_turf_tracking.dm b/code/datums/components/material_turf_tracking.dm new file mode 100644 index 00000000000..492b4d0f495 --- /dev/null +++ b/code/datums/components/material_turf_tracking.dm @@ -0,0 +1,203 @@ +/// Sends a signal to the owner material whenever something enters its objects' turf and steps onto said object +/datum/component/material_turf_tracking + dupe_mode = COMPONENT_DUPE_ALLOWED + /// Material we're linked to + var/datum/material/owner_material = null + /// Does our parent require the target to be elevated for us to trigger? + var/requires_elevation = FALSE + + /// Typecache of things we should ignore + var/static/list/interaction_blacklist = typecacheof(list( + /obj/docking_port, + /obj/effect/abstract, + /obj/effect/atmos_shield, + /obj/effect/collapse, + /obj/effect/constructing_effect, + /obj/effect/dummy/phased_mob, + /obj/effect/ebeam, + /obj/effect/fishing_float, + /obj/effect/hotspot, + /obj/effect/landmark, + /obj/effect/light_emitter/tendril, + /obj/effect/mapping_helpers, + /obj/effect/particle_effect/ion_trails, + /obj/effect/particle_effect/sparks, + /obj/effect/portal, + /obj/effect/projectile, + /obj/effect/spectre_of_resurrection, + /obj/effect/temp_visual, + /obj/effect/wisp, + /obj/energy_ball, + /obj/narsie, + /obj/singularity, + )) + + /// Typecache of objects which we only consider "touched" when they elevate the mob, or the mob is buckled to them + /// Easy way to keep track of snowflake behavior like flipped tables + var/static/list/elevation_interactions = typecacheof(list( + /obj/structure/platform, + /obj/structure/table, + /obj/structure/rack, + /obj/structure/bed, + /obj/structure/closet/crate, + /obj/structure/reagent_dispensers, + /obj/structure/altar, + )) + +/datum/component/material_turf_tracking/Initialize(datum/material/owner_material) + if (!isopenturf(parent) && !isobj(parent)) + return COMPONENT_INCOMPATIBLE + src.owner_material = owner_material + if (is_type_in_typecache(parent, elevation_interactions)) + requires_elevation = TRUE + +/datum/component/material_turf_tracking/Destroy(force) + owner_material = null + return ..() + +/datum/component/material_turf_tracking/RegisterWithParent() + var/turf/target_turf = parent + if (ismovable(parent)) + var/atom/movable/as_movable = parent + RegisterSignal(as_movable, COMSIG_ATOM_ENTERING, PROC_REF(on_source_entering)) + RegisterSignal(as_movable, COMSIG_ATOM_EXITING, PROC_REF(on_source_exiting)) + target_turf = as_movable.loc + + if (!isopenturf(target_turf)) + return + + if (!requires_elevation) + RegisterSignal(target_turf, SIGNAL_ADDTRAIT(TRAIT_ELEVATED_TURF), PROC_REF(on_turf_lost)) + RegisterSignal(target_turf, SIGNAL_REMOVETRAIT(TRAIT_ELEVATED_TURF), PROC_REF(on_turf_gained)) + if (HAS_TRAIT(target_turf, TRAIT_ELEVATED_TURF)) + return + + // Not tracking initializations or existing objects as this would allow you to TP someone from plating by placing a tile underneath + RegisterSignal(target_turf, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) + RegisterSignal(target_turf, COMSIG_TURF_MOVABLE_THROW_LANDED, PROC_REF(on_entered)) // Need this as shoves are 1 tile throws, and COMSIG_ATOM_ENTERED runs before the throw ends + RegisterSignal(target_turf, COMSIG_ATOM_EXITED, PROC_REF(on_exited)) + +/datum/component/material_turf_tracking/UnregisterFromParent() + . = ..() + if (isturf(parent)) + on_source_exiting(parent) + return + + var/atom/movable/as_movable = parent + UnregisterSignal(as_movable, list(COMSIG_ATOM_ENTERING, COMSIG_ATOM_EXITING)) + on_source_exiting(as_movable.loc) + +/datum/component/material_turf_tracking/proc/on_source_entering(atom/movable/source, atom/entering, atom/old_loc) + SIGNAL_HANDLER + + if (!isopenturf(entering)) + return + + if (!requires_elevation) + RegisterSignal(entering, SIGNAL_ADDTRAIT(TRAIT_ELEVATED_TURF), PROC_REF(on_turf_lost)) + RegisterSignal(entering, SIGNAL_REMOVETRAIT(TRAIT_ELEVATED_TURF), PROC_REF(on_turf_gained)) + if (HAS_TRAIT(entering, TRAIT_ELEVATED_TURF)) + return + on_turf_gained(entering) + +/datum/component/material_turf_tracking/proc/on_source_exiting(atom/movable/source, atom/exiting) + SIGNAL_HANDLER + + if (!isturf(exiting)) + return + + UnregisterSignal(exiting, list(SIGNAL_ADDTRAIT(TRAIT_ELEVATED_TURF), SIGNAL_REMOVETRAIT(TRAIT_ELEVATED_TURF))) + on_turf_lost(exiting) + +/datum/component/material_turf_tracking/proc/on_turf_gained(turf/source) + SIGNAL_HANDLER + + RegisterSignal(source, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) + RegisterSignal(source, COMSIG_TURF_MOVABLE_THROW_LANDED, PROC_REF(on_entered)) + RegisterSignal(source, COMSIG_ATOM_EXITED, PROC_REF(on_exited)) + for (var/atom/movable/thing in source) + on_entered(source, thing) + +/datum/component/material_turf_tracking/proc/on_turf_lost(turf/source) + SIGNAL_HANDLER + + UnregisterSignal(source, list(COMSIG_ATOM_ENTERED, COMSIG_TURF_MOVABLE_THROW_LANDED, COMSIG_ATOM_EXITED)) + for (var/atom/movable/thing in source) + UnregisterSignal(thing, list(SIGNAL_ADDTRAIT(TRAIT_MOB_ELEVATED), COMSIG_MOVETYPE_FLAG_DISABLED)) + +/datum/component/material_turf_tracking/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + SIGNAL_HANDLER + + if (arrived.throwing || arrived.invisibility >= INVISIBILITY_ABSTRACT || arrived == parent) + return + + if (is_type_in_typecache(arrived, interaction_blacklist)) + return + + if (!isliving(arrived) && requires_elevation) + return + + // Its floating but it may touch down + if (arrived.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) + RegisterSignal(arrived, COMSIG_MOVETYPE_FLAG_DISABLED, PROC_REF(on_move_flag_disabled)) + return + + if (!isliving(arrived)) + trigger_effect(arrived) + return + + if (requires_elevation) + // We want to know when they touch down so we can interact with them + RegisterSignal(arrived, SIGNAL_ADDTRAIT(TRAIT_MOB_ELEVATED), PROC_REF(on_mob_elevated)) + // The trait is kept even if the mob is buckled which is weird but plays into our hand here + if (!HAS_TRAIT(arrived, TRAIT_MOB_ELEVATED)) + return + + trigger_effect(arrived) + +/datum/component/material_turf_tracking/proc/on_exited(datum/source, atom/movable/gone) + SIGNAL_HANDLER + + UnregisterSignal(gone, list(SIGNAL_ADDTRAIT(TRAIT_MOB_ELEVATED), COMSIG_MOVETYPE_FLAG_DISABLED)) + +/datum/component/material_turf_tracking/proc/trigger_effect(atom/movable/arrived) + if (!isliving(arrived)) + SEND_SIGNAL(owner_material, COMSIG_MATERIAL_EFFECT_STEP, parent, arrived, null, null, FALSE) + return + + var/mob/living/victim = arrived + var/skin_contact = FEET + if (victim.body_position == LYING_DOWN) + skin_contact = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + + for (var/obj/item/worn_item in victim.get_equipped_items(INCLUDE_ABSTRACT)) + skin_contact &= ~worn_item.body_parts_covered + if (!skin_contact) + break + + SEND_SIGNAL(owner_material, COMSIG_MATERIAL_EFFECT_STEP, parent, arrived, null, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG), !!skin_contact) + +/datum/component/material_turf_tracking/proc/on_mob_elevated(mob/living/source, trait) + if (source.throwing || source.invisibility >= INVISIBILITY_ABSTRACT || (source.movement_type & MOVETYPES_NOT_TOUCHING_GROUND)) + return + + if (is_type_in_typecache(source, interaction_blacklist)) + return + + trigger_effect(source) + +/datum/component/material_turf_tracking/proc/on_move_flag_disabled(atom/movable/source, flag, old_state) + if (source.throwing || source.invisibility >= INVISIBILITY_ABSTRACT || (source.movement_type & MOVETYPES_NOT_TOUCHING_GROUND)) + return + + if (is_type_in_typecache(source, interaction_blacklist)) + return + + if (requires_elevation) + if (!isliving(source)) + return + RegisterSignal(source, SIGNAL_ADDTRAIT(TRAIT_MOB_ELEVATED), PROC_REF(on_mob_elevated)) + if (!HAS_TRAIT(source, TRAIT_MOB_ELEVATED)) + return + + trigger_effect(source) diff --git a/code/datums/components/twohanded.dm b/code/datums/components/twohanded.dm index 4414b466170..a65d8c4f3c7 100644 --- a/code/datums/components/twohanded.dm +++ b/code/datums/components/twohanded.dm @@ -147,6 +147,8 @@ RegisterSignal(parent, COMSIG_ITEM_SHARPEN_ACT, PROC_REF(on_sharpen)) RegisterSignal(parent, COMSIG_ITEM_APPLY_FANTASY_BONUSES, PROC_REF(apply_fantasy_bonuses)) RegisterSignal(parent, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, PROC_REF(remove_fantasy_bonuses)) + RegisterSignal(parent, COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, PROC_REF(on_materials_updated)) + RegisterSignal(parent, COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS, PROC_REF(on_materials_updated)) // Remove all siginals registered to the parent item /datum/component/two_handed/UnregisterFromParent() @@ -160,6 +162,8 @@ COMSIG_ITEM_SHARPEN_ACT, COMSIG_ITEM_APPLY_FANTASY_BONUSES, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, + COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, + COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS, )) /// Triggered on equip of the item containing the component @@ -419,6 +423,19 @@ unwield(source.loc) force_multiplier = source.reset_fantasy_variable("force_multiplier", force_multiplier) +/datum/component/two_handed/proc/on_materials_updated(obj/item/source, list/materials, datum/material/main_material) + SIGNAL_HANDLER + // With materials assigned we need to update our forces. + if (wielded) + // Materials modify force multiplicatively! Most of the time, for snowflakes they gotta handle it themselves + if (!isnull(force_wielded)) + force_unwielded *= source.force / force_wielded + force_wielded = source.force + else + if (!isnull(force_unwielded)) + force_wielded *= source.force / force_unwielded + force_unwielded = source.force + /** * The offhand dummy item for two handed items */ diff --git a/code/datums/elements/elevation.dm b/code/datums/elements/elevation.dm index a0c3da5f3ab..fcf6f524ff0 100644 --- a/code/datums/elements/elevation.dm +++ b/code/datums/elements/elevation.dm @@ -130,15 +130,19 @@ COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, COMSIG_TURF_RESET_ELEVATION, )) - REMOVE_TRAIT(source, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src)) for(var/mob/living/living in source) deelevate_mob(living) UnregisterSignal(living, list(COMSIG_LIVING_SET_BUCKLED, SIGNAL_ADDTRAIT(TRAIT_IGNORE_ELEVATION), SIGNAL_REMOVETRAIT(TRAIT_IGNORE_ELEVATION))) + REMOVE_TRAIT(source, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src)) return ..() /datum/element/elevation_core/proc/on_entered(turf/source, atom/movable/entered, atom/old_loc) SIGNAL_HANDLER - if((isnull(old_loc) || !HAS_TRAIT_FROM(old_loc, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src))) && isliving(entered)) + // If the movement has been aborted by something else within the chain we need to abort + if(!isliving(entered) || entered.loc != source) + return + + if(isnull(old_loc) || !HAS_TRAIT_FROM(old_loc, TRAIT_ELEVATED_TURF, ELEVATION_SOURCE(src))) register_new_mob(entered, elevate_time = isturf(old_loc) && source.Adjacent(old_loc) ? ELEVATE_TIME : 0) /datum/element/elevation_core/proc/on_initialized_on(turf/source, atom/movable/spawned) @@ -178,7 +182,6 @@ // we want to avoid accidentally double-elevating anything they're buckled to (namely vehicles) if(target.has_offset(source = ELEVATION_SOURCE(src))) return - ADD_TRAIT(target, TRAIT_MOB_ELEVATED, ELEVATION_SOURCE(src)) // We are buckled to something if(target.buckled) // We are buckled to a vehicle, so it also must be elevated @@ -189,15 +192,18 @@ pass() // We are buckled to some other object - perhaps the object itself - so skip else + ADD_TRAIT(target, TRAIT_MOB_ELEVATED, ELEVATION_SOURCE(src)) return + target.add_offsets(ELEVATION_SOURCE(src), z_add = pixel_shift, animate = elevate_time > 0) + ADD_TRAIT(target, TRAIT_MOB_ELEVATED, ELEVATION_SOURCE(src)) /// Reverts elevation of the mob. /datum/element/elevation_core/proc/deelevate_mob(mob/living/target, elevate_time = ELEVATE_TIME) - REMOVE_TRAIT(target, TRAIT_MOB_ELEVATED, ELEVATION_SOURCE(src)) target.remove_offsets(ELEVATION_SOURCE(src), animate = elevate_time > 0) if(isvehicle(target.buckled)) animate(target.buckled, pixel_z = -pixel_shift, time = elevate_time, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + REMOVE_TRAIT(target, TRAIT_MOB_ELEVATED, ELEVATION_SOURCE(src)) /** * If the mob is buckled or unbuckled to/from a vehicle, shift it up/down diff --git a/code/datums/elements/loomable.dm b/code/datums/elements/loomable.dm index 76ee071a9a2..ca32bde165b 100644 --- a/code/datums/elements/loomable.dm +++ b/code/datums/elements/loomable.dm @@ -22,7 +22,7 @@ loom_type = /obj/structure/loom, process_completion_verb = "spun", target_needs_anchoring = TRUE, - loom_time = 1 SECONDS + loom_time = 1 SECONDS, ) . = ..() //currently this element only works for items as we need to call /obj/item/attack_atom() @@ -80,7 +80,8 @@ break if(!stack_we_use.use(required_amount)) - user.balloon_alert(user, "need [required_amount] of [source]!") + if (!spawning_amount) + user.balloon_alert(user, "need [required_amount] of [source]!") break spawning_amount++ @@ -96,8 +97,13 @@ if(spawning_amount == 0) return - var/new_thing - for(var/repeated in 1 to spawning_amount) - new_thing = new resulting_atom(target.drop_location()) - + var/atom/new_thing = null + if (ispath(resulting_atom, /obj/item/stack)) + var/obj/item/stack/stack_type = resulting_atom + while (spawning_amount > 0) + new_thing = new resulting_atom(target.drop_location(), new_amount = min(spawning_amount, stack_type::max_amount)) + spawning_amount -= stack_type::max_amount + else + for(var/repeated in 1 to spawning_amount) + new_thing = new resulting_atom(target.drop_location()) user.balloon_alert_to_viewers("[process_completion_verb] [new_thing]") diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index f830fa5b7b5..5d34b97c75d 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -20,6 +20,9 @@ Simple datum which is instanced once per type and is used for every object of sa var/mat_flags = NONE /// List of material property IDs to their values, 0 - 10 var/mat_properties = null + /// Flags for which comsigs we should track/send + /// These exist for performance reasons as to avoid unnecessary work on materials without properties that trigger off these, or doing the same checks for each property + var/track_flags = NONE // Color values /// 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. @@ -99,16 +102,164 @@ 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, mat_amount, multiplier) +/// This proc is called when the material is added to an object. +/// Can be called even if the material is covered by a slot +/datum/material/proc/on_applied(atom/source, mat_amount, multiplier, from_slot) SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_MATERIAL_APPLIED, source, mat_amount, multiplier) + SEND_SIGNAL(src, COMSIG_MATERIAL_APPLIED, source, mat_amount, multiplier, from_slot) -///This proc is called when the material becomes the one the object is composed of the most + if (!(source.material_flags & MATERIAL_EFFECTS) || from_slot) + return + + if (track_flags & MATERIAL_TRACK_CONTACT) + var/static/list/turf_interactions = typecacheof(list( + /turf/open, + /obj/structure/platform, + /obj/structure/table, + /obj/structure/rack, + /obj/structure/bed, + /obj/structure/closet/crate, + /obj/structure/reagent_dispensers, + /obj/structure/altar, + )) + if (is_type_in_typecache(source, turf_interactions)) + source.AddComponent(/datum/component/material_turf_tracking, src) + + if (isclosedturf(source)) + RegisterSignal(source, COMSIG_LIVING_DISARM_COLLIDE, PROC_REF(on_wall_shove_collide)) + + if (track_flags & MATERIAL_TRACK_IMPACT) + RegisterSignal(source, COMSIG_MOVABLE_IMPACT, PROC_REF(on_throw_impact)) + RegisterSignal(source, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(on_throw_impact_living)) + RegisterSignal(source, COMSIG_ITEM_ATTACK, PROC_REF(on_item_attack)) + RegisterSignal(source, COMSIG_ITEM_ATTACK_ATOM, PROC_REF(on_item_attack)) + // Allow recipe crafting for stack items + if(!isstack(source)) + RegisterSignal(source, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_item_attack_self)) + RegisterSignal(source, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(on_item_attack_living)) + +/// This proc is called when the material becomes the one the object is composed of the most +/// Only called when the material isn't assigned to a slot /datum/material/proc/on_main_applied(atom/source, mat_amount, multiplier) SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_MATERIAL_MAIN_APPLIED, source, mat_amount, multiplier) +/// This proc is called when the material is removed from an object. +/datum/material/proc/on_removed(atom/source, mat_amount, material_flags, from_slot) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MATERIAL_REMOVED, source, mat_amount, material_flags, from_slot) + + if (!(source.material_flags & MATERIAL_EFFECTS)) + return + + if (track_flags & MATERIAL_TRACK_CONTACT) + var/static/list/material_signals = list( + COMSIG_LIVING_DISARM_COLLIDE, + ) + UnregisterSignal(source, material_signals) + var/list/tracker_components = source.GetComponents(/datum/component/material_turf_tracking) + if (istype(tracker_components, /datum/component/material_turf_tracking)) + qdel(tracker_components) + else + // Delete all trackers linked to ourselves (might be multiple if we've got multiple slots going on) + for (var/datum/component/material_turf_tracking/tracker as anything in tracker_components) + if (tracker.owner_material == src) + qdel(tracker) + + if (track_flags & MATERIAL_TRACK_IMPACT) + var/static/list/material_signals = list( + COMSIG_MOVABLE_IMPACT, + COMSIG_MOVABLE_IMPACT_ZONE, + COMSIG_ITEM_ATTACK, + COMSIG_ITEM_ATTACK_ATOM, + COMSIG_ITEM_ATTACK_SELF, + COMSIG_ITEM_ATTACK_ZONE, + ) + UnregisterSignal(source, material_signals) + +/// 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) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MATERIAL_MAIN_REMOVED, source, mat_amount, multiplier) + +/datum/material/proc/on_wall_shove_collide(turf/closed/source, mob/living/shover, mob/living/target, shove_flags, obj/item/weapon) + SIGNAL_HANDLER + + // If any part is exposed it makes sense it'd impact the wall + var/skin_contact = HEAD|CHEST|GROIN|LEGS|FEET|ARMS|HANDS + for (var/obj/item/worn_item in target.get_equipped_items(INCLUDE_ABSTRACT)) + skin_contact &= ~worn_item.body_parts_covered + if (!skin_contact) + break + + SEND_SIGNAL(src, COMSIG_MATERIAL_EFFECT_TOUCH, source, target, shover, null, !!skin_contact) + +/datum/material/proc/on_item_attack(obj/item/source, mob/living/target, mob/living/user) + SIGNAL_HANDLER + impact_affect_touch(source, user, user) + // Living mobs use a different signal + if (!isliving(target)) + impact_affect_target(source, target, user) + +/datum/material/proc/on_item_attack_living(obj/item/source, mob/living/target, mob/living/user, def_zone) + SIGNAL_HANDLER + var/skin_contact = body_zone2cover_flags(def_zone) + for (var/obj/item/worn_item in target.get_equipped_items(INCLUDE_ABSTRACT)) + skin_contact &= ~worn_item.body_parts_covered + if (!skin_contact) + break + + impact_affect_target(source, target, user, def_zone, !!skin_contact) + +/datum/material/proc/on_item_attack_self(obj/item/source, mob/living/user) + SIGNAL_HANDLER + impact_affect_touch(source, user, user) + +/datum/material/proc/on_throw_impact(obj/item/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught) + SIGNAL_HANDLER + if (caught) + impact_affect_touch(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + else if (!isliving(hit_atom)) // Hit mobs have armor checking + impact_affect_throw_impact(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + +/datum/material/proc/on_throw_impact_living(obj/item/source, mob/living/target, def_zone, blocked, datum/thrownthing/throwing_datum) + SIGNAL_HANDLER + + var/skin_contact = body_zone2cover_flags(def_zone) + for (var/obj/item/worn_item in target.get_equipped_items(INCLUDE_ABSTRACT)) + skin_contact &= ~worn_item.body_parts_covered + if (!skin_contact) + break + + impact_affect_throw_impact(source, target, astype(throwing_datum.thrower.resolve(), /mob/living), def_zone, !!skin_contact) + +/datum/material/proc/impact_affect_touch(obj/item/source, mob/living/user, mob/living/initiator) + var/arm_dir = IS_LEFT_INDEX(user.active_hand_index) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM + if (!ishuman(user)) + SEND_SIGNAL(src, COMSIG_MATERIAL_EFFECT_TOUCH, source, user, initiator, arm_dir, TRUE) + return + + var/mob/living/carbon/human/as_human = user + var/obj/item/bodypart/hand = as_human.has_hand_for_held_index(as_human.get_held_index_of_item(source)) + if (!hand) + SEND_SIGNAL(src, COMSIG_MATERIAL_EFFECT_TOUCH, source, user, initiator, arm_dir, FALSE) + return + + var/list/obj/item/hand_covers = as_human.get_clothing_on_part(hand) + var/hand_covered = FALSE + for (var/obj/item/worn_item in hand_covers) + if (worn_item.body_parts_covered & HANDS) + hand_covered = TRUE + break + + SEND_SIGNAL(src, COMSIG_MATERIAL_EFFECT_TOUCH, source, user, initiator, hand.body_zone, !hand_covered) + +/datum/material/proc/impact_affect_target(obj/item/source, atom/target, mob/living/user, def_zone, skin_contact = TRUE) + SEND_SIGNAL(src, COMSIG_MATERIAL_EFFECT_HIT, source, target, user, def_zone, skin_contact) + +/datum/material/proc/impact_affect_throw_impact(obj/item/source, atom/target, mob/living/user, def_zone, skin_contact = TRUE) + SEND_SIGNAL(src, COMSIG_MATERIAL_EFFECT_THROW_IMPACT, source, target, user, def_zone, skin_contact) + /datum/material/proc/setup_glow(turf/on) if(GET_TURF_PLANE_OFFSET(on) != GET_LOWEST_STACK_OFFSET(on.z)) // We ain't the bottom brother return @@ -127,15 +278,6 @@ 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) -/// This proc is called when the material is removed from an object. -/datum/material/proc/on_removed(atom/source, amount, material_flags) - SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_MATERIAL_REMOVED, source, amount, material_flags) - -/// 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) - SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_MATERIAL_MAIN_REMOVED, source, mat_amount, multiplier) ////Called in `/datum/component/edible/proc/on_material_effects` /datum/material/proc/on_edible_applied(atom/source, datum/component/edible/edible) diff --git a/code/datums/materials/alloys.dm b/code/datums/materials/alloys.dm index 6d90eb4ff1a..861be125aef 100644 --- a/code/datums/materials/alloys.dm +++ b/code/datums/materials/alloys.dm @@ -44,15 +44,15 @@ composition = list(/datum/material/iron = 1, /datum/material/plasma = 1) mat_rust_resistance = RUST_RESISTANCE_REINFORCED -/datum/material/alloy/plasteel/on_applied(atom/target, mat_amount, multiplier) +/datum/material/alloy/plasteel/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(istype(target, /obj/item/fishing_rod)) - ADD_TRAIT(target, TRAIT_ROD_LAVA_USABLE, REF(src)) + if(istype(source, /obj/item/fishing_rod)) + ADD_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) -/datum/material/alloy/plasteel/on_removed(atom/target, mat_amount, multiplier) +/datum/material/alloy/plasteel/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(istype(target, /obj/item/fishing_rod)) - REMOVE_TRAIT(target, TRAIT_ROD_LAVA_USABLE, REF(src)) + if(istype(source, /obj/item/fishing_rod)) + REMOVE_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) /** * Plastitanium @@ -78,15 +78,15 @@ composition = list(/datum/material/titanium = 1, /datum/material/plasma = 1) mat_rust_resistance = RUST_RESISTANCE_TITANIUM -/datum/material/alloy/plastitanium/on_applied(atom/target, mat_amount, multiplier) +/datum/material/alloy/plastitanium/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(istype(target, /obj/item/fishing_rod)) - ADD_TRAIT(target, TRAIT_ROD_LAVA_USABLE, REF(src)) + if(istype(source, /obj/item/fishing_rod)) + ADD_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) -/datum/material/alloy/plastitanium/on_removed(atom/target, mat_amount, multiplier) +/datum/material/alloy/plastitanium/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(istype(target, /obj/item/fishing_rod)) - REMOVE_TRAIT(target, TRAIT_ROD_LAVA_USABLE, REF(src)) + if(istype(source, /obj/item/fishing_rod)) + REMOVE_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) /** * Plasmaglass @@ -194,16 +194,16 @@ value_per_unit = 0.4 composition = list(/datum/material/iron = 2, /datum/material/plasma = 2) -/datum/material/alloy/alien/on_applied(atom/target, mat_amount, multiplier) +/datum/material/alloy/alien/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(isobj(target)) - target.AddElement(/datum/element/obj_regen, _rate=0.02) // 2% regen per tick. - if(istype(target, /obj/item/fishing_rod)) - ADD_TRAIT(target, TRAIT_ROD_LAVA_USABLE, REF(src)) + if(isobj(source)) + source.AddElement(/datum/element/obj_regen, _rate=0.02) // 2% regen per tick. + if(istype(source, /obj/item/fishing_rod)) + ADD_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) -/datum/material/alloy/alien/on_removed(atom/target, mat_amount, multiplier) +/datum/material/alloy/alien/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(isobj(target)) - target.RemoveElement(/datum/element/obj_regen, _rate=0.02) - if(istype(target, /obj/item/fishing_rod)) - REMOVE_TRAIT(target, TRAIT_ROD_LAVA_USABLE, REF(src)) + if(isobj(source)) + source.RemoveElement(/datum/element/obj_regen, _rate=0.02) + if(istype(source, /obj/item/fishing_rod)) + REMOVE_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 412e94090d9..4284503cede 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -89,6 +89,7 @@ MATERIAL_ELECTRICAL = 9, MATERIAL_THERMAL = 4, MATERIAL_CHEMICAL = 4, + MATERIAL_VAMPIRES_BANE = 5, ) sheet_type = /obj/item/stack/sheet/mineral/silver ore_type = /obj/item/stack/ore/silver @@ -209,7 +210,8 @@ MATERIAL_ELECTRICAL = 10, MATERIAL_THERMAL = 8, MATERIAL_CHEMICAL = 0, - MATERIAL_FLAMMABILITY = 9, // Literally sets itself on fire from any excitement + MATERIAL_FLAMMABILITY = 10, // Literally sets itself on fire from any excitement + MATERIAL_FIRESTACKER = 1, ) sheet_type = /obj/item/stack/sheet/mineral/plasma ore_type = /obj/item/stack/ore/plasma @@ -218,22 +220,19 @@ mineral_rarity = MATERIAL_RARITY_PRECIOUS points_per_unit = 15 / SHEET_MATERIAL_AMOUNT -/datum/material/plasma/on_applied(atom/source, mat_amount, multiplier) +/datum/material/plasma/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() - if(ismovable(source)) - source.AddElement(/datum/element/firestacker, 1 * multiplier) source.AddComponent(/datum/component/combustible_flooder, GAS_PLASMA, mat_amount * 0.05 * multiplier) //Empty temp arg, fully dependent on whatever ignited it. if(istype(source, /obj/item/fishing_rod)) ADD_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) -/datum/material/plasma/on_removed(atom/source, mat_amount, multiplier) +/datum/material/plasma/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() - source.RemoveElement(/datum/element/firestacker, mat_amount = 1 * multiplier) qdel(source.GetComponent(/datum/component/combustible_flooder)) if(istype(source, /obj/item/fishing_rod)) ADD_TRAIT(source, TRAIT_ROD_LAVA_USABLE, REF(src)) -///Can cause bluespace effects on use. (Teleportation) (Not yet implemented) +/// Can cause bluespace effects on use. (Teleportation) /datum/material/bluespace name = "bluespace crystal" desc = "Crystals with bluespace properties." @@ -250,6 +249,7 @@ MATERIAL_THERMAL = 4, MATERIAL_CHEMICAL = 4, MATERIAL_BEAUTY = 0.5, // Absolutely mesmerizing + MATERIAL_TELEPORTING = 5, ) sheet_type = /obj/item/stack/sheet/bluespace_crystal ore_type = /obj/item/stack/ore/bluespace_crystal @@ -306,7 +306,7 @@ mineral_rarity = MATERIAL_RARITY_UNDISCOVERED points_per_unit = 60 / SHEET_MATERIAL_AMOUNT -/datum/material/bananium/on_applied(atom/source, mat_amount, multiplier) +/datum/material/bananium/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() 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)) @@ -332,7 +332,7 @@ ) rewards += pick_weight(funny_fish) -/datum/material/bananium/on_removed(atom/source, mat_amount, multiplier) +/datum/material/bananium/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() qdel(source.GetComponent(/datum/component/slippery)) qdel(source.GetComponent(/datum/component/squeak)) @@ -391,12 +391,12 @@ mineral_rarity = MATERIAL_RARITY_UNDISCOVERED points_per_unit = 100 / SHEET_MATERIAL_AMOUNT -/datum/material/runite/on_applied(atom/source, mat_amount, multiplier) +/datum/material/runite/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() if(istype(source, /obj/item/fishing_rod)) ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //light-absorbing, environment-cancelling fishing rod. -/datum/material/runite/on_removed(atom/source, mat_amount, multiplier) +/datum/material/runite/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() if(istype(source, /obj/item/fishing_rod)) REMOVE_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //light-absorbing, environment-cancelling fishing rod. @@ -484,12 +484,12 @@ mineral_rarity = MATERIAL_RARITY_UNDISCOVERED // Doesn't naturally spawn on lavaland. points_per_unit = 100 / SHEET_MATERIAL_AMOUNT -/datum/material/adamantine/on_applied(atom/source, mat_amount, multiplier) +/datum/material/adamantine/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() if(istype(source, /obj/item/fishing_rod)) ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) // light-absorbing, environment-cancelling fishing rod. -/datum/material/adamantine/on_removed(atom/source, mat_amount, multiplier) +/datum/material/adamantine/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() if(istype(source, /obj/item/fishing_rod)) REMOVE_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) // light-absorbing, environment-cancelling fishing rod. @@ -522,13 +522,13 @@ mineral_rarity = MATERIAL_RARITY_UNDISCOVERED // Doesn't naturally spawn on lavaland. points_per_unit = 100 / SHEET_MATERIAL_AMOUNT -/datum/material/mythril/on_applied(atom/source, mat_amount, multiplier) +/datum/material/mythril/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() 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(atom/source, mat_amount, multiplier) +/datum/material/mythril/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() if(isitem(source)) REMOVE_TRAIT(source, TRAIT_INNATELY_FANTASTICAL_ITEM, REF(src)) // DO THIS FIRST OR WE WILL NEVER GET OUR BONUSES DELETED!!! @@ -557,16 +557,17 @@ MATERIAL_THERMAL = 8, MATERIAL_CHEMICAL = 4, MATERIAL_FLAMMABILITY = 10, + MATERIAL_FIRESTACKER = 1, ) sheet_type = /obj/item/stack/sheet/hot_ice material_reagent = /datum/reagent/toxin/hot_ice value_per_unit = 400 / SHEET_MATERIAL_AMOUNT -/datum/material/hot_ice/on_applied(atom/source, mat_amount, multiplier) +/datum/material/hot_ice/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() source.AddComponent(/datum/component/combustible_flooder, GAS_PLASMA, mat_amount * 1.5 * multiplier, (mat_amount * 0.2 + 300) * multiplier) -/datum/material/hot_ice/on_removed(atom/source, mat_amount, multiplier) +/datum/material/hot_ice/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() qdel(source.GetComponent(/datum/component/combustible_flooder)) @@ -603,7 +604,7 @@ color = "#EDC9AF" mat_flags = MATERIAL_BASIC_RECIPES | MATERIAL_CLASS_AMORPHOUS mat_properties = list( - MATERIAL_DENSITY = 2, + MATERIAL_DENSITY = 3, MATERIAL_HARDNESS = 0, MATERIAL_FLEXIBILITY = 0, MATERIAL_REFLECTIVITY = 7, @@ -679,13 +680,13 @@ MATERIAL_THERMAL = 1, MATERIAL_CHEMICAL = 8, ) + material_reagent = list(/datum/reagent/iron = 1, /datum/reagent/fuel/unholywater = 2) sheet_type = /obj/item/stack/sheet/runed_metal value_per_unit = 1500 / SHEET_MATERIAL_AMOUNT texture_layer_icon_state = "runed" /datum/material/runedmetal/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) . = ..() - victim.reagents.add_reagent(/datum/reagent/fuel/unholywater, rand(8, 12)) if(!HAS_TRAIT(victim, TRAIT_ROCK_EATER)) victim.apply_damage(10, BRUTE, BODY_ZONE_HEAD, wound_bonus = 5) return TRUE @@ -869,12 +870,12 @@ material_reagent = /datum/reagent/toxin/plasma value_per_unit = 900 / SHEET_MATERIAL_AMOUNT -/datum/material/zaukerite/on_applied(atom/source, mat_amount, multiplier) +/datum/material/zaukerite/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() if(istype(source, /obj/item/fishing_rod)) ADD_TRAIT(source, TRAIT_ROD_IGNORE_ENVIRONMENT, REF(src)) //light-absorbing, environment-cancelling fishing rod. -/datum/material/zaukerite/on_removed(atom/source, mat_amount, multiplier) +/datum/material/zaukerite/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() if(istype(source, /obj/item/fishing_rod)) REMOVE_TRAIT(source, TRAIT_ROD_IGNORE_ENVIRONMENT, REF(src)) //light-absorbing, environment-cancelling fishing rod. @@ -884,3 +885,44 @@ if(!HAS_TRAIT(victim, TRAIT_ROCK_EATER)) victim.apply_damage(30, BURN, BODY_ZONE_HEAD, wound_bonus = 5) return TRUE + +/// Evil and very unstable version of bluespace crystals +/datum/material/telecrystal + name = "telecrystal" + desc = "An ominous-looking gemstone capable of transporting objects vast distances through bluespace." + color = "#BD1B28" + alpha = 200 + starlight_color = COLOR_SYNDIE_RED + mat_flags = MATERIAL_BASIC_RECIPES | MATERIAL_CLASS_CRYSTAL | MATERIAL_CLASS_RIGID + mat_properties = list( + MATERIAL_DENSITY = 1, + MATERIAL_HARDNESS = 4, + MATERIAL_FLEXIBILITY = 0, + MATERIAL_REFLECTIVITY = 10, + MATERIAL_ELECTRICAL = 10, + MATERIAL_THERMAL = 2, + MATERIAL_CHEMICAL = 8, + MATERIAL_BEAUTY = -0.5, // very evil bad no good + MATERIAL_TELEPORTING = 8, + MATERIAL_PENETRATING = TRUE, + ) + sheet_type = /obj/item/stack/sheet/telepolycrystal + material_reagent = list(/datum/reagent/bluespace = 1, /datum/reagent/medicine/stimulants = 1) // We don't have liquid telecrystals and I don't wanna risk it + value_per_unit = 1200 / SHEET_MATERIAL_AMOUNT + texture_layer_icon_state = "shine" + +/datum/material/telecrystal/on_main_applied(atom/source, mat_amount, multiplier) + . = ..() + if(istype(source, /obj/item/fishing_rod)) + RegisterSignal(source, COMSIG_ROD_BEGIN_FISHING, PROC_REF(on_begin_fishing)) + +/datum/material/telecrystal/on_main_removed(atom/source, mat_amount, multiplier) + . = ..() + if(istype(source, /obj/item/fishing_rod)) + UnregisterSignal(source, COMSIG_ROD_BEGIN_FISHING) + +/datum/material/telecrystal/proc/on_begin_fishing(obj/item/fishing_rod/rod, datum/fishing_challenge/challenge) + SIGNAL_HANDLER + // Oops, all chainsawfish! + challenge.register_reward_signals(GLOB.preset_fish_sources[/datum/fish_source/portal/syndicate]) + diff --git a/code/datums/materials/material_slots/_slot.dm b/code/datums/materials/material_slots/_slot.dm new file mode 100644 index 00000000000..239458f3981 --- /dev/null +++ b/code/datums/materials/material_slots/_slot.dm @@ -0,0 +1,19 @@ +/// Singleton datum which controls how materials affect atoms they're applied to +/datum/material_slot + abstract_type = /datum/material_slot + /// Name of the slot for autolathe UI + var/name = "error" + /// Material requirement type which controls what materials can be used to fill this slot when printing an item + var/datum/material_requirement/requirement_type = null + /// Relative amount of material in this slot for when multiple slots are filled with a single material + var/material_amount = 1 + +/// Called when the material in this slot is applied to the atom. Return FALSE to prevent base apply_single_mat_effect from running. +/// If the material is main, main material application will also be cancelled. Should be consistent with on_removed. +/datum/material_slot/proc/on_applied(atom/target, datum/material/material, amount, multiplier) + return TRUE + +/// Called when the material in this slot is removed from the atom. Return FALSE to prevent base remove_single_mat_effect from running. +/// If the material is main, main material removal will also be cancelled. Should be consistent with on_applied. +/datum/material_slot/proc/on_removed(atom/target, datum/material/material, amount, multiplier) + return TRUE diff --git a/code/datums/materials/material_slots/generic.dm b/code/datums/materials/material_slots/generic.dm new file mode 100644 index 00000000000..971ae28b612 --- /dev/null +++ b/code/datums/materials/material_slots/generic.dm @@ -0,0 +1,210 @@ +// Generic slots for weapons + +/// Generic main/parent type for all weapon heads +/datum/material_slot/weapon_head + name = "weapon head" + requirement_type = /datum/material_requirement/solid_material + +/datum/material_slot/weapon_head/on_applied(obj/item/target, datum/material/material, amount, multiplier) + // Weapon head controls strength and conductivity + if (!(target.material_flags & MATERIAL_EFFECTS)) + return FALSE + + // Effect signals + RegisterSignal(target, COMSIG_MOVABLE_IMPACT, PROC_REF(on_throw_impact)) + RegisterSignal(target, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(on_throw_impact_living)) + RegisterSignal(target, COMSIG_ITEM_ATTACK, PROC_REF(on_item_attack)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_ATOM, PROC_REF(on_item_attack)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(on_item_attack_living)) + + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS)) + return FALSE + + // Damage + target.change_material_strength(material, amount, multiplier) + + // Conductivity + var/conductivity = material.get_property(MATERIAL_ELECTRICAL) + var/siemens_modifier = round(max(0, conductivity - 1) ** 1.18 * 0.15, 0.01) + var/siemens_mult = 1 + (siemens_modifier - 1) * multiplier + target.siemens_coefficient *= max(0, siemens_mult) + + if (target.siemens_coefficient == 0) + target.obj_flags &= ~CONDUCTS_ELECTRICITY + +/datum/material_slot/weapon_head/on_removed(obj/item/target, datum/material/material, amount, multiplier) + var/static/list/interaction_signals = list( + COMSIG_MOVABLE_IMPACT, + COMSIG_MOVABLE_IMPACT_ZONE, + COMSIG_ITEM_ATTACK, + COMSIG_ITEM_ATTACK_ATOM, + COMSIG_ITEM_ATTACK_ZONE, + ) + UnregisterSignal(target, interaction_signals) + + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS) || !(target.material_flags & MATERIAL_EFFECTS)) + return FALSE + + // Damage + target.change_material_strength(material, amount, multiplier, remove = TRUE) + + // Conductivity + var/conductivity = material.get_property(MATERIAL_ELECTRICAL) + var/siemens_modifier = round(max(0, conductivity - 1) ** 1.18 * 0.15, 0.01) + var/siemens_mult = 1 + (siemens_modifier - 1) * multiplier + if (siemens_mult > 0) + target.siemens_coefficient /= siemens_mult + + if (target.siemens_coefficient > 0 && (initial(target.obj_flags) & CONDUCTS_ELECTRICITY) && !(target.obj_flags & CONDUCTS_ELECTRICITY)) + target.obj_flags |= CONDUCTS_ELECTRICITY + +/datum/material_slot/weapon_head/proc/on_throw_impact(obj/item/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught) + SIGNAL_HANDLER + if (!caught && !isliving(hit_atom)) + affect_throw_impact(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + +/datum/material_slot/weapon_head/proc/on_item_attack(obj/item/source, atom/movable/target, mob/living/user) + SIGNAL_HANDLER + // Living mobs use a different signal + if (!isliving(target)) + affect_target(source, target, user) + +/datum/material_slot/weapon_head/proc/on_item_attack_living(obj/item/source, mob/living/target, mob/living/user, def_zone) + SIGNAL_HANDLER + + var/skin_contact = body_zone2cover_flags(def_zone) + for (var/obj/item/worn_item in target.get_equipped_items(INCLUDE_ABSTRACT)) + skin_contact &= ~worn_item.body_parts_covered + if (!skin_contact) + break + + affect_target(source, target, user, def_zone, !!skin_contact) + +/datum/material_slot/weapon_head/proc/on_throw_impact_living(obj/item/source, mob/living/target, def_zone, blocked, datum/thrownthing/throwing_datum) + SIGNAL_HANDLER + + var/skin_contact = body_zone2cover_flags(def_zone) + for (var/obj/item/worn_item in target.get_equipped_items(INCLUDE_ABSTRACT)) + skin_contact &= ~worn_item.body_parts_covered + if (!skin_contact) + break + + affect_throw_impact(source, target, astype(throwing_datum.thrower.resolve(), /mob/living), def_zone, !!skin_contact) + +/datum/material_slot/weapon_head/proc/affect_target(obj/item/source, atom/target, mob/living/user, def_zone, skin_contact = TRUE) + var/datum/material/source_mat = source.get_material_from_slot(type) + SEND_SIGNAL(source_mat, COMSIG_MATERIAL_EFFECT_HIT, source, target, user, def_zone, skin_contact) + +/datum/material_slot/weapon_head/proc/affect_throw_impact(obj/item/source, atom/target, mob/living/user, def_zone, skin_contact = TRUE) + var/datum/material/source_mat = source.get_material_from_slot(type) + SEND_SIGNAL(source_mat, COMSIG_MATERIAL_EFFECT_THROW_IMPACT, source, target, user, def_zone, skin_contact) + +/// Main type for all weapon handles +/datum/material_slot/handle + name = "handle" + requirement_type = /datum/material_requirement/solid_material + +/datum/material_slot/handle/on_applied(obj/item/target, datum/material/material, amount, multiplier) + // Handle controls integrity, armor, conductivity and wieldiness stats-wise + if (!(target.material_flags & MATERIAL_EFFECTS)) + return FALSE + + // Effect signals + RegisterSignal(target, COMSIG_MOVABLE_IMPACT, PROC_REF(on_throw_impact)) + RegisterSignal(target, COMSIG_ITEM_ATTACK, PROC_REF(on_item_attack)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_ATOM, PROC_REF(on_item_attack)) + RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_item_attack_self)) + + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS)) + return FALSE + + // Armor/integrity + var/integrity_mod = material.get_property(MATERIAL_INTEGRITY) + target.modify_max_integrity(ceil(target.max_integrity * integrity_mod)) + var/list/armor_mods = material.get_armor_modifiers(multiplier) + target.set_armor(target.get_armor().generate_new_with_multipliers(armor_mods)) + + // Conductivity + var/conductivity = material.get_property(MATERIAL_ELECTRICAL) + var/siemens_modifier = round(max(0, conductivity - 1) ** 1.18 * 0.15, 0.01) + var/siemens_mult = 1 + (siemens_modifier - 1) * multiplier + target.siemens_coefficient *= max(0, siemens_mult) + + if (target.siemens_coefficient == 0) + target.obj_flags &= ~CONDUCTS_ELECTRICITY + + // Wielding + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + // Can be faster/slower by 2 dcs + target.attack_speed += MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.5 * multiplier + target.throw_range += ((hardness - 4) - (density - 4) * 2) * multiplier + return FALSE + +/datum/material_slot/handle/on_removed(obj/item/target, datum/material/material, amount, multiplier) + UnregisterSignal(target, list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_ATOM, COMSIG_ITEM_ATTACK_SELF)) + + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS) || !(target.material_flags & MATERIAL_EFFECTS)) + return FALSE + + // Armor/integrity + var/integrity_mod = material.get_property(MATERIAL_INTEGRITY) + + target.modify_max_integrity(ceil(target.max_integrity * integrity_mod)) + var/list/armor_mods = material.get_armor_modifiers(multiplier) + for (var/armor_type, value in armor_mods) + if (value != 0) // Needs to be restored to initial values in finalize effects, sorry + armor_mods[armor_type] = 1 / value + target.set_armor(target.get_armor().generate_new_with_multipliers(armor_mods)) + + // Conductivity + var/conductivity = material.get_property(MATERIAL_ELECTRICAL) + var/siemens_modifier = round(max(0, conductivity - 1) ** 1.18 * 0.15, 0.01) + var/siemens_mult = 1 + (siemens_modifier - 1) * multiplier + if (siemens_mult > 0) + target.siemens_coefficient /= siemens_mult + + if (target.siemens_coefficient > 0 && (initial(target.obj_flags) & CONDUCTS_ELECTRICITY) && !(target.obj_flags & CONDUCTS_ELECTRICITY)) + target.obj_flags |= CONDUCTS_ELECTRICITY + + // Wielding + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + target.attack_speed -= MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.5 * multiplier + target.throw_range -= ((hardness - 4) - (density - 4) * 2) * multiplier + return FALSE + +/datum/material_slot/handle/proc/on_item_attack(obj/item/source, atom/movable/target, mob/living/user) + SIGNAL_HANDLER + affect_user(source, user, user) + +/datum/material_slot/handle/proc/on_item_attack_self(obj/item/source, mob/living/user) + SIGNAL_HANDLER + affect_user(source, user, user) + +/datum/material_slot/handle/proc/on_throw_impact(obj/item/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught) + SIGNAL_HANDLER + if (caught) + affect_user(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + +/datum/material_slot/handle/proc/affect_user(obj/item/source, mob/living/user, mob/living/initiator) + var/datum/material/source_mat = source.get_material_from_slot(type) + var/arm_dir = IS_LEFT_INDEX(user.active_hand_index) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM + if (!ishuman(user)) + SEND_SIGNAL(source_mat, COMSIG_MATERIAL_EFFECT_TOUCH, source, user, initiator, arm_dir, TRUE) + return + + var/mob/living/carbon/human/as_human = user + var/obj/item/bodypart/hand = as_human.has_hand_for_held_index(as_human.get_held_index_of_item(source)) + if (!hand) // ??? + SEND_SIGNAL(source_mat, COMSIG_MATERIAL_EFFECT_TOUCH, source, user, initiator, arm_dir, FALSE) // ...no hand, no skin contact? + return + + var/list/obj/item/hand_covers = as_human.get_clothing_on_part(hand) + var/hand_covered = FALSE + for (var/obj/item/worn_item in hand_covers) + if (worn_item.body_parts_covered & HANDS) + hand_covered = TRUE + break + + SEND_SIGNAL(source_mat, COMSIG_MATERIAL_EFFECT_TOUCH, source, user, initiator, hand.body_zone, !hand_covered) diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 8e33c31a50f..00c26c98797 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -8,7 +8,7 @@ mat_properties = list( MATERIAL_DENSITY = 5, MATERIAL_HARDNESS = 0, - MATERIAL_FLEXIBILITY = 6, + MATERIAL_FLEXIBILITY = 5, MATERIAL_REFLECTIVITY = 4, MATERIAL_ELECTRICAL = 8, MATERIAL_THERMAL = 4, @@ -34,7 +34,7 @@ if(!(organ::organ_flags & ORGAN_ORGANIC)) organ.organ_flags |= ORGAN_ORGANIC -/datum/material/meat/on_applied(atom/source, mat_amount, multiplier) +/datum/material/meat/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() if(IS_EDIBLE(source)) make_edible(source, mat_amount, multiplier) @@ -92,7 +92,7 @@ blood_dna_info = blood_dna,\ ) -/datum/material/meat/on_removed(atom/source, mat_amount, multiplier) +/datum/material/meat/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() source.RemoveComponentSource(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible) qdel(source.GetComponent(/datum/component/blood_walk)) diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 3eb8bb533e2..df77ba1d1e4 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -6,7 +6,7 @@ mat_properties = list( MATERIAL_DENSITY = 4, MATERIAL_HARDNESS = 1, - MATERIAL_FLEXIBILITY = 6, + MATERIAL_FLEXIBILITY = 5, MATERIAL_REFLECTIVITY = 2, MATERIAL_ELECTRICAL = 8, MATERIAL_THERMAL = 4, @@ -23,7 +23,7 @@ make_edible(source, mat_amount) ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //the fishing rod itself is the bait... sorta. -/datum/material/pizza/on_applied(atom/source, mat_amount, multiplier) +/datum/material/pizza/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() if(IS_EDIBLE(source)) make_edible(source, mat_amount, multiplier) @@ -54,7 +54,7 @@ eat_time = 3 SECONDS, \ tastes = /obj/item/food/pizza/margherita::tastes) -/datum/material/pizza/on_removed(atom/source, mat_amount, multiplier) +/datum/material/pizza/on_removed(atom/source, mat_amount, multiplier, from_slot) . = ..() source.RemoveComponentSource(SOURCE_EDIBLE_PIZZA_MAT, /datum/component/edible) diff --git a/code/datums/materials/properties/_properties.dm b/code/datums/materials/properties/_properties.dm index b9fa27e26a0..abb6dd6b8cc 100644 --- a/code/datums/materials/properties/_properties.dm +++ b/code/datums/materials/properties/_properties.dm @@ -11,6 +11,10 @@ /datum/material_property/proc/get_descriptor(value) return null +/// Returns the contents of the tooltip under our descriptor +/datum/material_property/proc/get_tooltip(value) + return "[value < 0 ? "-" : ""]\Roman[round(abs(value), 1)]" + /// Called whenever a material with this property initializes. Mostly used for behavior tracking on optional properties /datum/material_property/proc/attach_to(datum/material/material) return diff --git a/code/datums/materials/properties/derived.dm b/code/datums/materials/properties/derived.dm index 4c18c035de7..162c4954927 100644 --- a/code/datums/materials/properties/derived.dm +++ b/code/datums/materials/properties/derived.dm @@ -45,3 +45,14 @@ // Requires the material to be especially shiny or dull var/reflectivity = material.get_property(MATERIAL_REFLECTIVITY) return MATERIAL_PROPERTY_DIVERGENCE(reflectivity, 3, 6) * 0.05 + +/// Siemens coeff multiplier for our material +/datum/material_property/derived/insulation + id = MATERIAL_INSULATION + +/datum/material_property/derived/insulation/get_value(datum/material/material) + // [0 ~ 1] is fully insulating, (1 ~ 6] maps to (0 ~ 1] and [6 ~ 10] maps to [1 ~ 2] + // 1.18 and 0.15 here are to allow 6 to map to 1 and 10 to map to 2 and are pulled out of my ass (system in the desmos below) + // See https://www.desmos.com/calculator/rdbv1x8oty + var/conductivity = material.get_property(MATERIAL_ELECTRICAL) + return round(max(0, conductivity - 1) ** 1.18 * 0.15, 0.01) diff --git a/code/datums/materials/properties/optional.dm b/code/datums/materials/properties/optional.dm index 8982e0d5e7c..38d5287d3cf 100644 --- a/code/datums/materials/properties/optional.dm +++ b/code/datums/materials/properties/optional.dm @@ -33,16 +33,16 @@ RegisterSignal(material, COMSIG_MATERIAL_APPLIED, PROC_REF(on_applied)) RegisterSignal(material, COMSIG_MATERIAL_REMOVED, PROC_REF(on_removed)) -/datum/material_property/flammability/proc/on_applied(datum/material/source, atom/new_atom, mat_amount, multiplier) +/datum/material_property/flammability/proc/on_applied(datum/material/source, atom/new_atom, mat_amount, multiplier, from_slot) SIGNAL_HANDLER - if (isobj(new_atom) && (new_atom.material_flags & MATERIAL_AFFECT_STATISTICS) && source.get_property(id) > MINIMUM_FLAMMABILITY) + if (isobj(new_atom) && (new_atom.material_flags & MATERIAL_AFFECT_STATISTICS) && source.get_property(id) >= MINIMUM_FLAMMABILITY) new_atom.resistance_flags |= FLAMMABLE -/datum/material_property/flammability/proc/on_removed(datum/material/source, atom/old_atom, mat_amount, multiplier) +/datum/material_property/flammability/proc/on_removed(datum/material/source, atom/old_atom, mat_amount, multiplier, from_slot) SIGNAL_HANDLER - if (isobj(old_atom) && (old_atom.material_flags & MATERIAL_AFFECT_STATISTICS) && source.get_property(id) > MINIMUM_FLAMMABILITY && !(initial(old_atom.resistance_flags) & FLAMMABLE)) + if (isobj(old_atom) && (old_atom.material_flags & MATERIAL_AFFECT_STATISTICS) && source.get_property(id) >= MINIMUM_FLAMMABILITY && !(initial(old_atom.resistance_flags) & FLAMMABLE)) old_atom.resistance_flags &= ~FLAMMABLE #undef MINIMUM_FLAMMABILITY @@ -74,16 +74,135 @@ RegisterSignal(material, COMSIG_MATERIAL_APPLIED, PROC_REF(on_applied)) RegisterSignal(material, COMSIG_MATERIAL_REMOVED, PROC_REF(on_removed)) -/datum/material_property/radioactivity/proc/on_applied(datum/material/source, atom/new_atom, mat_amount, multiplier) +/datum/material_property/radioactivity/proc/on_applied(datum/material/source, atom/new_atom, mat_amount, multiplier, from_slot) SIGNAL_HANDLER // Uranium structures should irradiate, but not items, because item irradiation is a lot more annoying. if (!isitem(new_atom)) new_atom.AddElement(/datum/element/radioactive, chance = source.get_property(id) / URANIUM_RADIOACTIVITY * URANIUM_IRRADIATION_CHANCE * multiplier) -/datum/material_property/radioactivity/proc/on_removed(datum/material/source, atom/old_atom, mat_amount, multiplier) +/datum/material_property/radioactivity/proc/on_removed(datum/material/source, atom/old_atom, mat_amount, multiplier, from_slot) SIGNAL_HANDLER if (!isitem(old_atom)) old_atom.RemoveElement(/datum/element/radioactive, chance = source.get_property(id) / URANIUM_RADIOACTIVITY * URANIUM_IRRADIATION_CHANCE * multiplier) #undef URANIUM_RADIOACTIVITY + +/// Applies firestacks to affected mobs +/datum/material_property/firestacker + name = "Igniting" + id = MATERIAL_FIRESTACKER + +/datum/material_property/firestacker/get_descriptor(value) + return "igniting" + +/datum/material_property/firestacker/get_tooltip(value) + return "Applies [value] firestacks to affected mobs" + +/datum/material_property/firestacker/attach_to(datum/material/material) + . = ..() + material.track_flags |= MATERIAL_TRACK_CONTACT | MATERIAL_TRACK_IMPACT + var/static/list/interaction_signals = list( + COMSIG_MATERIAL_EFFECT_TOUCH, + COMSIG_MATERIAL_EFFECT_STEP, + COMSIG_MATERIAL_EFFECT_HIT, + COMSIG_MATERIAL_EFFECT_THROW_IMPACT, + ) + RegisterSignals(material, interaction_signals, PROC_REF(on_contact)) + +/datum/material_property/firestacker/proc/on_contact(datum/material/source, atom/object, mob/living/target, mob/living/user, def_zone, skin_contact) + SIGNAL_HANDLER + + // Floors don't trigger if you're wearing shoes because it'd be too cancer + if (isfloorturf(object) && !skin_contact && !source.get_property(MATERIAL_PENETRATING)) + return + + if (isliving(target)) + target.adjust_fire_stacks(source.get_property(id)) + +/// Deals additional burn damage to vampires, property value determines damage +/datum/material_property/vampires_bane + name = "Vampires' Bane" + id = MATERIAL_VAMPIRES_BANE + +/datum/material_property/vampires_bane/get_descriptor(value) + return "vampires' bane" + +/datum/material_property/vampires_bane/get_tooltip(value) + return "Deals [value] additional burn damage to vampires on contact" + +/datum/material_property/vampires_bane/attach_to(datum/material/material) + . = ..() + material.track_flags |= MATERIAL_TRACK_CONTACT | MATERIAL_TRACK_IMPACT + var/static/list/interaction_signals = list( + COMSIG_MATERIAL_EFFECT_TOUCH, + COMSIG_MATERIAL_EFFECT_STEP, + COMSIG_MATERIAL_EFFECT_HIT, + COMSIG_MATERIAL_EFFECT_THROW_IMPACT, + ) + RegisterSignals(material, interaction_signals, PROC_REF(on_contact)) + +/datum/material_property/vampires_bane/proc/on_contact(datum/material/source, atom/object, mob/living/target, mob/living/user, def_zone, skin_contact) + SIGNAL_HANDLER + + if (!isvampire(target) || (!skin_contact && !source.get_property(MATERIAL_PENETRATING))) + return + + to_chat(target, span_userdanger("Contact with [object] sears your undead flesh!")) + target.apply_damage(source.get_property(id), BURN, def_zone, wound_bonus = 10, wound_clothing = FALSE) + +/// Teleports targets who come into active contact with the material around, property value determines teleport radius and damage taken per teleport +/datum/material_property/teleporting + name = "Teleporting" + id = MATERIAL_TELEPORTING + +/datum/material_property/teleporting/get_descriptor(value) + return "dimensionally unstable" + +/datum/material_property/teleporting/get_tooltip(value) + return "Randomly teleports whoever comes into contact with it in a [value] tile radius" + +/datum/material_property/teleporting/attach_to(datum/material/material) + . = ..() + material.track_flags |= MATERIAL_TRACK_CONTACT | MATERIAL_TRACK_IMPACT + var/static/list/interaction_signals = list( + COMSIG_MATERIAL_EFFECT_TOUCH, + COMSIG_MATERIAL_EFFECT_STEP, + COMSIG_MATERIAL_EFFECT_HIT, + COMSIG_MATERIAL_EFFECT_THROW_IMPACT, + ) + RegisterSignals(material, interaction_signals, PROC_REF(on_contact)) + +/datum/material_property/teleporting/proc/on_contact(datum/material/source, atom/object, atom/target, mob/living/user, def_zone, skin_contact) + SIGNAL_HANDLER + + if (!ismovable(target)) + return + + var/atom/movable/as_movable = target + // Don't teleport airlocks around please + if (as_movable.anchored || as_movable.move_resist >= INFINITY) + return + + // Floors don't trigger if you're wearing shoes because it'd be too cancer + if (isfloorturf(object) && !skin_contact && !source.get_property(MATERIAL_PENETRATING)) + return + + var/value = source.get_property(id) + do_teleport(target, get_turf(target), value, channel = TELEPORT_CHANNEL_BLUESPACE) + if (isstack(object)) + var/obj/item/stack/as_stack = object + as_stack.use(1) + else if (object.uses_integrity) + object.take_damage(object.max_integrity * value * 0.01) + +/// Makes all contact count as skin contact +/datum/material_property/penetrating + name = "Penetrating" + id = MATERIAL_PENETRATING + +/datum/material_property/penetrating/get_descriptor(value) + return "dimensionally penetrating" + +/datum/material_property/penetrating/get_tooltip(value) + return "Ignores all means of skin protection when triggering other material effects" diff --git a/code/datums/materials/requirements/_requirement.dm b/code/datums/materials/requirements/_requirement.dm index 2447add5960..d23e11c3fb9 100644 --- a/code/datums/materials/requirements/_requirement.dm +++ b/code/datums/materials/requirements/_requirement.dm @@ -57,6 +57,9 @@ property_minimums = list( MATERIAL_HARDNESS = 2, ) + property_maximums = list( + MATERIAL_FLEXIBILITY = 5, + ) /datum/material_requirement/rigid_material required_flags = MATERIAL_CLASS_RIGID diff --git a/code/game/atom/atom_examine.dm b/code/game/atom/atom_examine.dm index a19b83ad84d..02e66ab749e 100644 --- a/code/game/atom/atom_examine.dm +++ b/code/game/atom/atom_examine.dm @@ -145,8 +145,9 @@ if (isnull(prop_value)) // Error? continue var/descriptor = property?.get_descriptor(prop_value) + var/tooltip_hint = property?.get_tooltip(prop_value) if (descriptor) // Overriden derivative property? - material_string += span_tooltip("[property]: [prop_value < 0 ? "-" : ""]\Roman[round(abs(prop_value), 1)]", descriptor) + material_string += span_tooltip("[property]: [tooltip_hint]", descriptor) if (length(material_string)) . += span_info("[capitalize(material.name)] is [english_list(material_string)].") diff --git a/code/game/atom/atom_materials.dm b/code/game/atom/atom_materials.dm index 16153284345..05a1801ee6f 100644 --- a/code/game/atom/atom_materials.dm +++ b/code/game/atom/atom_materials.dm @@ -1,11 +1,13 @@ /atom - ///The custom materials this atom is made of, used by a lot of things like furniture, walls, and floors (if I finish the functionality, that is.) - ///The list referenced by this var can be shared by multiple objects and should not be directly modified. Instead, use [set_custom_materials][/atom/proc/set_custom_materials]. + /// The custom materials this atom is made of, used by a lot of things like furniture, walls, and floors (if I finish the functionality, that is.) + /// The list referenced by this var can be shared by multiple objects and should not be directly modified. Instead, use [set_custom_materials][/atom/proc/set_custom_materials]. var/list/datum/material/custom_materials - ///Bitfield for how the atom handles materials. + /// Bitfield for how the atom handles materials. var/material_flags = NONE - ///Modifier that raises/lowers the effect of the amount of a material, prevents small and easy to get items from being death machines. + /// 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 + /// List of material slots to be used to control material behaviors instead of default ones + var/list/datum/material_slot/material_slots = null /// 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) @@ -81,8 +83,101 @@ MATERIAL_LIST_MULTIPLIER = get_material_multiplier(material, materials, index), ) index++ + + if(material_slots) + configure_material_slots(material_effects) + return material_effects +/// Add MATERIAL_LIST_SLOTS entries to material effects +/atom/proc/configure_material_slots(list/datum/material/material_effects) + for (var/slot_index in 1 to length(material_slots)) + var/slot_type = material_slots[slot_index] + var/datum/material/material = null + // The slot has a specific material assigned to it + if (material_slots[slot_type]) + material = SSmaterials.get_material(material_slots[slot_type]) + // Slots were unset, abort + if (!material_effects[material]) + continue + else if (slot_index <= length(material_effects)) // Otherwise, go by index + material = material_effects[slot_index] + if (!material) + continue + var/list/effects_list = material_effects[material] + if (!effects_list[MATERIAL_LIST_SLOTS]) + effects_list[MATERIAL_LIST_SLOTS] = list() + var/list/effects_slots = effects_list[MATERIAL_LIST_SLOTS] + effects_slots[slot_type] = TRUE + +/atom/proc/set_material_slot(slot_type, new_material) + if (material_slots[slot_type]) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + var/datum/material/material = SSmaterials.get_material(material_slots[slot_type]) + // Not present/initialized + if (material && custom_materials[material]) + var/list/materials_slots = get_slots_of_material(material) + var/slot_sum = 0 + if (length(materials_slots) > 1) + for (var/other_slot_type in materials_slots) + var/datum/material_slot/other_slot = SSmaterials.material_slots[other_slot_type] + slot_sum += other_slot.material_amount + slot.on_removed(src, material, custom_materials[material] * (slot_sum > 0 ? slot.material_amount / slot_sum : 1), get_material_multiplier(material, custom_materials, custom_materials.Find(material))) + + + // Don't store materials directly, only their IDs + if (istype(new_material, /datum/material)) + var/datum/material/as_material = new_material + material_slots[slot_type] = as_material.id + else + material_slots[slot_type] = new_material + + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + var/datum/material/material = istype(new_material, /datum/material) ? new_material : SSmaterials.get_material(new_material) + if (!material || !custom_materials[material]) + return + var/list/materials_slots = get_slots_of_material(material) + var/slot_sum = 0 + if (length(materials_slots) > 1) + for (var/other_slot_type in materials_slots) + var/datum/material_slot/other_slot = SSmaterials.material_slots[other_slot_type] + slot_sum += other_slot.material_amount + slot.on_applied(src, material, custom_materials[material] * (slot_sum > 0 ? slot.material_amount / slot_sum : 1), get_material_multiplier(material, custom_materials, custom_materials.Find(material))) + +/atom/proc/set_material_slots(list/new_slots) + if (length(material_slots)) + for (var/slot_type, material_id in material_slots) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + var/datum/material/material = SSmaterials.get_material(material_id) + // Not present/initialized + if (!material || !custom_materials[material]) + continue + var/list/materials_slots = get_slots_of_material(material) + var/slot_sum = 0 + if (length(materials_slots) > 1) + for (var/other_slot_type in materials_slots) + var/datum/material_slot/other_slot = SSmaterials.material_slots[other_slot_type] + slot_sum += other_slot.material_amount + slot.on_removed(src, material, custom_materials[material] * (slot_sum > 0 ? slot.material_amount / slot_sum : 1), get_material_multiplier(material, custom_materials, custom_materials.Find(material))) + + if (!length(new_slots)) + material_slots = null + return + + material_slots = new_slots.Copy() + for (var/slot_type, material_id in material_slots) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + var/datum/material/material = SSmaterials.get_material(material_id) + if (!material || !custom_materials[material]) + continue + var/list/materials_slots = get_slots_of_material(material) + var/slot_sum = 0 + if (length(materials_slots) > 1) + for (var/other_slot_type in materials_slots) + var/datum/material_slot/other_slot = SSmaterials.material_slots[other_slot_type] + slot_sum += other_slot.material_amount + slot.on_applied(src, material, custom_materials[material] * (slot_sum > 0 ? slot.material_amount / slot_sum : 1), get_material_multiplier(material, custom_materials, custom_materials.Find(material))) + /** * A proc that can be used to selectively control the stat changes and effects from a material without affecting the others. * @@ -93,6 +188,12 @@ * be 1 if below 1. Just don't return negative values. */ /atom/proc/get_material_multiplier(datum/material/custom_material, list/materials, index) + if (!length(material_slots)) + return 1 / length(materials) + // Slots usually account for multipliers in their own behaviors, so unless overriden it should just be 1 + for (var/slot_type in material_slots) + if (material_slots[slot_type] == custom_material.id) + return 1 return 1 / length(materials) ///Called by apply_material_effects(). It ACTUALLY handles applying effects common to all atoms (depending on material flags) @@ -104,13 +205,36 @@ var/datum/material/main_material = materials[1]//the material with the highest amount (after calculations) var/main_mat_amount = materials[main_material][MATERIAL_LIST_OPTIMAL_AMOUNT] var/main_mat_mult = materials[main_material][MATERIAL_LIST_MULTIPLIER] + var/do_main_material = TRUE 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] - apply_single_mat_effect(custom_material, mat_amount, multiplier) - custom_material.on_applied(src, mat_amount, multiplier) + var/do_effects = TRUE + var/from_slot = FALSE + if(!isnull(material_slots) && length(deets[MATERIAL_LIST_SLOTS])) + from_slot = TRUE + var/slot_sum = 0 + // A material is in multiple slots, we need to cut it up between them + if(length(deets[MATERIAL_LIST_SLOTS]) > 1) + for(var/slot_type in deets[MATERIAL_LIST_SLOTS]) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + slot_sum += slot.material_amount + + for(var/slot_type in deets[MATERIAL_LIST_SLOTS]) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + var/slot_amt = mat_amount + if (slot_sum > 0) + slot_amt *= slot.material_amount / slot_sum + do_effects &= slot.on_applied(src, custom_material, slot_amt, multiplier) + + if(!do_effects && custom_material == main_material) + do_main_material = FALSE + + if(do_effects) + apply_single_mat_effect(custom_material, mat_amount, multiplier) + custom_material.on_applied(src, mat_amount, multiplier, from_slot = from_slot) //Prevent changing things with pre-set colors, to keep colored toolboxes their looks for example if(material_flags & (MATERIAL_COLOR|MATERIAL_GREYSCALE)) @@ -118,7 +242,8 @@ var/added_alpha = custom_material.alpha * (custom_material.alpha / 255) total_alpha += GET_MATERIAL_MODIFIER(added_alpha, multiplier) - apply_main_material_effects(main_material, main_mat_amount, main_mat_mult) + if(do_main_material) + apply_main_material_effects(main_material, main_mat_amount, main_mat_mult) if(material_flags & (MATERIAL_COLOR|MATERIAL_GREYSCALE)) var/previous_alpha = alpha @@ -219,20 +344,15 @@ /atom/proc/apply_single_mat_effect(datum/material/material, amount, multiplier) SHOULD_CALL_PARENT(TRUE) + // Derived and not optional, so this needs to be on base and not in the property code itself var/beauty_modifier = material.get_property(MATERIAL_BEAUTY) if(beauty_modifier) AddElement(/datum/element/beauty, beauty_modifier * amount) if(beauty_modifier >= 0.15 && HAS_TRAIT(src, TRAIT_FISHING_BAIT)) AddElement(/datum/element/shiny_bait) - if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !uses_integrity) - return - - var/base_modifier = material.get_property(MATERIAL_INTEGRITY) - var/integrity_mod = GET_MATERIAL_MODIFIER(base_modifier, multiplier) - modify_max_integrity(ceil(max_integrity * integrity_mod)) - var/list/armor_mods = material.get_armor_modifiers(multiplier) - set_armor(get_armor().generate_new_with_multipliers(armor_mods)) + if((material_flags & MATERIAL_AFFECT_STATISTICS) && uses_integrity) + change_material_integrity(material, amount, multiplier) ///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, multiplier) @@ -249,22 +369,44 @@ 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 + var/main_mat_amount = materials[main_material][MATERIAL_LIST_OPTIMAL_AMOUNT] + var/main_mat_mult = materials[main_material][MATERIAL_LIST_MULTIPLIER] + var/do_main_material = TRUE 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) + var/do_effects = TRUE + var/from_slot = FALSE + if(!isnull(material_slots) && length(deets[MATERIAL_LIST_SLOTS])) + from_slot = TRUE + var/slot_sum = 0 + // A material is in multiple slots, we need to cut it up between them + if(length(deets[MATERIAL_LIST_SLOTS]) > 1) + for(var/slot_type in deets[MATERIAL_LIST_SLOTS]) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + slot_sum += slot.material_amount + + for(var/slot_type in deets[MATERIAL_LIST_SLOTS]) + var/datum/material_slot/slot = SSmaterials.material_slots[slot_type] + var/slot_amt = mat_amount + if (slot_sum > 0) + slot_amt *= slot.material_amount / slot_sum + do_effects &= slot.on_removed(src, custom_material, mat_amount, multiplier) + + if(!do_effects && custom_material == main_material) + do_main_material = FALSE + + if(do_effects) + remove_single_mat_effect(custom_material, mat_amount, multiplier) + custom_material.on_removed(src, mat_amount, multiplier, from_slot = from_slot) + if(material_flags & MATERIAL_COLOR) gather_material_color(custom_material, colors, mat_amount, multicolor = mat_length > 1) - remove_main_material_effects(main_material, main_mat_amount, main_mat_mult) + if(do_main_material) + remove_main_material_effects(main_material, main_mat_amount, main_mat_mult) if(material_flags & (MATERIAL_GREYSCALE|MATERIAL_COLOR)) if(material_flags & MATERIAL_COLOR) @@ -297,17 +439,8 @@ if(beauty_modifier >= 0.15 && HAS_TRAIT(src, TRAIT_FISHING_BAIT)) RemoveElement(/datum/element/shiny_bait) - if(!(material_flags & MATERIAL_AFFECT_STATISTICS) || !uses_integrity) - return - - var/base_modifier = material.get_property(MATERIAL_INTEGRITY) - var/integrity_mod = GET_MATERIAL_MODIFIER(base_modifier, multiplier) - modify_max_integrity(floor(max_integrity / integrity_mod)) - var/list/armor_mods = material.get_armor_modifiers(multiplier) - for (var/armor_type, value in armor_mods) - if (value != 0) // Needs to be restored to initial values in finalize effects, sorry - armor_mods[armor_type] = 1 / value - set_armor(get_armor().generate_new_with_multipliers(armor_mods)) + if((material_flags & MATERIAL_AFFECT_STATISTICS) && uses_integrity) + change_material_integrity(material, amount, multiplier, removing = TRUE) ///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) @@ -333,6 +466,42 @@ apply_material_effects() material_flags = new_flags +/// Applies changes to integrity and armor from a material +/atom/proc/change_material_integrity(datum/material/material, amount, multiplier, removing = FALSE) + var/base_modifier = material.get_property(MATERIAL_INTEGRITY) + var/integrity_mod = GET_MATERIAL_MODIFIER(base_modifier, multiplier) + var/integrity_change = removing ? floor(max_integrity / integrity_mod) : ceil(max_integrity * integrity_mod) + modify_max_integrity(integrity_change) + var/list/armor_mods = material.get_armor_modifiers(multiplier) + // Invert if we're removing our material + if (removing) + for (var/armor_type, value in armor_mods) + if (value != 0) // Needs to be restored to initial values in finalize effects, sorry + armor_mods[armor_type] = 1 / value + set_armor(get_armor().generate_new_with_multipliers(armor_mods)) + +/// Tries to fetch a material matching a specific slot +/atom/proc/get_material_from_slot(slot_type) + var/mat_type = material_slots?[slot_type] + if (mat_type) + return SSmaterials.get_material(mat_type) + +/// Fetches a copy of all material slots. +/atom/proc/get_material_slots() + return material_slots?.Copy() + +/// Returns TRUE if this atom utilizes material slots +/atom/proc/has_material_slots() + return !!length(material_slots) + +/// Lists all slots in which a material is present +/atom/proc/get_slots_of_material(datum/material/material) + . = list() + for (var/slot_type, material_id in material_slots) + if (material_id == istype(material) ? material.id : material) + . += slot_type + return . + /** * Returns the material composition of the atom. * diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index c28f6817330..fff9be1ef6b 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -159,9 +159,15 @@ customMaterials = FALSE continue - var/datum/material_requirement/requirement = SSmaterials.requirements[mat] - if (!requirement) - stack_trace("Design [design] has an invalid material requirement [requirement]") + var/datum/material_requirement/requirement = null + if (ispath(mat, /datum/material_slot)) + var/datum/material_slot/slot = SSmaterials.material_slots[mat] + requirement = SSmaterials.requirements[slot.requirement_type] + else + requirement = SSmaterials.requirements[mat] + + if (!istype(requirement)) + stack_trace("Design [design] has an invalid material requirement: [mat]") continue cost[requirement.get_description()] = design_cost @@ -257,14 +263,20 @@ // Check for materials required. For custom material items decode their required materials var/list/materials_needed = list() + var/list/slots_chosen = null var/mat_choice = FALSE for(var/material, amount_needed in design.materials) - if(!ispath(material, /datum/material_requirement)) // Material requirement + if(!ispath(material, /datum/material_requirement) && !ispath(material, /datum/material_slot)) // Material requirement if(!istype(material, /datum/material)) CRASH("Autolathe ui_act got passed an invalid material id: [material]") materials_needed[material] += amount_needed continue + var/datum/material_slot/slot = null + if (ispath(material, /datum/material_slot)) + slot = SSmaterials.material_slots[material] + material = slot.requirement_type + var/list/choices = list() for(var/datum/material/valid_candidate as anything in SSmaterials.get_materials_by_req(material)) if(materials.get_material_amount(valid_candidate) >= (amount_needed + materials_needed[valid_candidate])) @@ -276,7 +288,7 @@ var/chosen = tgui_input_list( ui.user, - "Select the material to use", + "Select the material to use[slot ? " for [LOWER_TEXT(slot.name)]" : ""]", "Material Selection", sort_list(choices), ) @@ -284,6 +296,9 @@ return // user cancelled material = choices[chosen] + if (slot) + var/datum/material/proper_mat = material + LAZYSET(slots_chosen, slot.type, proper_mat.id) if(isnull(material)) CRASH("A player chose an invalid custom material in autolathe ui_act: [material]") @@ -323,7 +338,7 @@ if(!istype(material, /datum/material/glass) && !istype(material, /datum/material/iron)) ui.user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, ui.user) break - addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_count, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target_location), build_time_per_item) + addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_count, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target_location, slots_chosen), build_time_per_item) return TRUE @@ -339,7 +354,7 @@ * * list/materials_needed - the list of materials to print 1 item * * turf/target - the location to drop the printed item on */ -/obj/machinery/autolathe/proc/do_make_item(datum/design/design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, list/materials_needed, turf/target) +/obj/machinery/autolathe/proc/do_make_item(datum/design/design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, list/materials_needed, turf/target, list/slots_chosen) PROTECTED_PROC(TRUE) if(items_remaining <= 0) // how @@ -386,6 +401,8 @@ created = design.create_result(target, materials_needed, amount = number_to_make) else created = design.create_result(target, materials_needed) + if (length(slots_chosen)) + created.set_material_slots(slots_chosen) split_materials_uniformly(materials_needed, material_cost_coefficient, created) if(isitem(created)) @@ -401,7 +418,7 @@ if(items_remaining <= 0) finalize_build() return - addtimer(CALLBACK(src, PROC_REF(do_make_item), design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target), build_time_per_item) + addtimer(CALLBACK(src, PROC_REF(do_make_item), design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target, slots_chosen), build_time_per_item) /** * Resets the icon state and busy flag diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index dc485a807d2..fd7a3f3058c 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -2001,11 +2001,7 @@ if (!(material_flags & MATERIAL_AFFECT_STATISTICS)) return - // [0 ~ 1] is fully insulating, (1 ~ 6] maps to (0 ~ 1] and [6 ~ 10] maps to [1 ~ 2] - // 1.18 and 0.15 here are to allow 6 to map to 1 and 10 to map to 2 and are pulled out of my ass (system in the desmos below) - // See https://www.desmos.com/calculator/rdbv1x8oty - var/conductivity = material.get_property(MATERIAL_ELECTRICAL) - var/siemens_modifier = round(max(0, conductivity - 1) ** 1.18 * 0.15, 0.01) + var/siemens_modifier = material.get_property(MATERIAL_INSULATION) // Cannot use the base formula as it would make any item with glass not conduct electricity if (siemens_modifier > 1) siemens_coefficient *= 1 + (siemens_modifier - 1) * multiplier @@ -2015,30 +2011,15 @@ if (siemens_coefficient == 0) obj_flags &= ~CONDUCTS_ELECTRICITY - if (material_flags & MATERIAL_NO_SLOWDOWN) - return - - // Density above 6 adds slowdown, density below 3 can reduce existing slowdown - var/density = material.get_property(MATERIAL_DENSITY) - var/slowdown_change = 0 - - if (density > 6) - slowdown_change = (density - 6) * MATERIAL_DENSITY_SLOWDOWN * mat_amount / SHEET_MATERIAL_AMOUNT - else if (density < 3) - slowdown_change = (3 - density) * -MATERIAL_DENSITY_SLOWDOWN * mat_amount / SHEET_MATERIAL_AMOUNT - - // Slowdown cannot be reduced below 0 if the item slows you down, or at all if the item speeds you up - if (slowdown_change) - slowdown = max(slowdown >= 0 ? 0 : slowdown, slowdown + slowdown_change * multiplier) + if (!(material_flags & MATERIAL_NO_SLOWDOWN)) + change_material_slowdown(material, mat_amount, multiplier) /obj/item/remove_single_mat_effect(datum/material/material, mat_amount, multiplier) . = ..() if (!(material_flags & MATERIAL_AFFECT_STATISTICS)) return - var/conductivity = material.get_property(MATERIAL_ELECTRICAL) - // 0 ~ 1 count as perfect insulators - var/siemens_modifier = round(max(conductivity - 1, 0) ** 1.18 * 0.15, 0.01) + var/siemens_modifier = material.get_property(MATERIAL_INSULATION) // Cannot use the base formula as it would make any item with glass not conduct electricity if (siemens_modifier > 1) siemens_coefficient /= 1 + (siemens_modifier - 1) * multiplier @@ -2050,16 +2031,24 @@ if (siemens_coefficient > 0 && (initial(obj_flags) & CONDUCTS_ELECTRICITY) && !(obj_flags & CONDUCTS_ELECTRICITY)) obj_flags |= CONDUCTS_ELECTRICITY - if (material_flags & MATERIAL_NO_SLOWDOWN) - return + if (!(material_flags & MATERIAL_NO_SLOWDOWN)) + change_material_slowdown(material, mat_amount, multiplier, removing = TRUE) +/obj/item/proc/change_material_slowdown(datum/material/material, mat_amount, multiplier, removing = FALSE) + // Density above 6 adds slowdown, density below 3 can reduce existing slowdown var/density = material.get_property(MATERIAL_DENSITY) var/slowdown_change = 0 if (density > 6) slowdown_change = (density - 6) * MATERIAL_DENSITY_SLOWDOWN * mat_amount / SHEET_MATERIAL_AMOUNT - else if (density < 3) - slowdown_change = (3 - density) * -MATERIAL_DENSITY_SLOWDOWN * mat_amount / SHEET_MATERIAL_AMOUNT + else if (density < 4) + slowdown_change = (4 - density) * -MATERIAL_DENSITY_SLOWDOWN * mat_amount / SHEET_MATERIAL_AMOUNT + + if (!removing) + // Slowdown cannot be reduced below 0 if the item slows you down, or at all if the item speeds you up + if (slowdown_change) + slowdown = max(slowdown >= 0 ? 0 : slowdown, slowdown + slowdown_change * multiplier) + return if (slowdown_change > 0) slowdown -= slowdown_change * multiplier @@ -2069,11 +2058,12 @@ /obj/item/finalize_remove_material_effects(list/materials) . = ..() + if (!(material_flags & MATERIAL_AFFECT_STATISTICS) || initial(siemens_coefficient) == 0 || siemens_coefficient != 0) + return // If we were made from an insulator we cannot restore via division - if (initial(siemens_coefficient) != 0 && siemens_coefficient == 0) - siemens_coefficient = initial(siemens_coefficient) - if (siemens_coefficient > 0 && (initial(obj_flags) & CONDUCTS_ELECTRICITY) && !(obj_flags & CONDUCTS_ELECTRICITY)) - obj_flags |= CONDUCTS_ELECTRICITY + siemens_coefficient = initial(siemens_coefficient) + if (siemens_coefficient > 0 && (initial(obj_flags) & CONDUCTS_ELECTRICITY) && !(obj_flags & CONDUCTS_ELECTRICITY)) + obj_flags |= CONDUCTS_ELECTRICITY /obj/item/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) var/density = material.get_property(MATERIAL_DENSITY) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 64d594b8baf..d7bf67cf730 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -7,7 +7,8 @@ singular_name = "bluespace crystal" dye_color = DYE_COSMIC w_class = WEIGHT_CLASS_TINY - mats_per_unit = list(/datum/material/bluespace=SHEET_MATERIAL_AMOUNT) + material_flags = MATERIAL_NO_DESCRIPTORS // Handles in-hand/thrown teleports by itself + mats_per_unit = list(/datum/material/bluespace = SHEET_MATERIAL_AMOUNT) points = 50 refined_type = /obj/item/stack/sheet/bluespace_crystal scan_state = "rock_bscrystal" @@ -52,6 +53,9 @@ blink_mob(hit_atom) use(1) +/obj/item/stack/ore/bluespace_crystal/attack_self_secondary(mob/user, modifiers) + interact(user) + //Artificial bluespace crystal, doesn't give you much research. /obj/item/stack/ore/bluespace_crystal/artificial name = "artificial bluespace crystal" @@ -67,12 +71,12 @@ // Polycrystals, aka stacks /obj/item/stack/sheet/bluespace_crystal name = "bluespace polycrystal" - icon = 'icons/obj/stack_objects.dmi' - icon_state = "polycrystal" - inhand_icon_state = null - gulag_valid = TRUE singular_name = "bluespace polycrystal" desc = "A stable polycrystal, made of fused-together bluespace crystals. You could probably break one off." + icon_state = "polycrystal" + inhand_icon_state = null + material_flags = MATERIAL_NO_DESCRIPTORS + gulag_valid = TRUE mats_per_unit = list(/datum/material/bluespace=SHEET_MATERIAL_AMOUNT) attack_verb_continuous = list("bluespace polybashes", "bluespace polybatters", "bluespace polybludgeons", "bluespace polythrashes", "bluespace polysmashes") attack_verb_simple = list("bluespace polybash", "bluespace polybatter", "bluespace polybludgeon", "bluespace polythrash", "bluespace polysmash") @@ -81,23 +85,21 @@ material_type = /datum/material/bluespace var/crystal_type = /obj/item/stack/ore/bluespace_crystal/refined -/obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening - to_chat(user, span_warning("You cannot crush the polycrystal in-hand, try breaking one off.")) - //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/stack/sheet/bluespace_crystal/attack_hand(mob/user, list/modifiers) - if(user.get_inactive_held_item() == src) - if(is_zero_amount(delete_if_zero = TRUE)) - return - var/BC = new crystal_type(src) - user.put_in_hands(BC) - use(1) - if(!amount) - to_chat(user, span_notice("You break the final crystal off.")) - else - to_chat(user, span_notice("You break off a crystal.")) + if(user.get_inactive_held_item() != src) + return ..() + + if(is_zero_amount(delete_if_zero = TRUE)) + return + + var/BC = new crystal_type(src) + user.put_in_hands(BC) + use(1) + if(!amount) + to_chat(user, span_notice("You break the final crystal off.")) else - ..() + to_chat(user, span_notice("You break off a crystal.")) /obj/item/stack/sheet/bluespace_crystal/fifty amount = 50 diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 17fd93bc5bf..d9a5e5c4bcc 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ ) AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) - var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/spear, /datum/crafting_recipe/stunprod, /datum/crafting_recipe/teleprod) // snatcher prod isn't here as a spoopy secret + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/spear, /datum/crafting_recipe/stunprod, /datum/crafting_recipe/teleprod, /datum/crafting_recipe/wireprod) // snatcher prod isn't here as a spoopy secret AddElement( /datum/element/slapcrafting,\ diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index d4138155da2..83b202bc911 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -167,9 +167,9 @@ GLOBAL_LIST_INIT(monkey_recipes, list ( \ amount = 5 /obj/item/stack/sheet/animalhide/xeno - name = "alien hide" + name = "alien chitin" + singular_name = "alien chitin piece" desc = "The skin of a terrible creature." - singular_name = "alien hide piece" icon_state = "sheet-xeno" inhand_icon_state = null merge_type = /obj/item/stack/sheet/animalhide/xeno @@ -210,16 +210,6 @@ GLOBAL_LIST_INIT(carp_recipes, list ( \ /obj/item/stack/sheet/animalhide/carp/five amount = 5 -//don't see anywhere else to put these, maybe together they could be used to make the xenos suit? -/obj/item/stack/sheet/xenochitin - name = "alien chitin" - desc = "A piece of the hide of a terrible creature." - singular_name = "alien hide piece" - icon = 'icons/mob/nonhuman-player/alien.dmi' - icon_state = "chitin" - novariants = TRUE - merge_type = /obj/item/stack/sheet/xenochitin - /obj/item/xenos_claw name = "alien claw" desc = "The claw of a terrible creature." diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index a8169715d35..8ec2a97520a 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -950,7 +950,7 @@ GLOBAL_LIST_INIT(paperframe_recipes, list( desc = "Something's bloody meat compressed into a nice solid sheet." singular_name = "meat sheet" icon_state = "sheet-meat" - material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR | MATERIAL_NO_DESCRIPTORS mats_per_unit = list(/datum/material/meat = SHEET_MATERIAL_AMOUNT) merge_type = /obj/item/stack/sheet/meat material_type = /datum/material/meat @@ -997,7 +997,7 @@ GLOBAL_LIST_INIT(pizza_sheet_recipes, list( desc = "These sheets seem cursed." singular_name = "haunted sheet" icon_state = "sheet-meat" - material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR + material_flags = MATERIAL_EFFECTS | MATERIAL_COLOR | MATERIAL_NO_DESCRIPTORS mats_per_unit = list(/datum/material/hauntium = SHEET_MATERIAL_AMOUNT) merge_type = /obj/item/stack/sheet/hauntium material_type = /datum/material/hauntium diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index 862d255133e..3d2b1f52030 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -56,8 +56,9 @@ if (isnull(prop_value)) // Error? continue var/descriptor = property?.get_descriptor(prop_value) + var/tooltip_hint = property?.get_tooltip(prop_value) if (descriptor) // Overriden derivative property? - material_string += span_tooltip("[property]: [prop_value < 0 ? "-" : ""]\Roman[round(abs(prop_value), 1)]", descriptor) + material_string += span_tooltip("[property]: [tooltip_hint]", descriptor) if (length(material_string)) . += span_info("[capitalize(material.name)] is [english_list(material_string)].") diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm index dd1b74eb106..4988a9748a8 100644 --- a/code/game/objects/items/stacks/telecrystal.dm +++ b/code/game/objects/items/stacks/telecrystal.dm @@ -1,18 +1,20 @@ /obj/item/stack/telecrystal name = "telecrystal" - desc = "It seems to be pulsing with suspiciously enticing energies." + desc = "Covered in a web of finely engraved geometrical patterns, pulsing with suspiciously enticing energies." singular_name = "telecrystal" - icon = 'icons/obj/stack_objects.dmi' icon_state = "telecrystal" dye_color = DYE_SYNDICATE + full_w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY max_amount = 50 item_flags = NOBLUDGEON merge_type = /obj/item/stack/telecrystal novariants = FALSE + material_type = /datum/material/telecrystal + mats_per_unit = list(/datum/material/telecrystal = SHEET_MATERIAL_AMOUNT) /obj/item/stack/telecrystal/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - if(interacting_with != user) //You can't go around smacking people with crystals to find out if they have an uplink or not. + if(interacting_with != user) // You can't go around smacking people with crystals to find out if they have an uplink or not. return NONE for(var/obj/item/implant/uplink/uplink in interacting_with) @@ -20,14 +22,30 @@ continue var/datum/component/uplink/hidden_uplink = uplink.GetComponent(/datum/component/uplink) - if(hidden_uplink) - hidden_uplink.uplink_handler.add_telecrystals(amount) - use(amount) - to_chat(user, span_notice("You press [src] onto yourself and charge your hidden uplink.")) - return ITEM_INTERACT_SUCCESS + if(!hidden_uplink) + continue + hidden_uplink.uplink_handler.add_telecrystals(amount) + use(amount) + to_chat(user, span_notice("You press [src] onto yourself and charge your hidden uplink.")) + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING /obj/item/stack/telecrystal/five amount = 5 /obj/item/stack/telecrystal/twenty amount = 20 + +/obj/item/stack/sheet/telepolycrystal + name = "telelocational podcrystal" + singular_name = "telelocational podcrystal" + desc = "A \"somewhat\" stable chunk of telecrystal. It lacks the precision-carved tuning channels, making it useless for long-range matter teleportation." + icon_state = "telepolycrystal" + inhand_icon_state = null + full_w_class = WEIGHT_CLASS_TINY + w_class = WEIGHT_CLASS_TINY + dye_color = DYE_SYNDICATE + novariants = TRUE + merge_type = /obj/item/stack/sheet/telepolycrystal + material_type = /datum/material/telecrystal + mats_per_unit = list(/datum/material/telecrystal = SHEET_MATERIAL_AMOUNT) diff --git a/code/game/objects/items/weaponry/melee/baton.dm b/code/game/objects/items/weaponry/melee/baton.dm index 07a40afabdc..3c5f0a4991a 100644 --- a/code/game/objects/items/weaponry/melee/baton.dm +++ b/code/game/objects/items/weaponry/melee/baton.dm @@ -933,6 +933,7 @@ slot_flags = null throw_stun_chance = 50 //I think it'd be funny can_upgrade = FALSE + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.15, /datum/material/telecrystal = SHEET_MATERIAL_AMOUNT, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 2) /obj/item/melee/baton/security/cattleprod/telecrystalprod/baton_effect(mob/living/target, mob/living/user, stun_override, clumsy) . = ..() diff --git a/code/game/objects/items/weaponry/melee/misc.dm b/code/game/objects/items/weaponry/melee/misc.dm index 8bb68ee396e..11d951f22a9 100644 --- a/code/game/objects/items/weaponry/melee/misc.dm +++ b/code/game/objects/items/weaponry/melee/misc.dm @@ -238,8 +238,10 @@ greyscale_config_worn = /datum/greyscale_config/cleric_mace 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 * 4.5, /datum/material/wood = SHEET_MATERIAL_AMOUNT * 1.5) //Defaults to an Iron Mace. + material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_GREYSCALE | MATERIAL_AFFECT_STATISTICS + // Defaults to an iron head, wooden handle mace + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 4.5, /datum/material/wood = SHEET_MATERIAL_AMOUNT * 1.5) + material_slots = list(/datum/material_slot/weapon_head/mace = /datum/material/iron, /datum/material_slot/handle = /datum/material/wood) slot_flags = ITEM_SLOT_BELT force = 16 w_class = WEIGHT_CLASS_BULKY @@ -250,31 +252,28 @@ 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 - +// It only inherits the name of the main material it's made of. The secondary is in the description. /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. + var/datum/material/material = get_material_from_slot(/datum/material_slot/weapon_head) + return material?.name /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]." + var/datum/material/material = get_material_from_slot(/datum/material_slot/handle) + if (material) + 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) + // 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. + // Or a road roller, if one happened to hit you. if(attack_type == PROJECTILE_ATTACK || attack_type == LEAP_ATTACK || attack_type == OVERWHELMING_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. Or a road roller, if one happened to hit you. + final_block_chance = 0 return ..() +/datum/material_slot/weapon_head/mace + name = "mace head" + material_amount = 3 + /obj/item/sord name = "\improper SORD" desc = "This thing is so unspeakably shitty you are having a hard time even holding it." diff --git a/code/game/objects/items/weaponry/melee/spear.dm b/code/game/objects/items/weaponry/melee/spear.dm index 00035afbc59..c3a87f4f0d6 100644 --- a/code/game/objects/items/weaponry/melee/spear.dm +++ b/code/game/objects/items/weaponry/melee/spear.dm @@ -1,4 +1,5 @@ -//spears +#define SPEAR_CUSTOM_TIP_PREFIX "spearblank" + /obj/item/spear name = "spear" desc = "A haphazardly-constructed yet still deadly weapon of ancient design." @@ -17,6 +18,7 @@ embed_type = /datum/embedding/spear armour_penetration = 5 custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 0.65, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 1.15) + material_slots = list(/datum/material_slot/weapon_head/speartip = /datum/material/glass, /datum/material_slot/handle/spear = /datum/material/iron) hitsound = 'sound/items/weapons/bladeslice.ogg' attack_verb_continuous = list("attacks", "pokes", "jabs", "tears", "lacerates", "gores") attack_verb_simple = list("attack", "poke", "jab", "tear", "lacerate", "gore") @@ -25,7 +27,7 @@ armor_type = /datum/armor/item_spear wound_bonus = -15 exposed_wound_bonus = 15 - material_flags = MATERIAL_EFFECTS + material_flags = MATERIAL_EFFECTS | MATERIAL_AFFECT_STATISTICS /// The icon prefix for this flavor of spear var/icon_prefix = "spearglass" /// How much damage to do unwielded @@ -36,8 +38,6 @@ var/improvised_construction = TRUE /// What is left over when a spear breaks var/spear_leftovers = /obj/item/stack/rods - /// Material type from which our tip is made - var/tip_mat_type = null /// What pike do we construct if someone kills themselves with us? var/pike_type = /obj/structure/headpike @@ -84,6 +84,10 @@ /obj/item/spear/update_icon_state() icon_state = "[icon_prefix]0" + if (icon_prefix == SPEAR_CUSTOM_TIP_PREFIX) + worn_icon_state = "spearglass0" + else + worn_icon_state = null return ..() /obj/item/spear/suicide_act(mob/living/carbon/user) @@ -107,87 +111,79 @@ var/obj/item/stack/rods/rod = locate() in components if (rod) spear_leftovers = rod.type + set_material_slot(/datum/material_slot/handle/spear, rod.get_master_material()) var/obj/item/shard/tip = locate() in components if (!tip) return ..() var/datum/material/tip_material = tip.get_master_material() - // For master material effects. As on_craft_completion is ran before set_custom_materials, this will allow the speartip to be treated as our master material no matter what - tip_mat_type = tip_material.id - switch (tip_mat_type) + set_material_slot(/datum/material_slot/weapon_head/speartip, tip_material) + return ..() + +/obj/item/spear/set_material_slot(slot_type, new_material) + . = ..() + if (slot_type != /datum/material_slot/weapon_head/speartip) + return + + if (istype(new_material, /datum/material)) + var/datum/material/as_material = new_material + new_material = as_material.type + + switch (new_material) if (/datum/material/alloy/plasmaglass) icon_prefix = "spearplasma" if (/datum/material/alloy/titaniumglass) icon_prefix = "speartitanium" if (/datum/material/alloy/plastitaniumglass) icon_prefix = "spearplastitanium" + else + icon_prefix = SPEAR_CUSTOM_TIP_PREFIX + + AddComponent(/datum/component/two_handed, \ + icon_wielded = "[icon_prefix]1", \ + wield_callback = CALLBACK(src, PROC_REF(on_wield)), \ + unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \ + ) update_appearance() - return ..() + +/obj/item/spear/finalize_material_effects(list/materials) + . = ..() + update_appearance() + +/obj/item/spear/update_overlays() + . = ..() + if (icon_prefix != SPEAR_CUSTOM_TIP_PREFIX) + return + var/datum/material/tip_material = get_master_material() + var/mutable_appearance/tip_overlay = mutable_appearance(icon, "speartip", appearance_flags = KEEP_APART | RESET_COLOR) + tip_overlay.color = tip_material.color + . += tip_overlay + +/obj/item/spear/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file) + . = ..() + if (icon_prefix != SPEAR_CUSTOM_TIP_PREFIX || !isinhands) + return + var/datum/material/tip_material = get_master_material() + var/mutable_appearance/tip_overlay = mutable_appearance(icon_file, "speartip[HAS_TRAIT(src, TRAIT_WIELDED)]", appearance_flags = RESET_COLOR) + tip_overlay.color = tip_material.color + . += tip_overlay /obj/item/spear/get_master_material() - if (tip_mat_type && custom_materials[tip_mat_type]) - return SSmaterials.get_material(tip_mat_type) - return ..() - -/obj/item/spear/apply_main_material_effects(datum/material/main_material, amount, multiplier) - . = ..() - var/density = main_material.get_property(MATERIAL_DENSITY) - var/hardness = main_material.get_property(MATERIAL_HARDNESS) - // If a spear is too hard its unwieldy, if it is too light it doesn't have enough weight behind it - var/force_change = (hardness - 4) - max(0, density - 4) - max(0, 4 - density) * 2 - force_unwielded += force_change - force_wielded += force_change - force = force_unwielded - throwforce += force_change - wound_bonus += force_change * 5 - modify_max_integrity(max_integrity + (hardness - 4) * 10) - throw_range += (hardness - 4) - (density - 4) * 2 - throw_speed += floor(((hardness - 4) - (density - 4) * 2) / 2) - // These try to keep parity with titanium/plastitanium spears as armorpen boost was exclusive to them - armour_penetration += MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) * 5 - exposed_wound_bonus += (MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) - (density - 4)) * 5 - AddComponent(/datum/component/two_handed, \ - force_unwielded = force_unwielded, \ - force_wielded = force_wielded, \ - icon_wielded = "[icon_prefix]1", \ - wield_callback = CALLBACK(src, PROC_REF(on_wield)), \ - unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \ - ) - -/obj/item/spear/remove_main_material_effects(datum/material/main_material, amount, multiplier) - . = ..() - var/density = main_material.get_property(MATERIAL_DENSITY) - var/hardness = main_material.get_property(MATERIAL_HARDNESS) - var/force_change = (hardness - 4) - (density - 4) - force_unwielded -= force_change - force_wielded -= force_change - force = force_unwielded - throwforce -= force_change - wound_bonus -= force_change * 5 - modify_max_integrity(max_integrity - (hardness - 4) * 10) - throw_range -= (hardness - 4) - (density - 4) * 2 - throw_speed -= floor(((hardness - 4) - (density - 4) * 2) / 2) - // These try to keep parity with titanium/plastitanium spears as armorpen boost was exclusive to them - armour_penetration -= MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) * 5 - exposed_wound_bonus -= (MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) - (density - 4)) * 5 - AddComponent(/datum/component/two_handed, \ - force_unwielded = force_unwielded, \ - force_wielded = force_wielded, \ - icon_wielded = "[icon_prefix]1", \ - wield_callback = CALLBACK(src, PROC_REF(on_wield)), \ - unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \ - ) + var/datum/material/tip_material = get_material_from_slot(/datum/material_slot/weapon_head/speartip) + if (!tip_material) + return ..() + return custom_materials[tip_material] ? tip_material : ..() /obj/item/spear/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers) - if(improvised_construction) + if(improvised_construction && !QDELETED(src)) take_damage(force / 2, sound_effect = FALSE) /obj/item/spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() if (.) //spear was caught return - if(improvised_construction) + if(improvised_construction && !QDELETED(src)) take_damage(throwforce / 2, sound_effect = FALSE) /obj/item/spear/atom_destruction(damage_flag) @@ -197,6 +193,10 @@ loc.balloon_alert(loc, "spear broken!") return ..() +/obj/item/spear/get_material_prefixes(list/materials) + var/datum/material/material = get_material_from_slot(/datum/material_slot/weapon_head/speartip) + return material?.name + /obj/item/spear/proc/on_wield(obj/item/source, mob/living/carbon/user) reach = 1 armour_penetration *= 2 @@ -205,6 +205,111 @@ reach = 2 armour_penetration /= 2 +/datum/material_slot/weapon_head/speartip + name = "tip" + material_amount = 1.75 + +/datum/material_slot/weapon_head/speartip/on_applied(obj/item/spear/target, datum/material/material, amount, multiplier) + . = ..() + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS)) + return FALSE + + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + // If a spear is too hard its unwieldy, if it is too light it doesn't have enough weight behind it + var/material_effect = (hardness - 4) - max(0, density - 4) - max(0, 4 - density) * 2 + target.wound_bonus += material_effect * 5 + // These try to keep parity with titanium/plastitanium spears as armorpen boost was exclusive to them + target.armour_penetration += MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) * 5 + target.exposed_wound_bonus += (MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) - (density - 4)) * 5 + return FALSE + +/datum/material_slot/weapon_head/spearhead/on_removed(obj/item/spear/target, datum/material/material, amount, multiplier) + . = ..() + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS)) + return FALSE + + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + var/material_effect = (hardness - 4) - max(0, density - 4) - max(0, 4 - density) * 2 + target.wound_bonus -= material_effect * 5 + target.armour_penetration -= MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) * 5 + target.exposed_wound_bonus -= (MATERIAL_PROPERTY_DIVERGENCE(hardness, 4, 6) - (density - 4)) * 5 + return FALSE + +/datum/material_slot/handle/spear + +/datum/material_slot/handle/spear/on_applied(obj/item/target, datum/material/material, amount, multiplier) + . = ..() + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS)) + return FALSE + + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + target.throw_range += (hardness - 4) - (density - 4) * 2 + target.throw_speed += floor((hardness - 4) / 2) - (density - 4) * 2 + return FALSE + +/datum/material_slot/handle/spear/on_removed(obj/item/target, datum/material/material, amount, multiplier) + . = ..() + if (!(target.material_flags & MATERIAL_AFFECT_STATISTICS)) + return FALSE + + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + target.throw_range -= (hardness - 4) - (density - 4) * 2 + target.throw_speed -= floor((hardness - 4) / 2) - (density - 4) * 2 + return FALSE + +/obj/item/wireprod + name = "wireprod" + desc = "A metal rod with some wire attached to one of the ends, waiting for something sharp." + icon = 'icons/obj/weapons/spear.dmi' + icon_state = "wireprod" + inhand_icon_state = "spearblank0" + lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi' + icon_angle = -45 + force = 5 + w_class = WEIGHT_CLASS_BULKY + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 0.65, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 1.5) + attack_verb_continuous = list("attacks", "pokes", "jabs", "tears", "lacerates", "gores") + attack_verb_simple = list("attack", "poke", "jab", "tear", "lacerate", "gore") + material_flags = MATERIAL_EFFECTS | MATERIAL_AFFECT_STATISTICS + +/obj/item/wireprod/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + var/datum/material/shard_mat = null + if (istype(tool, /obj/item/shard)) + shard_mat = tool.get_master_material() + else if (istype(tool, /obj/item/stack)) + shard_mat = tool.get_master_material() + if (!(shard_mat.mat_flags & MATERIAL_CLASS_CRYSTAL)) + shard_mat = null + + if (!shard_mat) + return NONE + + var/obj/item/spear/spear = new(drop_location()) + var/datum/material/rod_material = get_master_material() + spear.material_flags |= MATERIAL_ADD_PREFIX + spear.set_material_slot(/datum/material_slot/handle/spear, get_master_material()) + spear.set_material_slot(/datum/material_slot/weapon_head/speartip, shard_mat) + spear.set_custom_materials(list((rod_material) = custom_materials[rod_material], (shard_mat) = tool.custom_materials[shard_mat])) + to_chat(user, span_notice("You attach [tool] to [src]'s tip.")) + + if (istype(tool, /obj/item/stack)) + var/obj/item/stack/stack = tool + stack.use(1) + else + qdel(tool) + + var/was_holding = user.get_held_index_of_item(src) + qdel(src) + if (was_holding) + user.put_in_hands(spear) + +#undef SPEAR_CUSTOM_TIP_PREFIX + /obj/item/spear/explosive name = "explosive lance" icon_state = "spearbomb0" @@ -337,6 +442,7 @@ righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi' demolition_mod = 0.5 resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + material_flags = MATERIAL_EFFECTS force = 13 throwforce = 23 throw_range = 9 @@ -350,7 +456,9 @@ custom_materials = list( /datum/material/iron = SHEET_MATERIAL_AMOUNT * 42, /datum/material/alloy/plasteel = SHEET_MATERIAL_AMOUNT * 15, - /datum/material/titanium = SHEET_MATERIAL_AMOUNT * 5) + /datum/material/titanium = SHEET_MATERIAL_AMOUNT * 5, + ) + material_slots = list(/datum/material_slot/weapon_head/speartip = /datum/material/titanium, /datum/material_slot/handle/spear = /datum/material/alloy/plasteel) /obj/item/spear/dragonator/Initialize(mapload) . = ..() @@ -366,6 +474,7 @@ icon_state = "speardragonraw0" icon_prefix = "speardragonraw" base_icon_state = "speardragonraw" + material_flags = MATERIAL_EFFECTS demolition_mod = 0.5 wound_bonus = 0 exposed_wound_bonus = 0 @@ -375,10 +484,14 @@ custom_materials = list( /datum/material/iron = SHEET_MATERIAL_AMOUNT * 42, /datum/material/alloy/plasteel = SHEET_MATERIAL_AMOUNT * 15, - /datum/material/titanium = SHEET_MATERIAL_AMOUNT * 5) + /datum/material/titanium = SHEET_MATERIAL_AMOUNT * 5, + ) + material_slots = list(/datum/material_slot/weapon_head/speartip = /datum/material/titanium, /datum/material_slot/handle/spear = /datum/material/alloy/plasteel) /obj/item/spear/dragonator_untreated/fire_act(exposed_temperature, exposed_volume) var/obj/item/spear/dragonator/dragonator = new(loc) + dragonator.set_material_slots(material_slots) + dragonator.set_custom_materials(custom_materials.Copy()) playsound(dragonator.loc, 'sound/effects/magic/staff_change.ogg',5) qdel(src) @@ -394,6 +507,7 @@ throwforce = 22 armour_penetration = 20 //Enhanced armor piercing custom_materials = list(/datum/material/bone = SHEET_MATERIAL_AMOUNT * 4) + material_slots = list(/datum/material_slot/weapon_head/speartip = /datum/material/bone, /datum/material_slot/handle/spear = /datum/material/bone) force_unwielded = 12 force_wielded = 20 spear_leftovers = /obj/item/stack/sheet/bone @@ -419,6 +533,7 @@ throwforce = 23 //Better to throw custom_materials = list(/datum/material/bamboo = SHEET_MATERIAL_AMOUNT * 25) + material_slots = list(/datum/material_slot/weapon_head/speartip = /datum/material/bamboo, /datum/material_slot/handle/spear = /datum/material/bamboo) spear_leftovers = /obj/item/stack/sheet/mineral/bamboo pike_type = /obj/structure/headpike/bamboo @@ -445,11 +560,12 @@ attack_verb_simple = list("attack", "poke", "jab", "tear", "gore", "lance") throwforce = 24 embed_type = null //no embedding - + material_flags = MATERIAL_EFFECTS custom_materials = list( /datum/material/diamond = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/alloy/plastitaniumglass = SHEET_MATERIAL_AMOUNT, ) + material_slots = list(/datum/material_slot/weapon_head/speartip = /datum/material/diamond, /datum/material_slot/handle/spear = /datum/material/alloy/plastitaniumglass) action_slots = ITEM_SLOT_HANDS actions_types = list(/datum/action/item_action/skybulge) improvised_construction = FALSE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 3e572f7fb2e..167ca422109 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -330,15 +330,13 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) /obj/apply_single_mat_effect(datum/material/material, mat_amount, multiplier) . = ..() - if(!(material_flags & MATERIAL_AFFECT_STATISTICS)) - return - change_material_strength(material, mat_amount, multiplier) + if(material_flags & MATERIAL_AFFECT_STATISTICS) + change_material_strength(material, mat_amount, multiplier) /obj/remove_single_mat_effect(datum/material/material, mat_amount, multiplier) . = ..() - if(!(material_flags & MATERIAL_AFFECT_STATISTICS)) - return - change_material_strength(material, mat_amount, multiplier, remove = TRUE) + if(material_flags & MATERIAL_AFFECT_STATISTICS) + change_material_strength(material, mat_amount, multiplier, remove = TRUE) /// Changes force and throwforce of an item based on its properties. Split into a separate proc as to allow items to change theirs based on sharpness and behavior /obj/proc/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index b70d6af0072..342bfc981fd 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -259,7 +259,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/carnivore/catch_weight_mod(obj/item/fishing_rod/rod, mob/fisherman, atom/location, obj/item/fish/fish_type) . = ..() - if(istype(rod.get_master_material(), /datum/material/meat)) //who cares about the bait, that fishing rod is yummy! + if(IS_EDIBLE(rod)) //who cares about the bait, that fishing rod is yummy! return if(!rod.bait) .[MULTIPLICATIVE_FISHING_MOD] = 0 diff --git a/code/modules/manufactorio/machines/lathe.dm b/code/modules/manufactorio/machines/lathe.dm index 559b92b7c10..c248bc6e47c 100644 --- a/code/modules/manufactorio/machines/lathe.dm +++ b/code/modules/manufactorio/machines/lathe.dm @@ -112,8 +112,17 @@ return //check for materials required. For custom material items decode their required materials var/list/materials_needed = list() + var/list/slots_chosen = null for(var/material, amount_needed in design.materials) - if(ispath(material, /datum/material_requirement)) // Material requirement + var/datum/material_requirement/requirement = null + var/datum/material_slot/slot = null + if(ispath(material, /datum/material_requirement)) + requirement = material + else if (ispath(material, /datum/material_slot)) + slot = SSmaterials.material_slots[material] + requirement = slot.requirement_type + + if(requirement) // Material requirement for(var/datum/material/valid_candidate as anything in SSmaterials.get_materials_by_req(material)) if(materials.get_material_amount(valid_candidate) >= amount_needed) material = valid_candidate @@ -121,6 +130,9 @@ if(isnull(material)) return materials_needed[material] = amount_needed + if (slot) + var/datum/material/proper_mat = material + LAZYSET(slots_chosen, slot.type, proper_mat.id) if(!materials.has_materials(materials_needed)) return @@ -129,9 +141,9 @@ flick_overlay_view(mutable_appearance(icon, "lathe_printing"), craft_time) print_sound.start() add_load(power_cost) - busy = addtimer(CALLBACK(src, PROC_REF(do_make_item), design, materials_needed), craft_time, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_DELETE_ME) + busy = addtimer(CALLBACK(src, PROC_REF(do_make_item), design, materials_needed, slots_chosen), craft_time, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_DELETE_ME) -/obj/machinery/power/manufacturing/lathe/proc/do_make_item(datum/design/design, list/materials_needed) +/obj/machinery/power/manufacturing/lathe/proc/do_make_item(datum/design/design, list/materials_needed, list/slots_chosen) finalize_build() if(surplus() < power_cost) return @@ -154,7 +166,10 @@ created = new stack_item(drop_location(), amount) else created = design.create_result(drop_location(), materials_needed) + if (length(slots_chosen)) + created.set_material_slots(slots_chosen) split_materials_uniformly(materials_needed, target_object = created) + if(isitem(created)) created.pixel_x = created.base_pixel_x + rand(-6, 6) created.pixel_y = created.base_pixel_y + rand(-6, 6) diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 9a16feceebb..bd8dd61d250 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -189,7 +189,7 @@ accepted_magazine_type = /obj/item/ammo_box/magazine/r10mm actions_types = list(/datum/action/item_action/toggle_firemode) obj_flags = UNIQUE_RENAME // if you did the sidequest, you get the customization - custom_materials = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT * 30, /datum/material/silver = SHEET_MATERIAL_AMOUNT * 25, /datum/material/iron = SHEET_MATERIAL_AMOUNT * 11.5) + custom_materials = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT * 30, /datum/material/silver = SHEET_MATERIAL_AMOUNT * 25, /datum/material/iron = SHEET_MATERIAL_AMOUNT * 11.5, /datum/material/telecrystal = SHEET_MATERIAL_AMOUNT * 4) /obj/item/gun/ballistic/automatic/pistol/aps name = "\improper Stechkin APS machine pistol" diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 1105c0a611c..78f39dc9ee5 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -3023,6 +3023,12 @@ target.set_custom_materials() var/list/metal_dat = list((metal_ref) = metal_amount) target.material_flags = applied_material_flags + if (target.has_material_slots()) + var/list/new_slots = target.get_material_slots() + for (var/slot_type in new_slots) + new_slots[slot_type] = metal_ref + // Safe to call and doesn't do anything as no materials are currently present on the target + target.set_material_slots(new_slots) target.set_custom_materials(metal_dat) /datum/reagent/gravitum diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index a6e3c103417..bc1d5eaee0f 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -70,7 +70,7 @@ other types of metals and chemistry for reagents). var/list/temp_list = list() // Go through all of our materials, get the subsystem instance, and then replace the list. for(var/mat_type, amount in materials) - if(ispath(mat_type, /datum/material_requirement)) + if(ispath(mat_type, /datum/material_requirement) || ispath(mat_type, /datum/material_slot)) temp_list[mat_type] = amount continue diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index e83b0b77fb4..b09378ea49b 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -626,7 +626,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(/datum/material_requirement/solid_material = SHEET_MATERIAL_AMOUNT * 4.5, /datum/material_requirement/rigid_material = SHEET_MATERIAL_AMOUNT * 1.5) + materials = list(/datum/material_slot/weapon_head = SHEET_MATERIAL_AMOUNT * 4.5, /datum/material_slot/handle = SHEET_MATERIAL_AMOUNT * 1.5) build_path = /obj/item/melee/cleric_mace category = list(RND_CATEGORY_IMPORTED) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 727518bef72..594094deefd 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -1122,7 +1122,7 @@ GLOBAL_LIST_INIT(slime_extract_auto_activate_reactions, init_slime_auto_activate ///Definitions for slime products that don't have anywhere else to go (Floor tiles, blueprints). /obj/item/stack/tile/bluespace - name = "bluespace floor tile" + name = "stabilized bluespace floor tile" singular_name = "floor tile" desc = "Through a series of micro-teleports these tiles let people move at incredible speeds." icon_state = "tile_bluespace" diff --git a/icons/mob/inhands/weapons/polearms_lefthand.dmi b/icons/mob/inhands/weapons/polearms_lefthand.dmi index a882482331f2d74a5ccaeb2b1dfff69f496e8214..9cf37e16e042a04468e2bb6450ae3f371dc02916 100644 GIT binary patch literal 12139 zcmcI~byytVmTfmQ4#Ay3CqN^?f=jT3U_k?f5G+^%0fKAe?(Qy0<4$mQ2~L6&ym5CL z`t@(-&U|-f?!5PA=Dk1qd|maOI#qS*?7h}rXN9V%$PwVu-~s>u0tI=Qw*Uap2le}i zjfpx_?O!gAI-qgaeD5e@=3ruPVe4pN^A!Ma1tunRenopiBsDgyZFRnEzV{Q>stp=j=+Pbj^M644<8i$bZZ2FK746%)hJoJP|9BrMTbdru$GY3ngGIZfwN9%-I`mgm8bp3!kqL2^s~j$ zY%V_wr*Z#?w+Xd@ElF%^4UTeiX4QA;^*~GS4GV9|T)A@~=X$8>$9X-%CRx|pCYECk zhk!Em{590X+w-^=CHHN?C&E41DgbwhNJ;Q*F?9wiJ{xMymA~*T@ zX`)B`tDaCb?NWY;G|N`0A-FKyL{^OlEvy?KY$&=P0K_C_3aOSl^88>~XMVf9uvA~% zRI-N@v%U3l(w0=!zDHh6T&V=1o})4jAN3Id&S>bU_Kh#PfXb=0w8^ z`;2r;Ug{$g+DcA?7%Mem@|SDgTZKkepZmF-?<0`iTR(5?wno0c$z*{`4$`}A7~*YZ z!6H?Jhh{ehG2)A#nCj$#M@lIQQs*z>L#&o5F&xHKs^Na3*^ho5j?K#ho6g$k`DBS$2R-5 zr_xq?x16%69j~37M&n=*!3w(xJ2ZJTp=KkR^bgwo29{qGGY2-q#j)#BOyA}ZQ(9Zp zQUssuau~XOl!kW{s8+ZH;Zt|9v$N0QadYrEe^Zl3;7H)+usu0~Hue~rUJC_@KvJb% zz4D)$oa~yPpFhpAG&B3Ip|3weLrbf{XfJKTEi1e_jY9{-6uJ-#W zL;KYuGqYy|tlOyRaEGZnC^gzwlggy95qhDiHa48ud>vzZpwmzSmjYmeAk$Fq4`(K5 zhfT`*-j|;|#h=YJMu?xd%b~_1ymuo{Uz%7=QXObJ9P-2A!}6L^_FmN!+7s12@3Dxg z&(b&2W3HeQnzk^kDO+)qL?UWN$+h*|e!~62Bw2PKQW^}IV$J~+QY4Mlo&J%BJF=1D z=3b`hQqve;G+3P<2imLX4vFPX`4sIJPrfSsQ6l4hqv(gthm~bHh?HnR63s6sLD>QEapsex_roOWO>~?erXb#><~4GT#`MsrD{k z4^YHGZ8mOaehVwEj#EaAa=1JWjPMCD#$3d{{;?_I26Ky#^LVjXk?kEDbyo05F!qrE@#PG@~3HEapV&;1~V+LTr&c$i0)I3N9 zl8~RpEIwC9DEd}F)DH(NDJ4-wD>dtO)PTXYjm@HRZO&%B2Wh~lw)Ogm2F9<_PGH5$ zw!_I#aM)956)SxI5p94lCb%k5roJPUwa`KU7{ibPz*c1Ua*+Gcabho8hls_viPMgg z-*Y4a@;z*EBZ*qBXECk9 zDFNInNlFw)CJV-@X!EK8pcrdYD+IbBbw}A8{IglME;wv?wtF9I3Si*_vb~rmD22Hv z=w@sGD0P8EP!C%10B!b-E;SMv$`n|tkd9MNoKHjIOz=DIKG3j1RMM45zEP6gMW)wP z*2vH-Wkwc#8VUyLokdR__xnS5!lIufnE=s$**6|p%bf(`ej zD|?yZ{lwlfR_Ff^ju1LL)vELT#km(vDy6+rEcdgW$t(R0%=OJzO?XfnC*c z7WA!%WT5HVVk8Xd7b5%k` zGwPOLYw?YZ)vNEoAkL%@6feEu@x-20O5kZ&*}6*Yls8ijY#baO5l zAr7+^N967WAy(p8b0?^8!1Coz2$EX}8X%Oqm%UF)XULBW)dm03L<1-l{V_-0oRQYu z(18VvxV$@0-x3`+m(!P~A z{|k#hy+K9Hk6tEU1GQWa+v;&=R8(1YrNnZ?_rgxKY}NHMYrYkQ>bw0aT?fU04(I-i zeAd|8owZa}E-Hz?F(&lmgrt(0_q^7nDeEaZJHq6pS!B7WyYL-R^R^db0pQ)Xi0OY91pqyv1|9%f5bzkCG0SA zsWA0G*EAyNIAVZDfeXR^tJ3>Vf6-T@=UwJ*d43Erk@`=t^}(N|)T=0qViN;5k@c_Z zWgRbE-Lu(&ozFo16_X(G!TI?Q1*N4w#bJgw(hW_{0gMLtUZeaGX{|2Y@!~_F&7Z+r z^6&E1?Y;`;K6BRDJYIgT?DVbizTO-82!)m=?st-h-Cj}g+_sOjaJ%*b9Ho1P;>Or| zP11flkU=r+aH`%@Pw~qsiGShn*aaR)(!lDF>kE8fQ zp%%Gj^1Y1hfPny)3aA9Q0iH^m0sDM(!FX^i2%yU+3@ri;;)4LV<-`GEcu^?FS_uBn z*8Kknb|B@ub5l1OxwUh9_SR9c|J?$Dc_<(f8SUas7$Bv_yd)4UW%|auR@GL%Tsv`iQ3I62_{Ef z==n#54@`-`=r>IA5nip{bC^Y(6O_Mxi3mk9jQu`8?0)pHGqv1~*yNThnDIXLXULen zvt(h&xU0#oE^>0({{e$dhtl=7p@Mtl=0r6rRGjtSQ0G4VHr$q{+Xn=2cWzEQhY47$ z8r2B}6v>YN_Dx(x+wB(?yyn#)+F3aU&mIcS4~}zPfp~^_S6t2e)jLx#WnI@k>d%$^ z^w5Zl0nFLi*%X>sOLKGEDAQ-PC@8J!WQxZYTIQCpGEx;1d}}iJPx;|t{c1V)ht(X2 zSo(n`n_bZ#$8|l*oo@Fce9UZ1*3C}=P;WKYr9y9T*_)eHe=d3!P;gaSS9kgT#}_Sc z_jVZUlZ}?vuh=rV3X$&{$K8e=O^r1(l}6ofjnD#(2^CTFy~uW5{5}_JF8$)7)D+Hp z*|Ya}{#1q0*HGVZgsa&Da%X!cdnGVc4kaU2^2Zq<@qW&NdS45Bi(M0VxxUru#$d2u zgb{PA;lmi?{X@g&!RG9JSEsYOOROEf?%;PG$PA!A_ngZun+BoR-I#lX-teQc_f>ft zwbK3(hdY?4ITlso-9`JsCZi*FLSv(=OIuQ2?)+zpxyNg(q6T5iDhuj;z5cDAjqi}B zG1dreDDDl~Y@-Plt%S$*Y^Og~dp7lWI;ZEuCZmhXg;&jPIDPWF$L|kD{p&ANZH+A} z7%LFgJDoNLw!QUG;cPlnG3R}%X1BAgs~Un)`RBMaP&LgoCQ7fgFYj;GJbtHA?hO~)&Rh-rqSgJP$!?_hS2EIF z75Pd7dH%q4QuC%w(0P2MV4ss(n{PFcyX|^yqC1#S@?p26g5EfY1ab*36jWFilhB*V zwr+ZG7qnZG`Q7Yd^Lue|zg(AyNtjmXt0S~i>wB;sDY)T@ZHph7>;Q^?{c~A>;yE0O zR@yUBwldFQmeLDzj~|z!Y6FT-3Gu_OGv)fw#S<+Y`!-}jAZ&Q7J{r%RfWrqrM zN{L6QXsZV}@!;@Ju@waz^nArtOHMQTC`K55mjY9+hIKune=+c`TyK!xV1vhlsgohC9(CWkNW;(wYHR5)|L0Ai;#zC?W1ZryQ??!rl}j&^-Ej$)Vu+i_Csv@ zMFm;L%*@RDJ*29p`LdDra)9>x1DjXL(lgQcPrp=1;8PlURB0F@H_66Ah#8vrr@1D=Qdeqz3>Pk z?!{ZN54-gzlt}qgpqi~C7e$wvEl{na!}ZU^)VBn@Pf>Edpx(* zdpqNjdTG7J(N;|N$DL*SY?IU8LERRkb&5xLVfi9R0La7>*Z~4mQu6xZ{3XHwZvM*j z|3`5K)$zYw;2a><*_c?#=J{l1v;QXVY zTxIKT(#T5C@Ivj$%q$q>Yp_t(=k_En#PY#G~@L!G}h(#3MJ4 zil)9D@k9Qkx~#7;v;Hy8@k&n@UE3wUCzV;ub(9-6@Z{H6eZk}Z^6j*L>>kQ&W{Jld zfgNY=8Mnlx5Q-CWvb`VLZ}B3d@@&~6?Jz_Xo*iDBW*V1!J9}gQY|rrB(CGDV^D?)q zB;^4vLtP#t8F8F0Ee@u0#B&@8hSk3=HhYm#h?as$8pHWeeD(_dW}%km&GQqxb!OHh zO78=HGx1Xov$NCuzSZDbuuSJ!7#$^pU0U#f07lQBaOiGc%8Sy`EF@snNuM!|iHgw1 zwig>blAbR5EB7rzq*_TT+#f>|#*uezDu*IuLttr|l}WK7re&{z6RUeirI>sqVw-^fYneQ$s{mT8!} zJm%`~_4J@%did?qI>?YjQ%2rn08~inK4tdD{>b(zLWyzvG3R0kB8rquG-xPRJJ+G0 zdi{2}Z#`LmtMsug|1=HpAsVjTVXc6*ohXhAkR0#GZ1pgCae!B$oh{fn_Q^gBOyi3K z_rb)702l@h5h{_$0248&(ElQT_R_C`vcT9^UOq3>6aeznJU}8cO``uGj{Z;L@9&}; zEO=?)UNnVF)GjUc4>Yb95t3pk{0OFyU%72P#nqD9+x-|bo4McanQSoh5lxD@P!E#_ z1uemK-_5?GRMp--!x}9eyY!f)^3ex|uc-r}RWm5jT3QlI>UoYaa|%kp9mSEOPJiK6 zeTOKMEd8jTsc*G8lqjoT@22xSJz=RW{$5hSH8X(oKzzxgigMm1QHlf}`_R(LDXS=-Qv zz#KB28s@+DG7-R_t@7LIdVOTh>FMP!fdWxYlR}`d&g$;rU|ZEbfeU-L>dL>9SLKJz zpV%T~xK6GrgQ!i>@;czfKP?VW^rv=QWCJgD#lgZxa`y-6WdoMRE&Gz{1- zkXX^Xy?;_HQ>tD2n`|oxy#i2j7zq~*o_pCGvjkKl52(1dYiV71F-32QxD@hHJ8_U9 z#aDm#R2e1w-d;E=ANUrNc}JDfxfQ%P4b5PESzJMI(Pic#CzJ8vTf=spi3$-T5k|^s zr?Rw*KDit(ubdyds%U}hnE{V-==hmWSAA^ib9kmU;(m?NkdW;G!{ITd#f~&Y1XaU< zG94(OJxo&R?e3lp$J7n%$B^nUSkWB<~Wr zE;@N{6wCvc!<_{3(~XkMyZu^ZOcGh@&`Ykp#zkm@EJ*P=M2&|JF#-_x@F+Z`{D5HWqr*(`2?R@mIYJ9riFD3x1c0QKL>pKE zo#%=q1p~}Fi1-)=GpUUj25>OHW{j}RDCi`bPjaa0Mo?n|Yv3s-xlF-8D$~OYA^&RR zFck<00LMVk$C>R-0hx2i<`j`XZ()cCGZb0ykxBzeClAB|$B)QTuSv-PfN=u%fd4nO zDUsium)KO}y0>I-22c(3gU`kZY3_FBK=^(pDUJea#nRb3&7|IXc=RRnR71t|YE%$T zsMK96MFL)BoX9^|KCpZ*HzQpK9X^d9_!RT(k|{%%gT)Ts@+LD%JiCVF=*wsdYcUMG zMLh?w<2_sy4VI+9uwAJ<%Q&4}E=9)JMTDEq{{(CAORHPN&66sNPhO;7(J?BTqU8r= zca3XkrGEyj1>miw)u%@l#V>+{m#?PiphTK!-+s%$Ntsi8vRw$9h9#5GJfYa+Sd zyJh>9+U=AS6*Z&EGk@Ip={R!|rg==_?>yNU0H*XxG}ng!oY8O9zFJ5+4SK@Cu746hifPO z*>@Rt^WQ%Qlw2jy4uxZ9vSc!hg{B8r*hBg_7%|zsch=r4nVblAnhYf#vBjs&jZpT_ zv?){AY8WT0N5#c|Q)GQpTa{BpQI)*Y3oR+Xrl)-32V&XwT6B`@n1Q#A=W>9W1L9jRXGEA$Z*d z-;Jw!_Yk8Og9s1+vMB^mJ&qpQ0dLUG;w}*y3OMuPgRzX1-wx?hTz5YA){Fr09H0XR zig*eAyR`2Kr#Lla2?KVe)*MCHuViO%W3vpn#r;W1bs>9oJCi zRuEaXbo!2c_nWXj;}l>rfsshEP+p4KNM`)mSIC%)21ok5gsDwE$DrDx=WWJ@M3UWN z?FKdzx+Z;20P9oNuNRu|4&O07-~4_?_V!VwjME&4f-);~d5tJ3Ua4N7V#rfJ1H1LR zbgDax`lX>=F40(VQM0JKv{H-oe;$Vp{5UOb7CGoe@eVY|Y7Sl3bT+EewSV7<)w#w-V>&Y1-4*rH=U^V3@#MeIb+#R_THEDfhe zk_yp_G2DdMO`Uaa7Bpsu(`eAxgY0J>FU=4qVzL$uNWYGeXwEl*KR-Gf(@>q~x660f z(%|(73o_23vY?5;=Ce_~$+b?i2b~()WX_NzV#>2bV4q%D7^Fw|M)(t52{}cjhx7F+ z%RC3PrDXl4^Ig1<^bV>Js&>%pS4(A^5zq^TWQ* zw;nF1h@jRNrwDHq7nY~K?9!9#+quE;tUWKo-eiEf#S68H>^f+DgE@v>&75?W2A#7$W}GIVSUL^3=rLMkXc2p4vyKfc-bH&}#m0wypV2 zAU;C&9pSQ#qHJk>bz696fm`8yNdBk1*>o&>Ao{Vdk`KO5Pxd%lM;@?Oy)B~eB^sqB zs1;L6Jj10R8@@O_mws@#*efyL_WM1$>*jp?Y)8An`}1RQ`6$y0^blFDmt8#yP1FN= zV7LbFn$SY;Ek_C61gPa8zz~`$BD(d_BKzzSDT8O-#Xb4qx+H@W$-;vL;qQj?UlHYJ zWO85))uWO!E1dvhX}kFV_Ul9MhM$e+MPswYzm#Qv_om@EJ<1dd5+a0o<1+~-uzQ?*saxCj@qX&F6ll0EO7~^z!b{y2 zeg-8+v)Y~PBnRPf*#%{I$TZ{FqCZ8?ISs`!a32Y=Bz*_!y}FTr^z8JCof04UvA?53 z*!P@qh&}QuVe7>Bvw*I=CKTJs_#}++ONCC0bE~YfEqr4qJQA@k zsjA;yu%}ut1-6la* z;h(p}p2X%Yi{RML9lq-;`0zpE@T0Z0b*_K@4vl)mjY!3xg_1iyQ#8%2h>Iv;Sxn=( zHGw#@H1%U#pf~+%ki&tAA5LLfoO&Xo`gw12{dNK5`bao5JX7y{V8!7HE~yjd?WM$= zr})gg@1IN)W9nY)$0G|MnKjC9I zB$uPUT8HMZGCt+;DkR)J%q$v{K4V`S@Ck5r8hj6fO6&78vS*LmJz8@l z5O7V5?A*8jCWg2r$L8-KUCO(?`xP>lkMGQ8a`FN5TYLD0?=^CS4Q`V~hIYeuAhtho zN=Ov!9zl`FU516$3(>?G8<95 zm?naPd5~(E?J=FZVsNr#k)_;rvwlx(>>sz{mrnitgw&6@`I*%Cd3>&8WAi=gy)j$6 z18F;JbT=1^xAkp*6Ti}Q^k!TTn+!KbGnbcAe4TM~=mmR;5Yb!75-Z^DCX1P;3&ks- zoAQbii#m&5=dO*FKJ7M3z0>NwSQkJ9Z9)pw z#TUp#xq%G=CZfwgMh$(HCb`wtZUGvotN#vQ|F=%1e_V{Cw(qUWj+(t|jm>|}MqCTq z&8gEhM~nd-W*3|4?kWTbDrig&oL=9ls@%=QITl|x&r6!ZmD49YJH_S~mf*vboVG*H z*r^DUvIvW>-M`Stx6Pg%Bwx170w_J2J|XOe#cXO)g%(rTY6<^vbGk|0seZbfN!wWX zdXwegc3;2LZ;Zw&Jl|G%ZRU*ZMrJ7b4wFN36=P5XbT~wd&vWkH^cW&MF1|S|_2;>z zaD|y82Q86`@gvW;M8FuGCwM_5Jq#Lo0|!dw=SIfdns$>3luK$AZ?4Y$SZA5GY%08j z&VLYE(!lD0wcg&E@Yiqb2M4_##w%tAR=XEL(^*1u76xs3%~lT?eoK{Zc+L07d$W(p zN}_?rV{&O{d8A*_L`Qt^ghM6uuc(vt_9YCDcfCPe*+LHvEE(%*K1GbcTI5EZ_ol)Y zi>gPHw`9IgUv!cEvhKpXzM!`XFnh7S;*Lg@iZ2CR1!p{L>6w7O`-Oeu!IvGbMNUb1 zfT7&}`LhwT?nZ`?b2P2zv-C z0D(Kb4#ewcFh_cXM_!*+#5VM3BS-l3;(Wa)Ar>f4(Wgm5;>XW{&n(U@4ITDE*?M}@ zvKfe-4#kHa^YcD2nf$d*7(Nrz14k^M@h^%-TvkB1``e*`;x(MbxbK;O}`B|^C7*Ml(?LMpV1<=4~4cGP7I}wdz8C@hd~4% zU{}jnIHUzI?J#||c4n-3+S0ieg|&f^la+rjHx_;pYWel6^AJ{67=zp^1Hi5bb}A(k z!T%@YfRC(TeYw-M3BpSR0R9SoiHp)OjmH@3Th0X2-MS-FU)~+x?+?=eq$r7~2wq&x z<}c-CsUmvEv{glCJUP;^@KHr_{50NB-S4Z+TrHCyeQdabp*IU9f1C^n&+6ZFr^!w> z7M73dOis&?j|wGORgO+KiC%ut(AeEI&7B2?;5}n!5&~v^>cGh8$qw-DW2S5#+aVOf z67RFF_ZVA(FXF%(ARl+-b8>S#Ei5dIP}t@+*8K0R0faBplzDe%j(7U{X7Mx1n~ST@ z==r0TYjBgeKdfX3S<435X!Z5JhDuKz&FPT8TAFFtj%Luynh0s=7O?L&R_FCZkOLiN_Mr~N*OaF!ihe)^S~Wn zKUqEJ!{~bU`&{HJg*tpWe^Hu|loz5e{!r;kpx~hbR~BK=JaM|Jfq6xP2`tfyW6k2& z5C4r>@6;>jU-JN1xpnH>(F5ootg)Da zHJWjMs2wP(sQ4@xk|%V@bJxj_a+puBvol?Ca&ksI7!;WUmS-mApWDrw#sL7H=9FY4 zd=-G()+E`yK8tV#2nLPaM3Stf9hJ@ECOTBAmlvd~#A_kKvfjELC1$+CIw4qo>iamy z7#I^QJY!gSiLU8CgrWDB;SBA!IzX77A9HxM%cfhi+w*D(J}!z&?W=oZgxO&~4)76Z wU9XL{2VmpTpbS(0>WluzY~%l8N^Wdct?~{MWa4OL?`#FJ1A*LA5+*9_{xOmJug*zyvCS1_5A~~w7D_xT zBc~63qOo2@sxtsdZ@1nfrQD|2-4-uDW>^|w9HQJ)%xb02lg6HmD6a22P2$r`VKz>r^ zDT%Bj%Ag@K<>0P}HvWR}Kr4Ee41=t=Np60i0e z;h?OT>!^Cv$ij(jR2cWIn%}pzQe0OoEwYMwhQuF z&nMNVU?7VBVT+A>l=Mi^*SGaq6P@e^o$#|JPyv&al%e^eC`laaa&Qn)1a*fju0Ph- zhRFLYrem28KK$avGE?m5wVi+UD5>*t$MyB~&-8Sjiq_!*p~>*T8&S$^9UnHad*wm= zFCu^F+R;ZW+o84SMC?IsLw|CH(nM*0XUWle`Zy?5aO!>LjCh=21gr}B##>uCsJZZw z!*TOCapg#h6r%9^BVmabXIa%>kquBSo_*oax58uak}ozFW3_dWmQ+Ro)XdE6T#S&L zn=O&rP5EDp->u0Yuzr=raCd;zE#G4<_SfBk6s2E#!uze~)N5*c*1Za+Gczma6I}S& z)nHNYasnP{-`#Ehz)bIW4%xeE(T`;*<`y5GJQZjaSL%j|3VqdITBuP>Mk^-X zi^!0Pylr#SrUMODyV`5u3Pkxrue@6g2KLUbJC81#GL_}1OS~Y>zCRq9T~^L+P|W@} z^ZJZ(?Dic|Xhg|}28)V==jyWjRuByIt zJ@{E$D+KyB+SlJth}L(j=ub$^I9O-VIU2zZCZk_k=gV@Fe|Z<)?WV?!MBN^2e`h)o zV@sIpOLorqXp^4N$;n4fze`)X6BZcX6(7pwU$6l?+-e~zmh^kWk>F1@C##IYGN9|$ zWin8Haq)ibSKzJ;T_)FpBbyog1d^AJs05~0FK;%d`rmIz)DT`T7svx4%8uc=2a<@- zqc&)@({+U>6)O2c*X{MpYM%LvlctO!$(}G}tQO_T2s=$$-XRP?^3*{Ca%TAI@YQv7 z1En(I6OMQ;HuxB6%dUvM418icmti%T&p0qe+=YQkIYs4t@^cz#&7dUuVq(Lt;(*CF z9)C1dwYetVGrsZd(%HE3?%mCQyWS@WPSZ6sB>PL|_>oAEP~%&1Adzj>Yn_iDnW(9$ zuL`p+<{Q7%)f+YM{3~y5We}BQOsuP8X+iMmi8epaT_K@t)c=&6e^HKXGo?Yrzk%ez zR+Vc602cbPAe&s{A1T*cg}LYNG72Pa;@YK0+sB1}!y&1u5qqwMc}x|V)P=Y1)$Hof zezjudRS%WdF>l_iv!3ti^_*&q6O)HHOR5D$jfsvFE0~yeyX7fBDNtQDSSGnkhi&#O zJcIXjhl(#M)~um~JElQdsSm*ZvvPP4&MZm62NybRzpNHhO`dyg)k(Oywvk6iAFL}Y z_;EPaN2tbDdyf{)p~$CcoJnh>a_Q^s%z0 zO%O_tm46mj;W6)}KEK3Tcnia^Ij5z#M@k=gF%4Zg-Bi@%TvAKoF_iIw8}i!k7&))V zRz|#$6;pr`B)#-$`@FfhTUGCU{gY#vVBBFP(DnNCd5XA?(A?Xn%sl?KjA6lF~PitgnYX$S+PLsp+H7OwP$K|A_m;{&kbz<_ikxW@N$=piZ6Wgk)0-1+&Gn zyxINba)k@X?6VuKduWxKbKTbmIIG`lYg^|$Zu|g-XlQ5-EK8yz306|RceNi~MvQF3 zYe)@lg|xF=j-qDB)RePHy?vp}7e4lwereDVXTb(KofA+NKp`}U>0Sc6w1Wg*PJCq+t58e0qbb1n9*bs3pS(^LqmUPaL!UZG8jl>8^o=9@JRF@&w6mA1gK4m zzNS6>TN+E%XQb)t*WXM{O;?Jd=gZ;3UmV)quTjze+Gh&*c_5G;gbPpmzN&AfeD@;e zp@}utd1^ZwZ3i)sW7a|^Vjq3vv;SKx;#N9SOG=-yK}@#zC67#si98fpPKxr%HtTLW zdtuX~Wd^af9{))hxQL-=M!f1f7!-qD@K??EgmWB9rmFztztl*N?7V-I_ORdR#UX~Y zEsC6eA*4AHwSeVLr0Kk$yQDPrtd`7!`bJokL7eS>s3`uY={ZH&E2aDKTh91W+HFZv)#Q*o49{)U?kmxO_pac?K zL}3F@-kef`bOQ-EN>5#PnX^yi__-HK^W%+l{a>yYx3K?8*J=4S`IauinTVz5{4U7i zdc*W_Ae2C^4WumvI53eq88-QC1b{uLw${tmrz-z^p~bF>8iwC|Wjk(ufH9DIr`=K9 zJ#+Sj)rFrT7SPqMqssx*@^Ezx?5(V~q@g{^Zt<|<5XWF|`3{Bo<)esht>RgNz4)0y zGckqCyfYvU8cho=H~{pt^>`(%;4xawH~u5rPN;Vywl|nU))`NW@PGZ?T7!Gp?Cypz zMDBlqbWQp2^2Q9nj4pQD{|%&T+G&JeP^VN>k#)sjAiM8Zd=A}ys$KXE0V(?0Thhwfy3%w`vpBD|RXg{?U^nu0K)IyALjbN>C#H;n+`2A>DXU2i zZ{!$2cQ{=c0e#fgo;wiqg&N8*Mr8l}E6vZ(fBZ?_cJ`dM0-(&TZ_nxqT;q3AU7d-C z1?wISDKpQd=0t6jj<1~^w}0Aso!ZVtOioFO`HbX>tla`e5eVnH-O%glva|{xj7lHr z1EsFEZsSvA+%G4Lm;mn@~j9%O&tEd~lpA~UGlPdh= zdoCP6cDSefOW!H!Fa7Y1Sf2y>dY7U=iv+R-5jRr*6Quv2=T-Ru<-LFD#Qv@Z`Lhc4 zV;}oR3s4!~<>;%Mgnznf|BY)>3LKGy+dV_!K77mt)Jvi@&zg&!y$DRt4-|=&dDgai zWlBJaI>!N?!y~YminGB3>HMMPJDjE~zUea2VJ}%G1Z04}(Sb}EaS)T}bAWiJ@tsIww>#9ab5z{vW~?eL>xo%bT~L1vw_T@5!&}@kN3fU-22+pson2fgc%f zPR=u#Bd_J|>FDT$PcGkmcYCwoEY#X{0XtV~AaUn6D1OtOk6#xWYvf^3)^nH2%VSna z<%>`dV0fA}Bdh02l?jcVg906!8#Lx)T5dr>AyCC}!7%jHZSSYxv^CmJ;SMv2Tvx5j zF?V@lK`!6ZCrb!$fpe;O)Hx1*2T%u}7L@{(vG>KCg-9HFGf4&NiF0uX^UBT2GRZ=E z$;>w$JCPpwXbQNrD6G^6Foju#Lote$wrkuGXf&Nxt;*)70&5h@NWKj2+VvL8|pOltRlb&eU^!WH` zn6*hApN?BrvBbNA6;yc!10&jjg(msWu@96HWRKVx!#;0L6?Z$-@Ie8Yao{GE^2QJC zmdNDyg&T+kj&zwZ-C>&>`ql$dpbZ>rq^(~V7pMOudF%ukWvvARgPrJ zkqglx#9uuo^9#Mb^+p^lP>H+lw{55Ukur@!$>_xbb8}y85JMwr`GHmd`;UZCG?ij{ zwI@bpc`59(+;uFeHwg&|I1w_1W-K8#-^YOET=%x!#WgK6_A?o&SpiK0QvK_%!OSsB z^b|x*q-rrz==#B5d^l2=>k&TQ8&&TM=ZE)DCj`NEXd>k_i7?d7rH%BZ4<*Pk7(e`h z*aJO1UITX1sAD+i{VqS$bgBuYy&iYDJnQKgY7I!fx6!rz3DuGY*LMA*zL>;EfnR2fbc*9wooQ72ySi6N6jqi>GZck|Mt zJzy0KSH-iJ#hf^9FZlzX(xqx22tbya!)$GBrJ(k!GM}KnD52b(94=8m^ldl92d=9K znuILWmb7Ox>#kWy-TZzfEWAFRqX<;y{JzHlj4Ok`1w=d%FQ-d%ds-iUCy@y*h=?)x zW55@u{nUGatFCy6_QDV&0{{G2*57YD`cm9+qxWr9zg2?A*_IOSkDGMNbvo_Mpa zZ>orvN3Xs-+YsuTqphti<%Vnz=sf}ILyn`6TA~H~Cj#almN7S4*Qd#R*N#W@EWop> zUDy$LMOL=r3&F$x=d|#jv$4Z1ySul)WSE(oz`0iK$7bXYV-L`hTwGs{Wp9!fc5$>A zJ5QR^LSLH4%K3){$4v|=s8D_C`7GaV0HJ*k9+A|0vFfXgmvP?GUP?Klppv9AF%H80 zzH!c>_1#eK3Yoz1hwyHWx5p%_<&TYv&xZ-ql6S`zKD4r#kmMR>8u^Y5^Sf1gM$$;p zzPJ0k@%L9p8*zm0+1HaJZ>nFZPLSHX{r+0rgz49!te<_u<-FzRn%A$`znM^mskCH`#r%cM3L%MNTllJADbj|F;_{gl)eWE0eCj#(dwG5WR)=ckvP4e8#zj}$ z<^2VyyB;G(Y!5jkK>$Q?*)O3Yu~# zUkON`yQzqz>f@6ZZ9VoPny@cZwcuF&E|)N2NzjG7U6L(|p&V!x2DdD51tSl#N#!cO z3ZQI5W2b-buaIqSfs`~jT~z8Snau6304N>LP8F3B7&nPEe}We@JFK|fWKHXaug~6s?(tHH>H;0pjqPnk zpoz(fUG$h7EBo;e)0pohJ`J!cvZS!2R)UyNPc1z)PGN7n56MC#pkp+?mwn~>Gs)ZI zH(F-xp3;Y)a`%NHwN3#QG%8;0ZsB@9iNOapD4^?T)}1=R zYutfL%qT_&vOh&A+;vld4k%XrG40eRa-45~*RxjHKzq(Hb8N7khh*O4gR$jGlUOPh zO+#@lzEzvs+XIo}c^M@oBrNizNy5vE4=N;q#x1{uiAe3&=v%tFupD&T`Ee@PN$Bv8 zAjj3>>8W6)=lR2Q&`wC(ZGp{v{^K7GAOjK)39?b^vLU<~>`b}78xUt*hHr3dBDx`| zs3yZi&ggJPt^=U)!!v2+i^YMdc`5YS!2C&7p2JF<`Mx14|Mnuy>#L31`S~*FJG{;Y z_V~x!i1&AQ1~kw9Ra;GvTX8$Bc6|9QaV<1h??iKYb_Ub40RKD3XAa>36&s)e?-@Pt zCjycFdrnoM(N@buUg#Eh3wGW}#tT3pPeF`HNo5oucgPI4b|c~&!}&{~eGJ_0=~AiwDbO+9m_LJQE`JP$mjRve z0k0-k>VnIjnZ$z~p*`H}vw1w>^I0UXnE_cZl6Ry=M~@BCl~O+60P}66RbW2XO-yF> zVU5BCMbb$;a)Jsyh#SE4CAyB6>6S3scey^mm9wHEe^P@*fIB+u=C+0+yKqi6|J;bc zV$)R%ZZaPlmr<^PT6y&iQK+N7Nnc5#p$u@o)2KBQ+<8k0I*~8?xY>B!Tdp=(V=D4( zEAXG)#j)i&!zjG#HO92(H(F9O4%L_Y|IFH`)k55Skb=&6`~;IQ`C z4ZuOfJcd$ufOo#zO;8Lto^ht85eTFH_8axMhN|0dP#wl(WJ#lTgf|L|4Ue$-rVIf; zVP$0*g5{$FP3ZdosjdOyJRLtMYd(Z81yGNHO_!WlOK^(f(1U%@*J}ja-gZGY67C*O zr}(4Ltdr))*mRy$l-7BqMMEq?(~l!4xawainJn=L&=FQsCk7GY$E?e|_@2K?geZoh zPef*R>v0lNCkVoLy{TkH5?B{LP-jYAI@a6+jbzZESGCnVDwW>&Y;3Qp_z@o7^4#u9 zm0Rz&xNnZ&cW~ca%}u~$_~r|$8jmM!_4&qmvKAbbYoF?+KFG;s<{wTYogOP~`XrP0 zdP{leZTAXY-eRQ)+c+Ztd&P+mB~8u5*v(xYiRVprv4N?s1e7{{n;W}vC#Aw`jX%2v zcLS8A?}@r4IDr%?RU-?cRw48&CS{y^G^h{jbyW-eVdqUGoVvC z-^Ib)l<($Ay-|H*M4}`<+iP`T5-uTa^V&#^dCn{>{PKR>LZ>K=bH_WLt=O`tlu^lC zr!HsQH^0`zkM(j#^nBw2B;+VIxJ%%~>s_`>EZ`Vrfm`gW$zmlgXJR0_ z8I{Kni#>WsuE$vETW1$nnMX(*)BDAPTUAz5nfh~uK%wq>vvWU@vs6In`E=_j=tH-q zGq^DwYt98Eq$ol4UF3l>eWEvqBP$aZ=oB;*zPXL1Lo`U8Q#fG@%Eu`ui~Tn<9Qzq^ zsnC=8_=gX{B-xI^wq>H>g0HnWH-5DbL3OO}oMvqZ`@edd%_rFl7j^_|7XnGgrz&op z)r`%z6ZASazZH!LywaazX%mHhTD9riRxz5y*d9Bhx86^+f(6X41W)b#Z1rU|^< z5KQ$Clzgnf#iVYJk}j8sZVajo6Z^FT7sT^_yk5yN^=A2nzaTygNOESQ(W==^iB-jl+6v{!dXquA?&AdloQ` zGFGYy+luTp#Z!iXOKtr!Xpb}ob6=n#WJvKTwh-ZQ~8q&&)Ea z6{dJj_w12)t>}L~Df};E?aaTn#gSwr-Ri?{}74nC`l*K>_jV z`2qUdV=-8rZf&pPrk)Ne$1~qnZ7JMbt6Ls6Q-D03_hhmAcRh=mC<^RulUOD2RdK{*YQu8yHDFFV*`LhBCYK95Q6Rns1CA%Y2w1S=10Nx{yCpXlEm z^*$j6)gqKW1p}wNGshTPO8NC8&b1Qi6F?yH`Mci&czt;T1yF&OZ9eVE6i*Ct*F~G%~uvB=K3&CeP1+Ro}sX=$=fS3U0eG_~3`9fOM%?Q5z zLtl3b2lPjG_%Hm!UxB+r1Ml4e)Kvs@>z6|hsl+Q`5Bz#roZgaEqGtwfEK4Ot6Gk0~ z;Km|s>Eq0iF`n^JU$jQd_90xv>mbj#-AMiJmFU5e%$M;=8R}P_5BQY@zaVDH)^@0@ zW|7)ndgmu2e^`;c%?4X-c%v6_Q~^)vMpB<;EPUcJtO?P^&$XN(yt~Fy*LlFV2P3Z) z)xS{;4@kjc?acs{BUn&?LQUn%UKcZdGbe2*SXiEHf1R)#S=lWURr!WY4S7-B^g;7J zte{s+4&p@!yB4@1!|`Wed5tOd$izkhHtak}3;_7&mb~@R&7Jt_Xm|xaDCty*bmd0% zx&xspfIB50T-w6(6!wsd_x@f65WBJOCH%oLA&@uke%)XAV|>Ke6&3SZp{Z^&GO}o3h z`H}RFJIrJJS(usSX@p$GaDIjU$JR^ZWS%6~EXX>)+`J-*84rYSp9?X+7p!fiFqzyj zc0fg8&&tUzb+~oR8LiDy(=|L$C9B0Nk0n1<`=~9bzmfwS?2>rTp84s<*7fkstzr)R zE0w>r(Z$g+S(!$w5fZ<;z9A~Kw*wR{7-&%7{TjXuHM9?$aj6}MC(`P(uiq6=OoRig zFcaa-Mv_;u_wMsLPQAZH&XQvJpKX`i;PMIAQK%MHJ@cO`a43G7opuH{5jWi^On@bB z3TZ7D{kw4M@S9R+Zl08rE#QXr2O0X5kuLB(-wZJ*`pd%Sm zsgwNq;V*VeOCLiVY<0dYetB$=wQD!VcF4bJA+#e|ph@Gw0o4X~qCue7nW3glx@5yW z=}YoI!2D#s?eM;us?(o6(Ysj)dca!CwX?KJe^%Ep3riYw)Ej@A)rzuD1a7h7tS;u#D6$=wmo9Vi#o(FtB%!eR=bwzWW%aj z(2M$-2N(gE`pia|4+*Y+lqE;@&j+2uze~zEoDN;-53p4<3D_@Pq9fJ=Swd_A(0=Dv zhkHZgsb#oRJj;3Mx*{A2fJ!}WxIs>W2w5U*BR@x`Gm*8cKH3iqe$ z%yxcGb-7!937_|z)BOr|Ac7H-xfyxI<{w$wOypJY7@a2Aj)4n*>83U6P`bZ!Q?fS@ zRw^IlIWt$vU=d}m->j7Ti6gNubFB#rG(i=Q3(vsbBhy{#Xbj)h*M(XF`3=#pJe0}; zxc*hv(?>LIBqc{Sj9e+)isHyMjh_47zSZq6w6aq^a5ALvEQ{Zs=A}F7OS$=XHBH(s zqm1v)5fhBcWC8Z=)I5Ti(nQMnbl_dDWZ<{Mo3Qzdu+o3r*3Y~$4+L(F2Xxze{srw9 zQVx9g@m4*7J&C2PmwUx+k!iD6WKn&XtMWQ9xa}8&EDD)opOIm(-hGVcZ%obdQMXQC z{PZXfOOG+9oA$@p{L6W#HA*(`Z*ZqreTybKsq>1uR=J3}6r`v&ll`Rv6hCQA5~HT7 zj_qk)BR@3EUSe*MAY^n5B7PzPLV6g3K7)-Li_>^vV+W;?1HbbNK;YSNLMC!)yoo#) z4!?GURpxgEunI;;m|w?j!0t`N^FW!SUm}17s=9TsgebqWoiJ?BorCJ24dNnQ4?I^n zHDiH(V0UOIA)Op>L8T#Mc%H;0!B>b+RBp$R6;+T7&`rM$s+Y?}iq45vDVnV=ClG-) zFzH9@vt#Nat_Y2eh3dNV835Wcmr2Vmt{Jy&b_ZEO6PsBs6+X-`R-X)pq z#*$dRFS_Ws-y@!}eyM%3a)`5x@-+8Re{%$ts;^Pq?pdYuh|v7>B~rpZ)Aql}z*8SZ z119c?PLl!9Zd9JI_>vDo<-(*kpm8U&6U%!!(EE_+$)|AfwYxy89$dVAOI|Rn=y)w#g5$T``<{uuIKtg8gwL zOX2eR{fu{I4sQsymDnDM=c)`^v-s@n9T_xiQmOnc-+9q2V&YQQq@}SVn~WUA|98h? z|5ihM^6Tg*d$-}8nb>!u-WKbc*MMhX(VBkvP*s#-5nq9U2We8pog;gd@#~1SnbUAQyrQ8?bNa89T;RQ5;$LomFTOw^FhK3+Y0Ui~+P?r_ILKC{j~xR5)3$9zjStQ>DwkhH zEI5^EM}+9mO?u-aU=z75*O99st-o7~wEg+8XPCSRa^pZ-t7<(l;zssFf~i#ZDCM1> zd|)y}l_=qumJd-!J!dSvT;_%T{w8x)u0XLxQME<=1mJ1f)!K9bKACmMeDq(_B|TLs z9Q*TRL4RENHg<1$v*=EMB(;(LQ;j11L@~Cq1*SdG^gl(v=G#bB_f*$0FPyL`*&(0h zn;O%qva`K>X@4Ga@$6BXHNs|F)(;R3TaB%Ev!Vy9LSI>!-O3S)qG6%E%zd|yI9YwL zlhiAs{-b93&!HacTHY^ut6N!+(T8E%QdGY1UTIFn)2lghJ2U}QcK61$@Z2fuT&c!Y zAu%*PczS92-U>2!R=-6XA-yTL9dxkzxc}yNd#R?r%@jECw#F{&aES zw&G!lPQ{05G*TE;dTBCMmSB46RP?04>s6m!lEy5CsBv1SdL3vT(|YN;Jvx^ zZXF@k?BM-A5tq96mU;Rb-opG2Yb4#(^I z2HLs^X^2YUG@nvUy(nN3Snn;BYuvls-~ZY-JWSf8hq{PJ@GLVUp}~`TG0VqCApJ) zv9Xr<_AD^j0V<_z{-RXf62pW6HkNL{inmedHT~e%Bek&%^x6!t&VwJlYA=KQA2v5?N6+pQ_P3LaoP0!V=}w4HB0D2FX0b>|t5Qy;NR#tnlU#EJA(&~$ zPwO(xb9MT8)lGxeowquOsvW;bj;Xu4Ak;|mg>c=N;k)vk29^*Wymzd69586O0 z*~7p0DL6c09^N!O6sgb$epZw$gbhTbQE)e8Lw56`2XREW4A|8>njARw)+ z_FQ}6nrS~f^3SBHlXVrONn*$kDa}vEIy=l@am2njJD%kxtug5#)$*|esY?9UapeC? z1LS|0I5&c8h3rT%P7W>qP?R;jH_`g@WlCaq@Ja}O(SP&&me+#$R7_Vc;}cKI6XJ<+ zM(`|LtjNGq)$!;TArr5frtzSv0EI``^KZFigM~>3@hvWlSkfPs6KQNLA5t_#nYHI) zJ40adpS4b!H38c}Z9wj)HONDLfflIS$pf;m@$OfsL>GcdJ);5m@#G4SQ$c!UFaUg} zes8ieT=sCh00Qy5^dEpkXkIWM@p26!+KF&mOLg$g z1H(GB5+Ybkm>nbXjdQp?Q!Q_Z{bo-ePk)jqD^RtoZd1DViCbBfJT|Ww;Ay53-!pZ~ z1_ZPW7`SRdwrIseL-(`OIh0+s|5JPauklMP4C8@%{PB#t-8e9Sd2@u>ZKocam6P!kZTX1(vAb5hiy9C#M zo%zkYd*{A8>(09C{n52nSJ$elQ>XX$?b_cCRaKV5c|`sQ000~XdFj^x0D>Yu#u#Xb zo~nRyF~k>gFAW_RX>(^&Co2aRD|bAo zQVh2o<9N(8gTq}~%*wQ|##|WktE%vam_Mp_d$1oGsN#8JF%P|+618VCL{~h);2oMV zJKmh)UeHdrqJG&J%*CrHm8|<*_h5eH(wyFqqHGLC1cRdeR}ffjvC9OMYS#73EO$p@lt@!NEFZb%n%+>rrH8ElWhIMsz~M)I;<6Q|b$X=f73MVu^Iz{jl27QxflWtPl9Nynev# zv2{d5yek?v?>2AX?bp*H%!5@Zh}U*1--&2D6pazBF%uV}KAY5_WE=M!noJ^@}7P;2JIE) z!5PpJ&Pk|kXR_x}HaUx{y|6Q$DdJNT%y!T1_N4C>e9`#4QY)quj*J0QMuT2kz_E)d zjqlfk;k3hG_y;v7z0i9~i{I7{&bEs$607}q0AJtjJSjFR21wWG@GZ`29MR;q-^5Wi|lqOzSRx4hu*>iI;VXUlY90pnNuk1 z`%Bj%84O$&n;P6jO?ss|jXbfdyjH8y*1g4=CJ$Xn379sO&+H^A75xc8Tzg(Tw73$etXv!v6E9&q_98VsLrNOJdYtq47atnAMsk0WPqrP5APevCSl@fYHDf; zXAsxc)`k+mQd7xGva==lUc6u_(T+ij|0zf+#bUnTbSdTb3}Q(&Ws60e8(AS#T9CO8MhJ-7A;V|j6S*0!JQ{~g4 ze&eeUBE9v=O2LXM+|k$@2~CA&OPhnDnvo4wn1jCC`-^?*U~zaUL2&@vsNLo|R_E$b z?Hi|*=rnu?>2rw>g^!C1d^9K&f387Roomcnx3z?;1}%eviriKt)iiaPIU3)67Gv)` z9mmE5mu0k^t|E;!cvfdIN6^TMYqSmEC$O~)i*vQx8(9xO+`k-X^X=k#WoN%j=W;fS ztA4tZGb<3(k3G035RJmq^2&YOc=k;gNE z@x4*Tom>40Cj`URU-mX5Jd~ZQ#n@xn2e-yLS9aSjeukbJJogCSt@kPiC#g)$j*mav z-P==_sCz}~n4LSN2qq~K(5{Foy&~#j9=0nm_aLGL_-PI|Tu|v#N-)QX_8T;yDWny2^~9o{4#?DU5~;$7 zFN_*@$+Culd#Im>>iChUaZinoH<2Sw%qBT!5LctjwAJW4zKBnf6wOJzxTaA4H0EM4T|bs?&Dwmb34 zM)#f;5xrvKr^%p?9U1WRObvLq8;rmJ1hX592x`6l?SInNe+g}fNT_Ozh;{#F zB>a!zbs(D$zdfz5_N^mt+=l)NUh)v#EUSBtFxN?6rGD&Xk`aBAWW4+kT+FiR)S@HP z-Q7L8ABd0?f=00jA0>C}^gJ6)@U<}CW#e(x(lr_}c`8dOjJ-T)d$78mEtVK&LNuzT z-HvAZniAqdvoh0U`-$|0%h&g6e0k+<*bEVZE~TKDD{T0=tI2EETAfNK^JgNRUqT7X zo|I^XMuLq>mG8od90^yAAEjfA7DkPVRh_X zt{UH|DJ&~f(qJqsDyk$WCzm!g&8_l6wc=8U4B-CqdUAIM>p&VhDx5Qz@P^kp|H>Y{ zz*||`0e;IUA29ahQ)x3aZW7Z4#Yl#X%irUIUpT6)gz$85py%V9Z{B|n8G}#n11hQ< z;c~gyRF2;oaS|SJQVDWhbW1pGe16kxLUQ+|*Pp58TbZe&p*eLH-FZN9oZHy+thyC! zP+MHhW~Kq&TI*wQ1aE;M%S$q52^T)SC^|G&i$-1mWQROuYvvndLC*PBXcx*tcq&fA4hXjsnve%aa9#Ct{-u8X*U>D z0mBeS_!i^grC%rR$0ECqhTIY#mwwtbhpK6OwyV2j9>XrrNSB3l{1Gd=x&rzt^J`II zkG&}BX?4b7=h$WT;-y_{;edexYg;QT{PXkkBAPk+h=x(_LPhZVdk(vv`v;YEM*o9e z(*3LxY>Pyc&?a? z<(^^Fl;3^;0lfjYOW-SE%YXn}fJrg#$nSq(0RQp7|F;OkzZxDQa^%zFwZ144d1Gy% zR$3kE2&^Ee#%j}%&l34-HTu70@B@AF-qo!KvAinmiUTV>O2}0Q0A&{yNrSVYC1&Jl z5GfV?BPn+PKTT{s;8NVHA5Vp6MT$4#uh<@PMf;egQla_>(6)AqFJ9>co|M$CMrf{(nb9(egSgjH%9s05j#u@-Y@vvw5!XQfH6dP%!?5dk z>;%6Q+Tion`?!@yMu5PW&~fk6c{m5g?!$-`Fhd^2`pTi>np?=Q4l4`GR4#pD-bUq> z+2C(aml!KP@9lL_5={@ado800G7a%J)~{ZL7gkhovd|2>sj+ii3#Y@Nw^rbc^Kgo$ zS;h$8{MCm7t56$V@#x0`ez$msaHNe1?!w#lc+l4p2h|K5<@S0kv8OhDLo!5r!M%KZ z&8FNqecg97Hu9J*HMZ zqi!8jlLM!;u-ysEAyJ|IgJ9o;%c+%AhjIfegzwOb38|j#)kfIZs*D^A-rW_W5pHuq zufumspGp;AsH24RTpZU4b8p=+GbfsRSgA~y069{mtGV&4yywFF&d)0~&7FKBHGJ8{ z9tyqPvwct?tJQDUykg4>3E-#s)`aX3jVbpTZe7zX()UG-R)a|MJlHRRO~1g-Bd-d7rjk-2NFZ~QQ{et zYqU!B=rG3v?p&8`a0W zO+9jq!n@miq!n~HJox0El_}dHQlCJIF!B4N0_BXR{r&0@V!x|yYH5~4f^cH?mwzR{ zC^PbNbnun`)q1>2&nwPWKHHt~JU{HJ2ovl+vVg;s$NKvEScD;TMG3Bh3%D~1K(?!N z5_9vrO-08pA*(3`dBjO!5&LD%t~M1jN#!TUCX@@hkao}~8C10w7w>+Ple4}#7rpbt z^=WL~2inHG9Ki z$@ioPx#DIu!Z&`lT)g_$^CO`vR8}Pt3dZE{U$- zLz8=N^Q~KJRoPDb5}KMU9$Nf5DOV72lPlYB2{g#)9HUzG8V3g_r>d%I+gd&hv(WIT zmMvHD+UQ##tzGDMPak0v8(dRiZhElY$JO21C~X?CWYAo_{gQ^TgK;S;Q@p0WR4{g< z!*Yjz+UtS~f)XQ->u=z?3$N;3)ywaRes7G<$RVm|gj=LB0F|vSXH#NSjU1b{fn%@7 z!$OusfMKrbL03=?3!QS30qil(ewAI+9(2Yx&whA^sR&R5GtKdn!9=)wfgHu!c& zFkW2P!aR)E4rzv|zH~}6qap4BsL_A!0+D562m8*`U*Fcz5Y%MGawCsTPBQRFJ`WZ@ zPuQ+}-~R3M#_9I5gR2pDd+85f<#OK8#hjb6%sJ?6dGVKpw#m<*iPemZV2_HG1UYtG zW?u_+xzvH{E9S*n$|drk#gbDNWG;3onomCU_!3MTM*K?VF5x51aCoN>Qz(L(m3!p_vVvQ z(iMiSJ=PVi?^Mk3$ovT}m;Bl*lAVItj7mu4J*q=Fcuo5vYKrk0l2rP-&oS1>S0Ur| zRcK1jaG*Wy=2INmJf@SjTusY1DJY97w?pYd6FK-DpV{?$ri}d9XXoa6aRlaRE)Ex1 z-45rOpL(vxe%wkIaWCh8_aiw9R&P7^j(U#=E3KmCci6>?5yqy7T@;#q>yU1F$ka#s zxVmo)!+=X@`!3JwOW8nov&~!!b7C2i59hzMtCfX!zE}?q4jv6DTC^H% zQ@SsD79{El;N9Px6OM@AmTu2f7YLs85X#8N1T`GB-HvW%VZGhI2(`DqCkf>Np5{y4 zbu-dkv_2&9FPCWKCu-r^5bS~Bn{*;>`wfFb-ruEDQ&SIzNc&I8)^tW&y)Sjqai1C- zm)ZMRYi&;9*eRkUBlj$U5s{Z_wIUbWAp(JTu;}lz_C?R@awmy5XE1eGMgn)xiyCYP zg3GeZw;wA4+%S8n0bW|<=@@S4mryY1pVXLtMXvsZc=PWMKiNJI&~?ANu*!WH*CpDs zF`d248JMgBEPXx(Q6$CVf)YN>T?iomc3!DpruC2?}ThS?%YpQj*(usOVj> z28`n<(bcCtMyMw3r&``cZ@PrT+m&E;I4Us4!aK=O`6PUZ&T4KPE3Yde&7HAq3eQPC z^}K3b%#xoqs3{kMXW^h(Bc1G9yWD+wK(1`h(@ZdYlc#xC^nugdog4bKR}R%MP}GJt zKNg+J>Wns8$3;bfUgm>KSbG>xoEZ{ZRO9aJ?Muf(igRSy4a*74NI}EB{2ZVZ2 zS`NIwsKNY*^35|cJ$C%a>J8#=@8_)-Xk3}ogkR(4beqiD(-(}}d+4l!^QEo0e)9E# zTw+q#rHa^W9&QX1uHUj6z4-*+NK^jj$FT*l4QqtTGK>$Yi_j%zD9GaJO_d#Gh_4X0 zTN*SYT(y}R9Pw=QMIh9+M{=a{?GB&GFC=nzm)htQ8 z4wvM^vk3uZwNXZ4Y?|+u-L+qPj{z27N92H~3$}?h{Is0sW9%Ke-xF$AuB1GF z7XJVwGyJq>qYg>l2C$XHToJzdED9q_G_W=butD=2woij>&Ub6nYQN?kH3^!*F{0#@ zvJ-f(Qb7m!ict_dz9ePHVqS|h6LZ4gx}<(HHGD~z1eTUCl2=L*r~i3vq3Q7^P*Y7y z+-xjqC<`J)v5>ihtM(ld@Eqfw|r&Jo-_N)M8>~n zJj$)FDqU32GKjvs8+mxUeL5ns=8CUnuG<)c(=mhrv9MU9VElp2$E1Ok^715UFKYlL zUH$2`v@&tFI^Vt`mPvTIXqmz}c^o&;7m5E3N%5dFf4M~^fue>l4)gb-qItgTqhWB# z58;3#fkl$Hnx8j<3rQj66!L>O)aowg11|?1g|^r%dVVt2QTzFZoRM3APk2!2j$}`p zA8*(&7J#PDbKs(xBHCin{#71;gx*Vdfc@t z{{u|&iaY#k@!(4&#}vXzZhF&?ohZ6;*UqF(?nygQn%uI4L^ddPhyKzLKp5hn-w=-m zaGa>zJoSmM_fM7G$Ds+4(V^a`HG4RSN(GJ9(yvrg_(Bm;CF74qN;-3O!XqHVeLG?> zr-gqyVs`~v#f5@RtbydP@3Rb*5BtGJabJHCLb*cnK#;rBy2x0Dthg^9m>vO)mApWR zU*`oa@;2;R`w@aQtkadF;eD5x#;Cs)Jd)-<>gS}OBex6so$pB)VNGHDlui7H zx3xAyd3$x%xFdWxGN-Xtsm9JI{JOoVN%SvZ z#_&>;o4+(sj%LJ0wv(S%zB0)GRAt5$mq{iVbocZwLVxW|v6e(X3K+xxR5}NV=OgGC zCIwogR^tPAXb>#13j3Giw`(Ejb45?co&RIv7NNPe&{Xh(X$9el9-$iV9>1ez<3=-l ztnu;w{YwXMK5TGUaOh#7v{HrTU`l}tR4irCYa~ZWa4W$T(thifV+!+SoB>x)n^AzO zNXM*o12G81eHR;5hjSHf7G#pd?ZHV(ct%z)snWncw|ch*(s*>Lhv*-04CFYs{G4P4 z^r{cTT5L_~yH6fu%?-uPJ=MBk2RB7Fb}CV1wF0fddwr_<=xS~6L6IU&vvQh3<=9YR zo%#HLuaD?PZn^ zefu1*w!->xm6C@$HiDjKh2@B&Lq3vhzNluhJI5|o`ij_IR%#9ygSZY;I@Y8&t;(;4 z5rFXf`w)=k1YH0?57wO$LL>T*a;uBO#*-=Cinh=D?Oyp!Q4;C!zEu4(i}$dOGg{Th z*no@i$K%3sQ@pKDAm9yxdZ2SbEz@Dcm5vMV#=hPwB?GF6nypKW%ZdUnnKcfzCbI?^ zM0Lx(uQRYn2=6f$Fe*V1Bv&5r2wBzjVT{Dkic0hCskqu_MRQTx<_YHL~N z*pe;E5qPsknMc|MjM5S^i?WT1igll_+~BZL7`G4Gw|*1{S1{u7p~@WV0K)Pp)zrfTPqhd zP|9zp(D%etNF)=pt2>vJz~UJOGRDoF6Xm+jaU&D)l_=!wmaIQYHeg0}s!8r=ka#i% zvZ~_u7;Y^czn8;GGl-Si-d*P>?8y+B0unH=HYKUhQ^&9Xt78j^WX=M^xysLdC{*1B zmj!9J#AsPDT)nVCPSzcB@S%uhgO5uT+WaFG$|;b?E9<%&JYO8>r?czX!IA43#jBPC z{x$*I2>#~0q^lP5`m3vnVEKBmMN3bIM8RCYiL8#}-FpI|y(7!;HM;jrpF(I3>9%}W z)54ON8A+j%^3WamXX&q?uAgBgHUeFQ{jN~wVR`+6qze+2&vl{UpUZZpOJE22CrI@{ zVW%Pm_!oCaJCo}c?O~;$Z#g6ROlty;A-`KZ#nWNvu~UfIdyJGJ>up`_@dfFRvVQ@O zhU7?Ye9{Zaz%zO$J0Mz%<)&R(b6nx;5D%}x%Ke(%t})cXsI=pTjks9CvJHXs=gPM` zfnUFZP<(u^k>8p1m~m)CyH8d`Xi%op(azkNwWLBQd*PV_rr#&WrHVLC@1<39 zEefs(`NqvG2duv1Xy>iBB~;wkl6A=BGU^?bvCsQ2v~d*Qnano-c@qP|vqKSN z(zz?To1IE3Xi=2vmGNlla>cxfADVw50W)g*E<~)BhBlz3Jp*hMaf4xzSU}(z|=Ur`|LPTK|p7qHpIdFolP{a^f5?uuAz;FWC8par^Z2 z=cC@-n`4QSmlfMR{=F%^_9t?ZqF+6g`nPB;htnp3kLm61$-oJh zjk5Wm8&euI$f^_>qj_dDyMCpwMrSTC{Gf0b z8rJryDLot|I-jrQ#p^%y7V$F0;~M$F9nHF#D=Krrxu9L`(rqtxSkw&9Jxy#-zh|!8 zFBGRY`l$mDsFV@i6!AGohc8)Y@SGT<{fK1rYY5jf1 zW<@~Tu_OcDMccK(RD!Lv$t=I>#dmdy8mSPs))0)&spq)g*IXW$I@K9+_1rOaw>MB# zu3ZD~vIQj#)6bf68Rrhkz`1NZ#jfF=sBm>A;dfB^`Zs~<3vm#z@GoHiAZ zOtMXTrf#{Lmwd@H9JG@)*UjA4ghR6}^Ntj7z)9;kCAq{`OGj$DSU{Fc6f6<Lb#8#QNzJU*NiUZpT7I~a}+vv0Z?mWfD4##@XglOF^V1z-;hYcLIyIkdc{0H z$!nO$kG;%EPSat}|_%T>4j;OXEF5GR$H?`Hp%lM%zj#@sx zKo<%c@Btx_(L5l;D*K#coXFw|+JPlWOh{!1@Gq{|i2nc9>GWTR&jAlrjh$}(ysQ&_ zAGSivg}s^kdjykvqJ|==W+s;hiof-cUi$G3VA4IV1C^HPze`L^!s1BxJv8!F{vvEu zIXYC|ykpAkHBdt&;Nq+vfA6d@z)ky@q4T54$yz_o-Xif*+s3CN$)lCaod)H3_!tu- zqOPw9QhV!S@cOdKW8M9fkX6wA!7Pg3bl}&;T2=tHv`~Ie=W|1kT_X``G1%2$g-UeO zPhYmQPcLaZ?x`c4T>7&S?B@+1I6s{6Qf=Wxqgw#Ck%ym!&}9uxSD9eVn4royKDoVh z<;{psXNeUG=n!t1kjwj+3XSXS4|A>i)cV&NSD)tGLz?YwLtlUTi6gYv4gW3TxERyv zrrOY^#>%+k$b^EEW_2~#-!K_~n%)Du>Ew^EsPgl5yk;%m>ydQW2?@6)R23rl$9}p2 z4rL?b*16+0pH9Zh9aC_BA|CfAiukMF9UuvuALo&JLJHvl`m|e9V>r@OnbD3VoZ%Pa zn&&1u*SZ(ZY&V8CA8klolzBjszbt`2$BiKF9CMIsBo-DHw%rcLBNWPnG9^D^{W=>p z0*@yf&zT=zS9y76D?Sw_bS$o5y9=C0zdJ*{7PCS7S)Z@1qB{Gc0iLTCRW7*B2Y69l zDlcP)Rr{)OFfuzX%diWTjF_XGQHD~Pw@ToQF~4A$jX;HsC~@b|^@Fw9?k|va@wPoR zWudoV@{R2qvwmF^_0PzcmDv;ps*Q$w z%oaB+bNt#Of;jzF^7&`YUyokB*(eM{7RSVPievX4rau$CWbRH870b8DtoE+oL+VWh zlKRz|5SK}r@y6#i=?!HQ43aN9>(w2=Q) zaa@0}}Zi1u$00k2p0{RC+Zm;Eh1(s@|-u#iqUQz?88gJOO zN)1xvb5r;nb81a~vCy)y&Yr*Wpo9cA>HWlB=1ij~MT81waoOEf(GDc#Rh2FkKlxPO zzazsh;$|G5WR4-r^tr00rg`3km72bO8q-P9e`C2ZQxvU{rc?jpMJT_Cazb`sUB7Fp zbsa1nQ_pv$l=)#iX4q70h|LNf^o^2%ub!b!Hsc&M7svk{DE*c+R;#&EcbW+x!Vn9i z+_mW@VMJ9)5n-e08~SCTcYxeCvoSJ*C}<(m{5C&7qohhpOYMnkN)l-u8B9=^{??^p zGgC$1`|(KTitGL5YQPNfAL&A4;j7Bm;7VZ?>~+m#s`IPsqwcf1-`19;~eDr z-tV9IHGb%_of*J^@^}gl==yNbWo^mtGwo$?ZSs`(4(ZDX&|p?Ssx<4|a@N++m-^%I>M#XQgYjR8 zl%#E(?X(h9mU{H)KkM1VA|Fv<)are&1S?|8(|A{fhK5iJ=;isWc6&TI2wG&$^~I)O zga6guGiIF+3vWS-`5Tz2?Uu$igof95xXn+~7nWCm}q zu)jc^K^IW?$Iv&>!<(*2@O)RfGjHkd9HjSMcP|FJMZaAIKZWR!_TS7v{q~4;9wUEy zL86j#IA7akvip4L@N-u6jpWsgV>~X8*c-BT?eyU1aK$O5+{}lKt?3H>6=#(HWbF%T zWMzQ5Wt%3`z15r=wLHfe$j3E0n!U8#~-7{6WKr`HA+p@TX z^Dooy-6M105uqb5OGEvXWy(H~LT8NebwGHI5YfBiZen^QY0`WD z!4d5j*c~>;08mK(Bk2C4c{lI_4GpMSF^SdhUlomk{i?mM)hx{`h|Yo#9_~ literal 14090 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 R&3gzU-k43VK?kWew%*HYQCXA7yU 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�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 diff --git a/icons/obj/weapons/spear.dmi b/icons/obj/weapons/spear.dmi index e654cbde28df1dddfd453802ce4c238caaf18c87..6a2f95f78b5c36bf4f3251de3ce53eb522d78dc8 100644 GIT binary patch literal 5388 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 literal 5909 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 diff --git a/icons/turf/composite.dmi b/icons/turf/composite.dmi index a40c4121d252d2fd716ea0bc82c5eda01fe31e8b..51938161ed1bdcd7ccf006fa2f8a4a0cad25ea0f 100644 GIT binary patch delta 3863 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 Z{2y-|&d@wmq2&Mo002ovPDHLkV1nyJGL`@U delta 3328 zcmV+b4gd0(9)%huiBL{Q4GJ0x0000DNk~Le0001B0001B2nGNE0OFW;H~;_up^+sg ze;JZHD76}k5v0Ihf0K_R000ahNklEd_n0VCV!U z;JGV}JC%wCXT(RDX*MODStyk8c9HwteDA#T_x;ID+WUj>?mg!_f8O_<^Zh#~e@Or! zLd^DqLzZvM3nMjQ0Tl4Ok-9|S=!Z-eJ!m_7Wpf0%f*BL)DO`OShepWbys02&uu-5d>2EmT#VuAe{% z0bqS)CP}iUW4;gMflU*Mo{vrH`Z;=K^%MX+IM;VwwF`8sf8lcN6asXq>SQ4Vqo4js zH7}R%qH3r6uB!4lj>A9*VPt+3MFUBaJXTH41*DpEYU!&p$3Fua8FTc?f9k0R=lZVm zXD$R+)gyzCvoKRTz3b{H-}m`0tu9XL2Ur(Gx2m!h>^t*SQMv>1Sv%yryC>^{uLN(bp=N+VPdHYaa+9 zj9V)+o`(QDRjpv&Hj1Jje{ob75uf%+MZVbFMF1e= zQsI8Ssxj3A8}22ib)}(az60`ADl?zJgun#=Z0v$ML;crZ|D&$`{i~nk?Xz9rV}v__ z+zlm|^p?C!bhIkhP1oP;LpufFz7=jXbkP4vFB-I-B*BT16SnXm5jT{xmB+7IBn0REXI$qNVi zJRii&&mF>4L2&ih2O_@cfP`>ZQKw=;sff)X|!t${pF#6-TbDjuGSOx$tBhupu3a zTC?Xh?lMw?D2jTLBzXk@K@jZa?X$8_PR3<;1Hk7EYVP@1{y082eV(4@#xH#!cR&mt zo(ktxYG-&Vf1GzsSIBS)np|jn#>;nr?_f5=s>&?tydg5e<8#yJIn(8Ld36s@h4Y7J zS4RQh(L|p!qh%E&C*w>yoYUy|qH3$6A%18D0Mutld3iG{KsV{=`Pih)YyvNr1u)g~ z&7ARvXIDp6Lf|__H!qV4vZWbx0#d!}%DSOJt9c&Tf2-2XqLu4){RL^7YSYb1mBBn1ow0RsX(^?#@WXHX zCQY$p_+t2bUhksIO)5yGvgn!Tf?NWzb|o8Cs5=i(8C{MB4@UBMGOy^UE+NP0_LI9x zsR%9vf1kq_f=Xa26(nauRmnJltgm%+t+dJAP~M0bo2}B%fpsMj1VJk6xy)^Sl_be4 z-cJ@A{F?-%6K}KWR0GRpx`|Qw?L#{SQoIJxJ#;br(Dwk|f0te-fM(#Emf>xP-slCjQ}^k%<5y>n ze})uYLl?sj0e^-zb7R8S26Ph2gKI)N4UZ6_rVRBN^8r26nmLXfpPN3x+gl z5-!nslmaLi0e}%+aQa(4gV$cZx?9kEHXTK)r^0Q3jIC}HYL&`jSgpQQt5hb#YPDqp z-bIsYwWI$Rgw^U>*<)O*RGjlze>!vl#c#u{j#{O%n0-!WKZ^ham=NSoSClrubMX=L z!)kRVV|L6{68l_ayG4t_ZNN6r`T2?_ozHgwXR<61xn6~i=7P36h>6*&$jbQ2mW^=E z@Jv`%BVEP;4&bYpp2-$uKa*6)?8Tx>-=z&Os3%FKEHdUd=y$oyRRtApe*0SYi?##lF~^hx!q-H_8dxuGa+ zfb-&GX@~}UpsI60w>*L9owsrF1o=Ar>4sZZZ zHBebtts>(JW> z+uE>QVQll_h4qgte{M;%O9-+Gat2c^^2D_LsK(j9f4|SLTMF$ELN{x4Q)Z?#n3I5f zg}GgK0HIYOG}r(g^EhKoc0t!4r{!bp-tF)Q_kKDL% z<9{k8?kfcTA2gJzMy2m9ae*_05I3vUYN3HxC*UIl23;q+bLY;k zB7a=x=?k6F2jcoue9d|#API#H1%j>iY zww>S{3Hzubf9jLyRIV-29XodHwaXXj6nt|xt&Aa;3&H-AUPd^p^JHWp@poCx=pt$+ zh*awxJ$v@7P!%*iJ>9nB#b#iP z16+K49gQK1&RtLdIB?)VlT&XWTq4#^3Bj6*;1R8h$D@KtkVVGs(cit(J`2Y#}&bO(YssszMj2ZCB_R%!Sadv6QzW zB$eZJo7lx=