mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 01:34:01 +00:00
Refactors MODsuit module rendering and allows overslotted parts to show items they overslot when unsealed (#90414)
MODsuit modules now render on the part they're attached to, that being first part if required_slots is set, otherwise defaulting to the control module. Instead of using icon ops and a cache, module masking (used by armor boosters and insignias) will instead render the module on all parts, each overlay alpha filtered using the worn piece as the mask. To do this we also migrate modules to separate_worn_overlays, which fixes the issue where they'd always get painted the same color as the back piece, ignoring use_mod_colors's value (which is FALSE by default). So now modules that inherit MOD's color like armor booster will be painted accordingly to their piece. This also means that modules actually layer properly, and don't go ontop of items that they should be under. Additionally, whenever gloves or boots overslot an item, the overslotted item will still render underneath them if they're unsealed. Because it looks weird when your gloves disappear when you extend your MODsuit ones.  Look at that hip look, she'd have bare hands and ankles without this PR. Closes #90370 Fixes a bunch of visual jank that looks weird, and overslotting displaying overslotted item is just behavior you'd expect normally. 🆑 add: When a MODsuit piece overslots an item, it will now render beneath that piece as long as its unsealed. refactor: Refactored how MODsuit modules are rendered, report any bugs on GitHub! /🆑
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -119,49 +119,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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -658,3 +658,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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -115,13 +115,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)
|
||||
@@ -454,11 +451,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)
|
||||
@@ -492,21 +492,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()
|
||||
@@ -613,7 +598,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()
|
||||
@@ -633,7 +617,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -108,7 +108,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))
|
||||
@@ -118,7 +118,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
|
||||
|
||||
|
||||
@@ -180,9 +180,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
|
||||
@@ -199,11 +199,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))
|
||||
@@ -220,7 +231,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
|
||||
@@ -271,11 +282,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()
|
||||
@@ -343,27 +381,45 @@
|
||||
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
|
||||
|
||||
/* BUBBER EDIT START - Making MODsuits mutant-compatible - ORIGINAL:
|
||||
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
|
||||
*/
|
||||
@@ -380,22 +436,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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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/gun/microfusion)) //SKYRAT EDIT - MICROFUSION
|
||||
|
||||
/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())
|
||||
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user