diff --git a/code/__DEFINES/mod.dm b/code/__DEFINES/mod.dm index dcfcf028d08..1a4bed1ca99 100644 --- a/code/__DEFINES/mod.dm +++ b/code/__DEFINES/mod.dm @@ -57,9 +57,5 @@ /// Global list of all /datum/mod_theme GLOBAL_LIST_INIT(mod_themes, setup_mod_themes()) -/// Global cache of mod skins to masks per different configuration of pulled out parts. -GLOBAL_LIST_EMPTY(mod_masks) -/// Global cache of mod skins to deployed parts to module icon states -GLOBAL_LIST_EMPTY(mod_module_overlays) /// Global list of all ids associated to a /datum/mod_link instance GLOBAL_LIST_EMPTY(mod_link_ids) diff --git a/code/game/objects/structures/mannequin.dm b/code/game/objects/structures/mannequin.dm index e4cbfc7d629..2260751bbf7 100644 --- a/code/game/objects/structures/mannequin.dm +++ b/code/game/objects/structures/mannequin.dm @@ -114,49 +114,12 @@ var/obj/item/worn_item = worn_items[slot_flag] if(!worn_item) continue - var/default_layer = 0 - var/default_icon = null + var/default_icon = get_default_icon_by_slot(text2num(slot_flag)) + var/default_layer = get_default_layer_by_slot(text2num(slot_flag)) var/female_icon = NO_FEMALE_UNIFORM - switch(text2num(slot_flag)) //this kinda sucks because build worn icon kinda sucks - if(ITEM_SLOT_HEAD) - default_layer = HEAD_LAYER - default_icon = 'icons/mob/clothing/head/default.dmi' - if(ITEM_SLOT_EYES) - default_layer = GLASSES_LAYER - default_icon = 'icons/mob/clothing/eyes.dmi' - if(ITEM_SLOT_EARS) - default_layer = EARS_LAYER - default_icon = 'icons/mob/clothing/ears.dmi' - if(ITEM_SLOT_MASK) - default_layer = FACEMASK_LAYER - default_icon = 'icons/mob/clothing/mask.dmi' - if(ITEM_SLOT_NECK) - default_layer = NECK_LAYER - default_icon = 'icons/mob/clothing/neck.dmi' - if(ITEM_SLOT_BACK) - default_layer = BACK_LAYER - default_icon = 'icons/mob/clothing/back.dmi' - if(ITEM_SLOT_BELT) - default_layer = BELT_LAYER - default_icon = 'icons/mob/clothing/belt.dmi' - if(ITEM_SLOT_ID) - default_layer = ID_LAYER - default_icon = 'icons/mob/clothing/id.dmi' - if(ITEM_SLOT_ICLOTHING) - default_layer = UNIFORM_LAYER - default_icon = DEFAULT_UNIFORM_FILE - if(body_type == FEMALE && istype(worn_item, /obj/item/clothing/under)) - var/obj/item/clothing/under/worn_jumpsuit = worn_item - female_icon = worn_jumpsuit.female_sprite_flags - if(ITEM_SLOT_OCLOTHING) - default_layer = SUIT_LAYER - default_icon = DEFAULT_SUIT_FILE - if(ITEM_SLOT_GLOVES) - default_layer = GLOVES_LAYER - default_icon = 'icons/mob/clothing/hands.dmi' - if(ITEM_SLOT_FEET) - default_layer = SHOES_LAYER - default_icon = DEFAULT_SHOES_FILE + if(body_type == FEMALE && istype(worn_item, /obj/item/clothing/under)) + var/obj/item/clothing/under/worn_jumpsuit = worn_item + female_icon = worn_jumpsuit.female_sprite_flags . += worn_item.build_worn_icon(default_layer, default_icon, female_uniform = female_icon) /obj/structure/mannequin/attack_hand_secondary(mob/user, list/modifiers) diff --git a/code/modules/antagonists/clown_ops/clownop.dm b/code/modules/antagonists/clown_ops/clownop.dm index 2fd2daa7489..9e2b79102b1 100644 --- a/code/modules/antagonists/clown_ops/clownop.dm +++ b/code/modules/antagonists/clown_ops/clownop.dm @@ -78,8 +78,7 @@ /datum/outfit/clown_operative/post_equip(mob/living/carbon/human/H, visuals_only) var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.active = TRUE - H.update_worn_back() + booster.activate() /datum/outfit/clown_operative_elite name = "Clown Operative (Elite, Preview only)" @@ -89,5 +88,4 @@ /datum/outfit/clown_operative_elite/post_equip(mob/living/carbon/human/H, visuals_only) var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.active = TRUE - H.update_worn_back() + booster.activate() diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index 32fe7dfd5c0..9ecfbb9f991 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -188,8 +188,7 @@ /datum/outfit/nuclear_operative/post_equip(mob/living/carbon/human/H, visuals_only) var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.active = TRUE - H.update_worn_back() + booster.activate() /datum/outfit/nuclear_operative_elite name = "Nuclear Operative (Elite, Preview only)" @@ -201,8 +200,7 @@ /datum/outfit/nuclear_operative_elite/post_equip(mob/living/carbon/human/H, visuals_only) var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.active = TRUE - H.update_worn_back() + booster.activate() var/obj/item/shield/energy/shield = locate() in H.held_items shield.icon_state = "[shield.base_icon_state]1" H.update_held_items() diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 6a216fda617..abc96cb33d3 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -638,3 +638,57 @@ GLOBAL_LIST_EMPTY(masked_leg_icons_cache) new_leg_appearance_lower.layer = -BODYPARTS_LOW_LAYER . += new_leg_appearance_lower return . + +/proc/get_default_icon_by_slot(slot_flag) + switch(slot_flag) + if(ITEM_SLOT_HEAD) + return 'icons/mob/clothing/head/default.dmi' + if(ITEM_SLOT_EYES) + return 'icons/mob/clothing/eyes.dmi' + if(ITEM_SLOT_EARS) + return 'icons/mob/clothing/ears.dmi' + if(ITEM_SLOT_MASK) + return 'icons/mob/clothing/mask.dmi' + if(ITEM_SLOT_NECK) + return 'icons/mob/clothing/neck.dmi' + if(ITEM_SLOT_BACK) + return 'icons/mob/clothing/back.dmi' + if(ITEM_SLOT_BELT) + return 'icons/mob/clothing/belt.dmi' + if(ITEM_SLOT_ID) + return 'icons/mob/clothing/id.dmi' + if(ITEM_SLOT_ICLOTHING) + return DEFAULT_UNIFORM_FILE + if(ITEM_SLOT_OCLOTHING) + return DEFAULT_SUIT_FILE + if(ITEM_SLOT_GLOVES) + return 'icons/mob/clothing/hands.dmi' + if(ITEM_SLOT_FEET) + return DEFAULT_SHOES_FILE + +/proc/get_default_layer_by_slot(slot_flag) + switch(text2num(slot_flag)) + if(ITEM_SLOT_HEAD) + return HEAD_LAYER + if(ITEM_SLOT_EYES) + return GLASSES_LAYER + if(ITEM_SLOT_EARS) + return EARS_LAYER + if(ITEM_SLOT_MASK) + return FACEMASK_LAYER + if(ITEM_SLOT_NECK) + return NECK_LAYER + if(ITEM_SLOT_BACK) + return BACK_LAYER + if(ITEM_SLOT_BELT) + return BELT_LAYER + if(ITEM_SLOT_ID) + return ID_LAYER + if(ITEM_SLOT_ICLOTHING) + return UNIFORM_LAYER + if(ITEM_SLOT_OCLOTHING) + return SUIT_LAYER + if(ITEM_SLOT_GLOVES) + return GLOVES_LAYER + if(ITEM_SLOT_FEET) + return SHOES_LAYER diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm index a31d7b43742..12de6ac26d7 100644 --- a/code/modules/mod/mod_activation.dm +++ b/code/modules/mod/mod_activation.dm @@ -93,7 +93,7 @@ RegisterSignal(part, COMSIG_ATOM_EXITED, PROC_REF(on_overslot_exit)) if(wearer.equip_to_slot_if_possible(part, part.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) ADD_TRAIT(part, TRAIT_NODROP, MOD_TRAIT) - wearer.update_clothing(slot_flags) + wearer.update_clothing(slot_flags|part.slot_flags) SEND_SIGNAL(src, COMSIG_MOD_PART_DEPLOYED, user, part_datum) if(user) wearer.visible_message(span_notice("[wearer]'s [part.name] deploy[part.p_s()] with a mechanical hiss."), @@ -131,7 +131,9 @@ return FALSE if(SEND_SIGNAL(src, COMSIG_MOD_PART_RETRACTING, user, part_datum) & MOD_CANCEL_RETRACTION) return FALSE + var/unsealing = FALSE if(active && part_datum.sealed) + unsealing = TRUE if(instant) seal_part(part, is_sealed = FALSE) else if(!delayed_seal_part(part)) @@ -144,13 +146,14 @@ var/obj/item/overslot = part_datum.overslotting if(!QDELING(wearer) && !wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) wearer.dropItemToGround(overslot, force = TRUE, silent = TRUE) - wearer.update_clothing(slot_flags) + wearer.update_clothing(slot_flags|part.slot_flags) if(!user) return TRUE wearer.visible_message(span_notice("[wearer]'s [part.name] retract[part.p_s()] back into [src] with a mechanical hiss."), span_notice("[part] retract[part.p_s()] back into [src] with a mechanical hiss."), span_hear("You hear a mechanical hiss.")) - playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + if (!unsealing) + playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) return TRUE /// Starts the activation sequence, where parts of the suit activate one by one until the whole suit is on. @@ -268,7 +271,6 @@ part.heat_protection = NONE part.cold_protection = NONE part.alternate_worn_layer = part_datum.unsealed_layer - generate_suit_mask() update_speed() wearer.update_clothing(part.slot_flags | slot_flags) wearer.update_obscured_slots(part.visor_flags_inv) @@ -281,7 +283,7 @@ for(var/obj/item/mod/module/module as anything in modules) if(module.part_activated || !module.has_required_parts(mod_parts, need_active = TRUE)) continue - module.on_part_activation() + module.on_part_activation() module.part_activated = TRUE else for(var/obj/item/mod/module/module as anything in modules) @@ -300,23 +302,16 @@ active = is_on if(active) for(var/obj/item/mod/module/module as anything in modules) - if(module.part_activated || !module.has_required_parts(mod_parts, need_active = TRUE)) - continue - module.on_part_activation() - module.part_activated = TRUE + if(!module.part_activated && module.has_required_parts(mod_parts, need_active = TRUE)) + module.on_part_activation() else for(var/obj/item/mod/module/module as anything in modules) if(!module.part_activated) continue module.on_part_deactivation() - module.part_activated = FALSE - if(!module.active || (module.allow_flags & MODULE_ALLOW_INACTIVE)) - continue - module.deactivate(display_message = FALSE) update_charge_alert() update_appearance(UPDATE_ICON_STATE) - generate_suit_mask() - wearer.update_clothing(slot_flags) + wearer.update_clothing() /// Quickly deploys all the suit parts and if successful, seals them and turns on the suit. Intended mostly for outfits. /obj/item/mod/control/proc/quick_activation() diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index f64539bbbd5..bf6966499fa 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -114,13 +114,10 @@ if(core) QDEL_NULL(core) QDEL_NULL(mod_link) - for(var/datum/mod_part/part_datum as anything in get_part_datums(all = TRUE)) - var/obj/item/part_item = part_datum.part_item - part_datum.part_item = null - part_datum.overslotting = null - mod_parts -= part_datum - if(!QDELING(part_item)) - qdel(part_item) + for(var/part_key in mod_parts) + var/datum/mod_part/part_datum = mod_parts[part_key] + mod_parts -= part_key + qdel(part_datum) return ..() /obj/item/mod/control/atom_destruction(damage_flag) @@ -443,11 +440,14 @@ CRASH("get_part_datum called with incorrect item [part] passed.") /obj/item/mod/control/proc/get_part_from_slot(slot) - var/datum/mod_part/part = mod_parts["[slot]"] - return part?.part_item + RETURN_TYPE(/obj/item) + return get_part_datum_from_slot(slot)?.part_item /obj/item/mod/control/proc/get_part_datum_from_slot(slot) - return mod_parts["[slot]"] + RETURN_TYPE(/datum/mod_part) + for (var/part_key in mod_parts) + if (text2num(part_key) & slot) + return mod_parts[part_key] /obj/item/mod/control/proc/set_wearer(mob/living/carbon/human/user) if(wearer == user) @@ -481,21 +481,6 @@ covered_slots |= part.slot_flags return covered_slots -/obj/item/mod/control/proc/generate_suit_mask() - var/list/parts = get_parts(all = TRUE) - var/covered_slots = get_sealed_slots(parts) - if(GLOB.mod_masks[skin]) - if(GLOB.mod_masks[skin]["[covered_slots]"]) - return GLOB.mod_masks[skin]["[covered_slots]"] - else - GLOB.mod_masks[skin] = list() - var/icon/slot_mask = icon('icons/blanks/32x32.dmi', "nothing") - for(var/obj/item/part as anything in parts) - slot_mask.Blend(icon(part.worn_icon, part.icon_state), ICON_OVERLAY) - slot_mask.Blend("#fff", ICON_ADD) - GLOB.mod_masks[skin]["[covered_slots]"] = slot_mask - return GLOB.mod_masks[skin]["[covered_slots]"] - /obj/item/mod/control/proc/clean_up() if(QDELING(src)) unset_wearer() @@ -602,7 +587,6 @@ modules += new_module complexity += new_module.complexity new_module.mod = src - new_module.RegisterSignal(src, COMSIG_ITEM_GET_WORN_OVERLAYS, TYPE_PROC_REF(/obj/item/mod/module, add_module_overlay)) new_module.on_install() if(wearer) new_module.on_equip() @@ -622,7 +606,6 @@ old_module.on_part_deactivation(deleting = deleting) if(old_module.active) old_module.deactivate(display_message = !deleting, deleting = deleting) - old_module.UnregisterSignal(src, COMSIG_ITEM_GET_WORN_OVERLAYS) old_module.on_uninstall(deleting = deleting) QDEL_LIST_ASSOC_VAL(old_module.pinned_to) old_module.mod = null diff --git a/code/modules/mod/mod_part.dm b/code/modules/mod/mod_part.dm index 88f8024628d..a184df7f7a0 100644 --- a/code/modules/mod/mod_part.dm +++ b/code/modules/mod/mod_part.dm @@ -18,5 +18,29 @@ var/obj/item/overslotting = null /datum/mod_part/Destroy() + // To avoid qdel loops in MOD control units, since they're also a part + if (!QDELING(part_item)) + qdel(part_item) part_item = null + overslotting = null return ..() + +/datum/mod_part/proc/set_item(obj/item/new_part) + part_item = new_part + RegisterSignal(part_item, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS, PROC_REF(get_separate_worn_overlays)) + +// If we're overslotting an item, add its visual as an underlay +/datum/mod_part/proc/get_separate_worn_overlays(obj/item/source, list/overlays, mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file) + SIGNAL_HANDLER + + if (!overslotting || sealed) + return + + var/checked_slot = source.slot_flags + if (ismob(source.loc)) + var/mob/as_mob = source.loc + checked_slot = as_mob.get_slot_by_item(source) + var/mutable_appearance/worn_overlay = overslotting.build_worn_icon(default_layer = -draw_target.layer + 0.1, default_icon_file = get_default_icon_by_slot(checked_slot)) + for (var/mutable_appearance/overlay in worn_overlay.overlays) + overlay.layer = draw_target.layer + 0.1 + overlays += worn_overlay diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 7ac3aeda0cc..1f9de066352 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -106,7 +106,7 @@ mod.ui_theme = ui_theme mod.charge_drain = charge_drain var/datum/mod_part/control_part_datum = new() - control_part_datum.part_item = mod + control_part_datum.set_item(mod) mod.mod_parts["[mod.slot_flags]"] = control_part_datum for(var/path in variants[default_skin]) if(!ispath(path)) @@ -116,7 +116,7 @@ var/obj/item/clothing/chestplate = mod_part chestplate.allowed |= allowed_suit_storage var/datum/mod_part/part_datum = new() - part_datum.part_item = mod_part + part_datum.set_item(mod_part) mod.mod_parts["[mod_part.slot_flags]"] = part_datum parts += mod_part diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm index 2fec22edbc6..fe3f02fc99b 100644 --- a/code/modules/mod/modules/_module.dm +++ b/code/modules/mod/modules/_module.dm @@ -172,9 +172,9 @@ update_signal(used_button) balloon_alert(mod.wearer, "[src] activated, [used_button]-click to use") active = TRUE - mod.wearer.update_clothing(mod.slot_flags) SEND_SIGNAL(src, COMSIG_MODULE_ACTIVATED) on_activation() + update_clothing_slots() return TRUE /// Called when the module is deactivated @@ -191,11 +191,22 @@ else UnregisterSignal(mod.wearer, used_signal) used_signal = null - mod.wearer.update_clothing(mod.slot_flags) SEND_SIGNAL(src, COMSIG_MODULE_DEACTIVATED, mod.wearer) on_deactivation(display_message = TRUE, deleting = FALSE) + update_clothing_slots() return TRUE +/// Call to update all slots visually affected by this module +/obj/item/mod/module/proc/update_clothing_slots() + var/updated_slots = mod.slot_flags + if (mask_worn_overlay) + for (var/obj/item/part as anything in mod.get_parts()) + updated_slots |= part.slot_flags + else if (length(required_slots)) + for (var/slot in required_slots) + updated_slots |= slot + mod.wearer.update_clothing(updated_slots) + /// Called when the module is used /obj/item/mod/module/proc/used() if(!COOLDOWN_FINISHED(src, cooldown_timer)) @@ -212,7 +223,7 @@ return FALSE start_cooldown() addtimer(CALLBACK(mod.wearer, TYPE_PROC_REF(/mob, update_clothing), mod.slot_flags), cooldown_time+1) //need to run it a bit after the cooldown starts to avoid conflicts - mod.wearer.update_clothing(mod.slot_flags) + update_clothing_slots() SEND_SIGNAL(src, COMSIG_MODULE_USED) on_use() return TRUE @@ -263,11 +274,38 @@ /// Called from MODsuit's install() proc, so when the module is installed /obj/item/mod/module/proc/on_install() - return + SHOULD_CALL_PARENT(TRUE) + + if (mask_worn_overlay) + for (var/obj/item/part as anything in mod.get_parts(all = TRUE)) + RegisterSignal(part, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS, PROC_REF(add_module_overlay)) + return + + if (!length(required_slots)) + RegisterSignal(mod, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS, PROC_REF(add_module_overlay)) + return + + var/obj/item/part = mod.get_part_from_slot(required_slots[1]) + RegisterSignal(part, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS, PROC_REF(add_module_overlay)) /// Called from MODsuit's uninstall() proc, so when the module is uninstalled /obj/item/mod/module/proc/on_uninstall(deleting = FALSE) - return + SHOULD_CALL_PARENT(TRUE) + + if (deleting) + return + + if (mask_worn_overlay) + for (var/obj/item/part as anything in mod.get_parts(all = TRUE)) + UnregisterSignal(part, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS) + return + + if (!length(required_slots)) + UnregisterSignal(mod, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS) + return + + var/obj/item/part = mod.get_part_from_slot(required_slots[1]) + UnregisterSignal(part, COMSIG_ITEM_GET_SEPARATE_WORN_OVERLAYS) /// Called when the MODsuit is activated /obj/item/mod/module/proc/on_part_activation() @@ -335,26 +373,44 @@ qdel(src) /// Adds the worn overlays to the suit. -/obj/item/mod/module/proc/add_module_overlay(obj/item/source, list/overlays, mutable_appearance/standing, isinhands, icon_file) +/obj/item/mod/module/proc/add_module_overlay(obj/item/source, list/overlays, mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file) SIGNAL_HANDLER - overlays += generate_worn_overlay(standing) + if (isinhands) + return + + var/list/added_overlays = generate_worn_overlay(source, standing) + if (!added_overlays) + return + + if (!mask_worn_overlay) + overlays += added_overlays + return + + for (var/mutable_appearance/overlay as anything in added_overlays) + overlay.add_filter("mod_mask_overlay", 1, alpha_mask_filter(icon = icon(draw_target.icon, draw_target.icon_state))) + overlays += overlay /// Generates an icon to be used for the suit's worn overlays -/obj/item/mod/module/proc/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/proc/generate_worn_overlay(obj/item/source, mutable_appearance/standing) + if(!mask_worn_overlay) + if(!has_required_parts(mod.mod_parts, need_active = TRUE)) + return + else + var/datum/mod_part/part_datum = mod.get_part_datum(source) + if (!part_datum?.sealed) + return + . = list() - if(!mod.active || !has_required_parts(mod.mod_parts, need_active = TRUE)) - return var/used_overlay = get_current_overlay_state() if (!used_overlay) return - var/mutable_appearance/module_icon - if(mask_worn_overlay) - module_icon = mutable_appearance(get_module_icon_cache(used_overlay), layer = standing.layer + 0.1) - else - module_icon = mutable_appearance(overlay_icon_file, used_overlay, layer = standing.layer + 0.1) - if(!use_mod_colors) - module_icon.appearance_flags |= RESET_COLOR + + var/mutable_appearance/module_icon = mutable_appearance(overlay_icon_file, used_overlay, layer = standing.layer + 0.1) + if(use_mod_colors) + module_icon.color = mod.color + if (mod.cached_color_filter) + module_icon = filter_appearance_recursive(module_icon, mod.cached_color_filter) . += module_icon SEND_SIGNAL(src, COMSIG_MODULE_GENERATE_WORN_OVERLAY, ., standing) @@ -368,22 +424,6 @@ return overlay_state_inactive return null -/obj/item/mod/module/proc/get_module_icon_cache(used_overlay) - var/covered_slots = mod.get_sealed_slots(mod.get_parts(all = TRUE)) - if (GLOB.mod_module_overlays[mod.skin]) - if (GLOB.mod_module_overlays[mod.skin]["[covered_slots]"]) - if (GLOB.mod_module_overlays[mod.skin]["[covered_slots]"][used_overlay]) - return GLOB.mod_module_overlays[mod.skin]["[covered_slots]"][used_overlay] - else - GLOB.mod_module_overlays[mod.skin]["[covered_slots]"] = list() - else - GLOB.mod_module_overlays[mod.skin] = list() - GLOB.mod_module_overlays[mod.skin]["[covered_slots]"] = list() - var/icon/mod_mask = icon(mod.generate_suit_mask()) - mod_mask.Blend(icon(overlay_icon_file, used_overlay), ICON_MULTIPLY) - GLOB.mod_module_overlays[mod.skin]["[covered_slots]"][used_overlay] = mod_mask - return GLOB.mod_module_overlays[mod.skin]["[covered_slots]"][used_overlay] - /// Updates the signal used by active modules to be activated /obj/item/mod/module/proc/update_signal(value) switch(value) diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 9dce0940b3f..7f9d113b124 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -90,7 +90,7 @@ if (!active) module_slowdowns += space_slowdown -/obj/item/mod/module/armor_booster/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/armor_booster/generate_worn_overlay(obj/item/source, mutable_appearance/standing) overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" overlay_state_active = "[initial(overlay_state_active)]-[mod.skin]" return ..() @@ -105,9 +105,11 @@ REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) /obj/item/mod/module/armor_booster/on_install() + . = ..() RegisterSignal(mod, COMSIG_MOD_GET_VISOR_OVERLAY, PROC_REF(on_visor_overlay)) -/obj/item/mod/module/armor_booster/on_uninstall(deleting) +/obj/item/mod/module/armor_booster/on_uninstall(deleting = FALSE) + . = ..() UnregisterSignal(mod, COMSIG_MOD_GET_VISOR_OVERLAY) /obj/item/mod/module/armor_booster/proc/on_visor_overlay(datum/source, mutable_appearance/standing, list/overrides) @@ -241,7 +243,7 @@ overlay_state_inactive = "module_insignia" mask_worn_overlay = TRUE -/obj/item/mod/module/insignia/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/insignia/generate_worn_overlay(obj/item/source, mutable_appearance/standing) overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" . = ..() for(var/mutable_appearance/appearance as anything in .) @@ -409,6 +411,7 @@ var/obj/item/current_disguise /obj/item/mod/module/chameleon/on_install() + . = ..() var/list/all_disguises = sort_list(subtypesof(get_path_by_slot(mod.slot_flags)), GLOBAL_PROC_REF(cmp_typepaths_asc)) for(var/clothing_path in all_disguises) var/obj/item/clothing = clothing_path @@ -418,6 +421,7 @@ possible_disguises[chameleon_item_name] = clothing_path /obj/item/mod/module/chameleon/on_uninstall(deleting = FALSE) + . = ..() if(current_disguise) return_look() possible_disguises = null @@ -449,7 +453,7 @@ mod.righthand_file = initial(current_disguise.righthand_file) mod.worn_icon_state = initial(current_disguise.worn_icon_state) mod.inhand_icon_state = initial(current_disguise.inhand_icon_state) - mod.wearer.update_clothing(mod.slot_flags) + update_clothing_slots() RegisterSignal(mod, COMSIG_MOD_ACTIVATE, PROC_REF(return_look)) /obj/item/mod/module/chameleon/proc/return_look() @@ -463,7 +467,7 @@ mod.righthand_file = initial(mod.righthand_file) mod.worn_icon_state = null mod.inhand_icon_state = null - mod.wearer.update_clothing(mod.slot_flags) + update_clothing_slots() current_disguise = null UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) @@ -481,10 +485,12 @@ var/old_size /obj/item/mod/module/plate_compression/on_install() + . = ..() old_size = mod.w_class mod.update_weight_class(new_size) /obj/item/mod/module/plate_compression/on_uninstall(deleting = FALSE) + . = ..() mod.update_weight_class(old_size) old_size = null if(!mod.loc) @@ -528,9 +534,11 @@ var/list/traits_to_add = list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN, TRAIT_HEAD_INJURY_BLOCKED) /obj/item/mod/module/infiltrator/on_install() + . = ..() ADD_TRAIT(mod, TRAIT_EXAMINE_SKIP, REF(src)) /obj/item/mod/module/infiltrator/on_uninstall(deleting = FALSE) + . = ..() REMOVE_TRAIT(mod, TRAIT_EXAMINE_SKIP, REF(src)) /obj/item/mod/module/infiltrator/on_part_activation() diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index 9af2ea0bc5a..018d6d35275 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -62,9 +62,11 @@ var/list/active_traits = list(TRAIT_NO_SLIP_WATER, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE, TRAIT_NEGATES_GRAVITY) /obj/item/mod/module/magboot/on_install() + . = ..() RegisterSignal(mod, COMSIG_MOD_UPDATE_SPEED, PROC_REF(on_update_speed)) -/obj/item/mod/module/magboot/on_uninstall(deleting) +/obj/item/mod/module/magboot/on_uninstall(deleting = FALSE) + . = ..() UnregisterSignal(mod, COMSIG_MOD_UPDATE_SPEED) /obj/item/mod/module/magboot/on_activation() diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 2ddb7ccdc66..3a7c0792b31 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -25,6 +25,7 @@ atom_storage.set_locked(STORAGE_FULLY_LOCKED) /obj/item/mod/module/storage/on_install() + . = ..() var/datum/storage/modstorage = mod.create_storage(max_specific_storage = max_w_class, max_total_storage = max_combined_w_class, max_slots = max_items) modstorage.set_real_location(src) modstorage.allow_big_nesting = big_nesting @@ -34,6 +35,7 @@ RegisterSignal(suit, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(on_suit_unequip)) /obj/item/mod/module/storage/on_uninstall(deleting = FALSE) + . = ..() atom_storage.set_locked(STORAGE_FULLY_LOCKED) QDEL_NULL(mod.atom_storage) if(!deleting) @@ -328,6 +330,7 @@ var/former_visor_mask_flags = NONE /obj/item/mod/module/mouthhole/on_install() + . = ..() var/obj/item/clothing/helmet = mod.get_part_from_slot(ITEM_SLOT_HEAD) if(istype(helmet)) former_helmet_flags = helmet.flags_cover @@ -351,6 +354,7 @@ return FALSE /obj/item/mod/module/mouthhole/on_uninstall(deleting = FALSE) + . = ..() if(deleting) return var/obj/item/clothing/helmet = mod.get_part_from_slot(ITEM_SLOT_HEAD) @@ -375,9 +379,11 @@ required_slots = list(ITEM_SLOT_BACK|ITEM_SLOT_BELT) /obj/item/mod/module/emp_shield/on_install() + . = ..() mod.AddElement(/datum/element/empprotection, EMP_PROTECT_ALL) /obj/item/mod/module/emp_shield/on_uninstall(deleting = FALSE) + . = ..() mod.RemoveElement(/datum/element/empprotection, EMP_PROTECT_ALL) /obj/item/mod/module/emp_shield/advanced @@ -437,7 +443,7 @@ active_power_cost = base_power * light_range return ..() -/obj/item/mod/module/flashlight/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/flashlight/generate_worn_overlay(obj/item/source, mutable_appearance/standing) . = ..() if(!active) return @@ -460,7 +466,7 @@ balloon_alert(mod.wearer, "too dark!") return set_light_color(value) - mod.wearer.update_clothing(mod.slot_flags) + update_clothing_slots() if("light_range") set_light_range(clamp(value, min_range, max_range)) @@ -594,12 +600,14 @@ var/dna = null /obj/item/mod/module/dna_lock/on_install() + . = ..() RegisterSignal(mod, COMSIG_MOD_ACTIVATE, PROC_REF(on_mod_activation)) RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, PROC_REF(on_mod_removal)) RegisterSignal(mod, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp)) RegisterSignal(mod, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag)) /obj/item/mod/module/dna_lock/on_uninstall(deleting = FALSE) + . = ..() UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL) UnregisterSignal(mod, COMSIG_ATOM_EMP_ACT) @@ -665,11 +673,15 @@ incompatible_modules = list(/obj/item/mod/module/plasma_stabilizer) required_slots = list(ITEM_SLOT_HEAD) -/obj/item/mod/module/plasma_stabilizer/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/plasma_stabilizer/generate_worn_overlay(obj/item/source, mutable_appearance/standing) + . = ..() + if (!.) + return + var/mutable_appearance/visor_overlay = mod.get_visor_overlay(standing) visor_overlay.appearance_flags |= RESET_COLOR visor_overlay.color = COLOR_VIOLET - return list(visor_overlay) + . += visor_overlay /obj/item/mod/module/plasma_stabilizer/on_equip() ADD_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, REF(src)) diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm index 989481af76c..3d4f17b7f7a 100644 --- a/code/modules/mod/modules/modules_maint.dm +++ b/code/modules/mod/modules/modules_maint.dm @@ -17,9 +17,11 @@ var/step_change = 0.5 /obj/item/mod/module/springlock/on_install() + . = ..() mod.activation_step_time *= step_change /obj/item/mod/module/springlock/on_uninstall(deleting = FALSE) + . = ..() mod.activation_step_time /= step_change /obj/item/mod/module/springlock/on_part_activation() @@ -149,18 +151,22 @@ return SEND_SOUND(mod.wearer, sound('sound/machines/terminal/terminal_off.ogg', volume = 50, channel = CHANNEL_JUKEBOX)) -/obj/item/mod/module/visor/rave/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/visor/rave/generate_worn_overlay(obj/item/source, mutable_appearance/standing) + . = ..() + if (!.) + return + var/mutable_appearance/visor_overlay = mod.get_visor_overlay(standing) visor_overlay.appearance_flags |= RESET_COLOR if (!isnull(music_player.active_song_sound)) visor_overlay.color = rainbow_order[rave_number] - return list(visor_overlay) + . += visor_overlay /obj/item/mod/module/visor/rave/on_active_process(seconds_per_tick) rave_number++ if(rave_number > length(rainbow_order)) rave_number = 1 - mod.wearer.update_clothing(mod.slot_flags) + update_clothing_slots() rave_screen.update_color(rainbow_order[rave_number]) /obj/item/mod/module/visor/rave/get_configuration() diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm index 5f7abdd712b..e75141cf3d5 100644 --- a/code/modules/mod/modules/modules_ninja.dm +++ b/code/modules/mod/modules/modules_ninja.dm @@ -93,11 +93,9 @@ required_slots = list(ITEM_SLOT_HEAD|ITEM_SLOT_EYES|ITEM_SLOT_MASK) /obj/item/mod/module/welding/camera_vision/on_part_activation() - . = ..() RegisterSignal(mod.wearer, COMSIG_LIVING_CAN_TRACK, PROC_REF(can_track)) /obj/item/mod/module/welding/camera_vision/on_part_deactivation(deleting = FALSE) - . = ..() UnregisterSignal(mod.wearer, COMSIG_LIVING_CAN_TRACK) /obj/item/mod/module/welding/camera_vision/proc/can_track(datum/source, mob/user) @@ -422,9 +420,11 @@ addtimer(CALLBACK(src, PROC_REF(boost_aftereffects), mod.wearer), 7 SECONDS) /obj/item/mod/module/adrenaline_boost/on_install() + . = ..() RegisterSignal(mod, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(try_boost)) /obj/item/mod/module/adrenaline_boost/on_uninstall(deleting = FALSE) + . = ..() UnregisterSignal(mod, COMSIG_ATOM_ITEM_INTERACTION) /obj/item/mod/module/adrenaline_boost/proc/try_boost(source, mob/user, obj/item/attacking_item) diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 06bd9352a9c..a19cd09db2b 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -22,6 +22,7 @@ guns_typecache = typecacheof(list(/obj/item/gun/ballistic, /obj/item/gun/energy, /obj/item/gun/grenadelauncher, /obj/item/gun/chem, /obj/item/gun/syringe)) /obj/item/mod/module/magnetic_harness/on_install() + . = ..() var/obj/item/clothing/suit = mod.get_part_from_slot(ITEM_SLOT_OCLOTHING) if(!istype(suit)) return @@ -29,6 +30,7 @@ suit.allowed |= guns_typecache /obj/item/mod/module/magnetic_harness/on_uninstall(deleting = FALSE) + . = ..() if(deleting) return var/obj/item/clothing/suit = mod.get_part_from_slot(ITEM_SLOT_OCLOTHING) @@ -135,6 +137,7 @@ balloon_alert(mod.wearer, "holster full!") /obj/item/mod/module/holster/on_uninstall(deleting = FALSE) + . = ..() if(holstered) holstered.forceMove(drop_location()) diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index 3e9d47ebfb0..3eee7969e9c 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -422,7 +422,7 @@ mod.update_speed() traveled_tiles = 0 -/obj/item/mod/module/ash_accretion/generate_worn_overlay(mutable_appearance/standing) +/obj/item/mod/module/ash_accretion/generate_worn_overlay(obj/item/source, mutable_appearance/standing) overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" return ..() diff --git a/code/modules/mod/modules/modules_timeline.dm b/code/modules/mod/modules/modules_timeline.dm index 654aaa0e8ee..701cbc30421 100644 --- a/code/modules/mod/modules/modules_timeline.dm +++ b/code/modules/mod/modules/modules_timeline.dm @@ -20,10 +20,12 @@ var/true_owner_ckey /obj/item/mod/module/eradication_lock/on_install() + . = ..() RegisterSignal(mod, COMSIG_MOD_ACTIVATE, PROC_REF(on_mod_activation)) RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, PROC_REF(on_mod_removal)) /obj/item/mod/module/eradication_lock/on_uninstall(deleting = FALSE) + . = ..() UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL) @@ -228,6 +230,7 @@ INVOKE_ASYNC(chrono_beam, TYPE_PROC_REF(/obj/projectile, fire)) /obj/item/mod/module/tem/on_uninstall(deleting = FALSE) + . = ..() if(!field) return field_disconnect(field) diff --git a/code/modules/wiremod/shell/module.dm b/code/modules/wiremod/shell/module.dm index bec6ce8e5c7..a3c1f8572ea 100644 --- a/code/modules/wiremod/shell/module.dm +++ b/code/modules/wiremod/shell/module.dm @@ -41,11 +41,13 @@ QDEL_LIST_ASSOC_VAL(action_comp.granted_to) /obj/item/mod/module/circuit/on_install() + . = ..() if(!shell?.attached_circuit) return RegisterSignal(shell?.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE, PROC_REF(override_power_usage)) /obj/item/mod/module/circuit/on_uninstall(deleting = FALSE) + . = ..() if(!shell?.attached_circuit) return for(var/obj/item/circuit_component/equipment_action/action_comp in action_comps)