diff --git a/code/__DEFINES/misc_defines.dm b/code/__DEFINES/misc_defines.dm index acbbb10dccf..1e3392948ba 100644 --- a/code/__DEFINES/misc_defines.dm +++ b/code/__DEFINES/misc_defines.dm @@ -734,3 +734,5 @@ do { \ #define INGREDIENT_CHECK_EXACT 1 #define INGREDIENT_CHECK_FAILURE 0 #define INGREDIENT_CHECK_SURPLUS -1 + +#define ALPHA_VISIBLE 255 // the max alpha diff --git a/code/game/dna/mutations/mutation_powers.dm b/code/game/dna/mutations/mutation_powers.dm index e24f4b8819a..9cdd0861b68 100644 --- a/code/game/dna/mutations/mutation_powers.dm +++ b/code/game/dna/mutations/mutation_powers.dm @@ -209,19 +209,29 @@ ..() block = GLOB.shadowblock +/datum/mutation/stealth/darkcloak/deactivate(mob/living/M) + ..() + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.set_alpha_tracking(ALPHA_VISIBLE, src) + if(!ishuman(M)) + return + var/mob/living/carbon/human/H = M + H.set_alpha_tracking(ALPHA_VISIBLE, src) /datum/mutation/stealth/darkcloak/on_life(mob/M) var/turf/simulated/T = get_turf(M) - if(!istype(T)) + if(!istype(T) || !ishuman(M)) return + var/mob/living/carbon/human/H = M var/light_available = T.get_lumcount() * 10 if(light_available <= 2) - if(M.invisibility != INVISIBILITY_LEVEL_TWO) - M.alpha = round(M.alpha * 0.8) + if(H.invisibility != INVISIBILITY_LEVEL_TWO) + H.set_alpha_tracking(H.get_alpha() * 0.8, src) else - M.reset_visibility() - M.alpha = round(255 * 0.8) - if(M.alpha == 0) - M.make_invisible() + H.reset_visibility() + H.set_alpha_tracking(ALPHA_VISIBLE * 0.8, src) + if(H.get_alpha(src) == 0) + H.make_invisible() //WAS: /datum/bioEffect/chameleon /datum/mutation/stealth/chameleon @@ -234,15 +244,24 @@ ..() block = GLOB.chameleonblock -/datum/mutation/stealth/chameleon/on_life(mob/living/M) //look if a ghost gets this, its an admins problem - if((world.time - M.last_movement) >= 30 && !M.stat && (M.mobility_flags & MOBILITY_STAND) && !M.restrained()) - if(M.invisibility != INVISIBILITY_LEVEL_TWO) - M.alpha -= 25 +/datum/mutation/stealth/chameleon/deactivate(mob/living/M) + ..() + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.set_alpha_tracking(ALPHA_VISIBLE, src) + +/datum/mutation/stealth/chameleon/on_life(mob/living/M) + if(!ishuman(M)) + return + var/mob/living/carbon/human/H = M + if((world.time - H.last_movement) >= 30 && !H.stat && (H.mobility_flags & MOBILITY_STAND) && !H.restrained()) + if(H.invisibility != INVISIBILITY_LEVEL_TWO) + H.set_alpha_tracking(H.get_alpha() - 25, src) else - M.reset_visibility() - M.alpha = round(255 * 0.80) - if(M.alpha == 0) - M.make_invisible() + H.reset_visibility() + H.set_alpha_tracking(ALPHA_VISIBLE * 0.8, src) + if(H.get_alpha(src) == 0) + H.make_invisible() ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index a34e31f6738..e6921569f7b 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -292,13 +292,20 @@ RegisterSignal(user, COMSIG_CARBON_REGENERATE_ICONS, PROC_REF(reapply_hide)) mob_overlay = mutable_appearance(icon, icon_state, user.layer, user.plane, 255, appearance_flags = RESET_COLOR | RESET_TRANSFORM | RESET_ALPHA | KEEP_APART) user.add_overlay(mob_overlay) - user.alpha = 0 + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.set_alpha_tracking(0, src) + else + user.alpha = 0 /// User has either dropped the plant, or plant is being destroyed, restore user to normal. /obj/item/kirbyplants/proc/unhide_user(mob/living/carbon/user) UnregisterSignal(user, COMSIG_CARBON_REGENERATE_ICONS) user.cut_overlay(mob_overlay) user.alpha = initial(user.alpha) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.set_alpha_tracking(ALPHA_VISIBLE, src) QDEL_NULL(mob_overlay) /// Icon operation has occured, time to make sure we're showing a plant again if we need to be. diff --git a/code/modules/antagonists/changeling/powers/environmental_adaption.dm b/code/modules/antagonists/changeling/powers/environmental_adaption.dm index 6935bbdb3be..7d7e4623abe 100644 --- a/code/modules/antagonists/changeling/powers/environmental_adaption.dm +++ b/code/modules/antagonists/changeling/powers/environmental_adaption.dm @@ -16,6 +16,12 @@ var/recharge_slowdown = 0.15 var/chem_recharge_slowdown = 0 +/datum/action/changeling/environmental_adaptation/Destroy(force, ...) + if(ishuman(cling.owner.current)) + var/mob/living/carbon/human/H = cling.owner.current + H.set_alpha_tracking(ALPHA_VISIBLE, src) + return ..() + /datum/action/changeling/environmental_adaptation/sting_action(mob/living/carbon/human/cling) //SHOULD always be human, because req_human = TRUE ..() is_active = !is_active @@ -26,14 +32,16 @@ /datum/action/changeling/environmental_adaptation/proc/enable_ability(mob/living/carbon/human/cling) //Enable the adaptation - animate(cling, alpha = 65, time = 3 SECONDS) + cling.set_alpha_tracking(65, src, update_alpha = FALSE) + animate(cling, alpha = cling.get_alpha(), time = 3 SECONDS) cling.visible_message("[cling]'s skin suddenly starts becoming translucent!", \ "We adapt our pigmentation to suit the environment around us.") var/datum/antagonist/changeling/changeling_data = cling.mind?.has_antag_datum(/datum/antagonist/changeling) changeling_data?.chem_recharge_slowdown -= recharge_slowdown //Slows down chem regeneration /datum/action/changeling/environmental_adaptation/proc/disable_ability(mob/living/carbon/human/cling) //Restore the adaptation - animate(cling, alpha = 255, time = 3 SECONDS) + cling.set_alpha_tracking(ALPHA_VISIBLE, src, update_alpha = FALSE) + animate(cling, alpha = cling.get_alpha(), time = 3 SECONDS) cling.visible_message( "[cling] appears from thin air!", "We stop concentration on our pigmentation, allowing it to return to normal.", diff --git a/code/modules/antagonists/vampire/vamp_datum.dm b/code/modules/antagonists/vampire/vamp_datum.dm index cc62c38b72d..3fe4dcc7660 100644 --- a/code/modules/antagonists/vampire/vamp_datum.dm +++ b/code/modules/antagonists/vampire/vamp_datum.dm @@ -36,11 +36,17 @@ RESTRICT_TYPE(/datum/antagonist/vampire) blurb_a = 1 /datum/antagonist/vampire/Destroy(force, ...) - owner.current.create_log(CONVERSION_LOG, "De-vampired") draining = null QDEL_NULL(subclass) return ..() +/datum/antagonist/vampire/detach_from_owner() + owner.current.create_log(CONVERSION_LOG, "De-vampired") + if(ishuman(owner.current)) + var/mob/living/carbon/human/human_owner = owner.current + human_owner.set_alpha_tracking(ALPHA_VISIBLE, src) + return ..() + /datum/antagonist/vampire/add_owner_to_gamemode() SSticker.mode.vampires += owner @@ -258,24 +264,25 @@ RESTRICT_TYPE(/datum/antagonist/vampire) if(!ishuman(owner.current)) owner.current.alpha = 255 return - var/turf/simulated/T = get_turf(owner.current) + var/mob/living/carbon/human/human_owner = owner.current + var/turf/simulated/T = get_turf(human_owner) var/light_available = T.get_lumcount() * 10 if(!istype(T)) return - if(!iscloaking || owner.current.on_fire) - owner.current.alpha = 255 - REMOVE_TRAIT(owner.current, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT) + if(!iscloaking || human_owner.on_fire) + human_owner.set_alpha_tracking(ALPHA_VISIBLE, src) + REMOVE_TRAIT(human_owner, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT) return if(light_available <= 2) - owner.current.alpha = 38 // round(255 * 0.15) - ADD_TRAIT(owner.current, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT) + human_owner.set_alpha_tracking(ALPHA_VISIBLE * 0.15, src) + ADD_TRAIT(human_owner, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT) return - REMOVE_TRAIT(owner.current, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT) - owner.current.alpha = 204 // 255 * 0.80 + REMOVE_TRAIT(human_owner, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT) + human_owner.set_alpha_tracking(ALPHA_VISIBLE * 0.80, src) /** * Handles unique drain ID checks and increases vampire's total and usable blood by blood_amount. Checks for ability upgrades. diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm index 66a94acf1ad..eb5b621a630 100644 --- a/code/modules/mining/lavaland/loot/hierophant_loot.dm +++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm @@ -242,6 +242,9 @@ var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to, TRUE)) return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.set_alpha_tracking(0, src, update_alpha = FALSE) animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out sleep(1) if(!M) @@ -254,7 +257,12 @@ sleep(1) if(!M) return - animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN + var/our_alpha = 255 + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.set_alpha_tracking(ALPHA_VISIBLE, src, update_alpha = FALSE) + our_alpha = H.get_alpha() + animate(M, alpha = our_alpha, time = 2, easing = EASE_IN) //fade IN sleep(1) if(!M) return diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 5cf1b5218fc..501eda399e7 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -103,3 +103,6 @@ var/list/bodyparts = list() /// map organ names to organs var/list/bodyparts_by_name = list() + + /// Lazylist of sources to track what our alpha should be, alpha is set to the minimum. Use the `set_alpha_tracking` and `get_alpha` helpers. + var/list/alpha_sources diff --git a/code/modules/mob/living/carbon/human/human_mob.dm b/code/modules/mob/living/carbon/human/human_mob.dm index 2a68cfd0467..c73e1df7734 100644 --- a/code/modules/mob/living/carbon/human/human_mob.dm +++ b/code/modules/mob/living/carbon/human/human_mob.dm @@ -2034,3 +2034,30 @@ Eyes need to have significantly high darksight to shine unless the mob has the X dna.ResetUIFrom(src) flavor_text = "" +/** + * Helper for tracking alpha, use this to set an alpha source + * + * alpha_num - num between 0 and 255 that represents the alpha from `source` + * source - a datum that is the cause of the alpha source. This will be turned into a key via UID. + * update_alpha - boolean if alpha should be updated with this proc. Set this to false if you plan to animate the alpha after this call. + */ +/mob/living/carbon/human/proc/set_alpha_tracking(alpha_num, datum/source, update_alpha = TRUE) + alpha_num = round(alpha_num) + if(alpha_num >= ALPHA_VISIBLE) + LAZYREMOVE(alpha_sources, source.UID()) + else + LAZYSET(alpha_sources, source.UID(), max(alpha_num, 0)) + if(update_alpha) + alpha = get_alpha() + +/** + * Gets the target alpha of the human + * + * optional_source - use this to get the alpha of an exact source. This is unsafe, only use if you 100% know it will be in the list. For the best safety, only call this as get_alpha(src) + */ +/mob/living/carbon/human/proc/get_alpha(datum/optional_source) + if(optional_source) + return alpha_sources[optional_source.UID()] + . = ALPHA_VISIBLE + for(var/source in alpha_sources) + . = min(., alpha_sources[source]) diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index 95a6c790308..47f744999fe 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -564,6 +564,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) update_fire() update_icons() update_emissive_block() + alpha = get_alpha() if(player_logged) //make sure the SSD overlay stays overlays += image('icons/effects/effects.dmi', icon_state = "zzz_glow") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8a8e806f86b..3dcac7d1c69 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1360,6 +1360,10 @@ GLOBAL_LIST_INIT(holy_areas, typecacheof(list( alpha = initial(alpha) add_to_all_human_data_huds() +/mob/living/carbon/human/reset_visibility() + ..() + alpha = get_alpha() + /mob/proc/make_invisible() invisibility = INVISIBILITY_LEVEL_TWO alpha = 128 diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 835de26f048..3bfdf62ccb6 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -288,7 +288,8 @@ RegisterSignal(mod.wearer, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, PROC_REF(on_unarmed_attack)) RegisterSignal(mod.wearer, COMSIG_ATOM_BULLET_ACT, PROC_REF(on_bullet_act)) RegisterSignals(mod.wearer, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_HITBY, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW), PROC_REF(unstealth)) - animate(mod.wearer, alpha = stealth_alpha, time = 1.5 SECONDS) + mod.wearer.set_alpha_tracking(stealth_alpha, src, update_alpha = FALSE) + animate(mod.wearer, alpha = mod.wearer.get_alpha(), time = 1.5 SECONDS) drain_power(use_power_cost) /obj/item/mod/module/stealth/on_deactivation(display_message = TRUE, deleting = FALSE) @@ -298,7 +299,8 @@ if(bumpoff) UnregisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP) UnregisterSignal(mod.wearer, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_HITBY, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW)) - animate(mod.wearer, alpha = 255, time = 1.5 SECONDS) + mod.wearer.set_alpha_tracking(ALPHA_VISIBLE, src, update_alpha = FALSE) + animate(mod.wearer, alpha = mod.wearer.get_alpha(), time = 1.5 SECONDS) /obj/item/mod/module/stealth/proc/unstealth(datum/source) SIGNAL_HANDLER