diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 62573bad430..9125770ea3c 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -654,3 +654,6 @@ /// Sent from /obj/item/mail/traitor/after_unwrap(mob/user, obj/item/mail/traitor/letter) #define COMSIG_ITEM_IN_UNWRAPPED_TRAITOR_MAIL "traitor_mail_opened" #define COMPONENT_TRAITOR_MAIL_HANDLED (1<<0) + +/// Sent from /datum/component/reflection when the reflection is updated to the mob reflecting: (atom/movable/reflecting_in, obj/effect/abstract/reflection) +#define COMSIG_REFLECTION_UPDATED "reflection_updated" diff --git a/code/datums/components/reflection.dm b/code/datums/components/reflection.dm index d5d37b72dd2..5e786b0c4ac 100644 --- a/code/datums/components/reflection.dm +++ b/code/datums/components/reflection.dm @@ -118,6 +118,8 @@ /datum/component/reflection/proc/check_can_reflect(atom/movable/target) if(target == parent || !(target in view(1, parent))) return FALSE + if(target.invisibility >= INVISIBILITY_MAXIMUM) + return FALSE var/atom/movable/mov_parent = parent if(target.loc != mov_parent.loc && get_dir(mov_parent, target) != reflected_dir) return FALSE @@ -201,6 +203,8 @@ // purely for vv reflection.name = "[target.name]'s reflection" + SEND_SIGNAL(target, COMSIG_REFLECTION_UPDATED, parent, reflection) + ///Called when the target movable changes its appearance or dir. /datum/component/reflection/proc/update_reflection(atom/movable/source) SIGNAL_HANDLER diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 0bddf5575d2..dff81692a5f 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -61,10 +61,10 @@ register_context() /obj/structure/mirror/proc/can_reflect(atom/movable/target) - ///I'm doing it this way too, because the signal is sent before the broken variable is set to TRUE. - if(atom_integrity <= integrity_failure * max_integrity) + // I'm doing it this way too, because the signal is sent before the broken variable is set to TRUE. + if(atom_integrity <= integrity_failure * max_integrity || broken) return FALSE - if(broken || !isliving(target) || HAS_TRAIT(target, TRAIT_NO_MIRROR_REFLECTION)) + if(!isliving(target) || HAS_TRAIT(target, TRAIT_NO_MIRROR_REFLECTION)) return FALSE return TRUE diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index 4d7dd688350..4aae0ffa2d7 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -95,13 +95,22 @@ /mob/living/basic/revenant/Initialize(mapload) . = ..() AddElement(/datum/element/simple_flying) - add_traits(list(TRAIT_SPACEWALK, TRAIT_SIXTHSENSE, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_SEE_BLESSED_TILES), INNATE_TRAIT) + add_traits(list(TRAIT_SPACEWALK, TRAIT_SIXTHSENSE, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_SEE_BLESSED_TILES, TRAIT_IGNORE_ELEVATION), INNATE_TRAIT) grant_actions_by_list(abilities) RegisterSignal(src, COMSIG_LIVING_BANED, PROC_REF(on_baned)) RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) RegisterSignal(src, COMSIG_LIVING_LIFE, PROC_REF(on_life)) + RegisterSignal(src, COMSIG_REFLECTION_UPDATED, PROC_REF(on_reflect)) + RegisterSignals(src, list( + SIGNAL_ADDTRAIT(TRAIT_REVENANT_REVEALED), + SIGNAL_REMOVETRAIT(TRAIT_REVENANT_REVEALED), + SIGNAL_ADDTRAIT(TRAIT_REVENANT_INHIBITED), + SIGNAL_REMOVETRAIT(TRAIT_REVENANT_INHIBITED), + SIGNAL_ADDTRAIT(TRAIT_NO_TRANSFORM), + SIGNAL_REMOVETRAIT(TRAIT_NO_TRANSFORM), + ), PROC_REF(update_revenant_appearance)) name = generate_random_mob_name() GLOB.revenant_relay_mobs |= src @@ -146,9 +155,12 @@ essence = min(essence + (essence_regen_amount * change_in_time), max_essence) update_mob_action_buttons() //because we update something required by our spells in life, we need to update our buttons - update_appearance(UPDATE_ICON) update_health_hud() +/mob/living/basic/revenant/proc/update_revenant_appearance() + SIGNAL_HANDLER + update_appearance(UPDATE_ICON) + /mob/living/basic/revenant/AltClickOn(atom/target) if(CAN_I_SEE(target)) client.loot_panel.open(get_turf(target)) @@ -466,4 +478,18 @@ to_chat(src, span_revenminor("Lost [essence_to_change_by]E [source ? "from [source]":""].")) return TRUE +/mob/living/basic/revenant/proc/on_reflect(datum/source, atom/movable/reflecting_in, obj/effect/abstract/reflection) + SIGNAL_HANDLER + // powers are inhibited and we're not revealed so we can't project a reflect + if(HAS_TRAIT(src, TRAIT_REVENANT_INHIBITED) && !HAS_TRAIT(src, TRAIT_REVENANT_REVEALED)) + return + + // otherwise revenants are always visible in reflections even if otherwise invisible + reflection.clear_filters() + reflection.SetInvisibility(0) + + // but if we're (actually) invisible we look all wibbly and ghostly (unless the mirror is magic) + if(!HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) && !istype(reflecting_in, /obj/structure/mirror/magic)) + apply_wibbly_filters(reflection) + #undef REVENANT_STUNNED_TRAIT diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm index 8409716a629..d456f104218 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm @@ -188,6 +188,11 @@ new /obj/effect/temp_visual/revenant/cracks(window.loc) for(var/obj/machinery/light/light in victim) light.flicker(rand(3, 5)) //spooky + for(var/obj/structure/mirror/mirror in victim) + if(istype(mirror, /obj/structure/mirror/magic)) + continue + new /obj/effect/temp_visual/revenant(mirror.loc) + mirror.atom_break("magic") //Malfunction: Makes bad stuff happen to robots and machines. /datum/action/cooldown/spell/aoe/revenant/malfunction