diff --git a/code/__DEFINES/dcs/signals/signals_changeling.dm b/code/__DEFINES/dcs/signals/signals_changeling.dm new file mode 100644 index 00000000000..9b5406d669a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_changeling.dm @@ -0,0 +1,2 @@ +///Called when a changeling uses its transform ability (source = carbon), from /datum/action/changeling/transform/sting_action(mob/living/carbon/human/user) +#define COMSIG_CHANGELING_TRANSFORM "changeling_transform" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index 9a4542f9d8c..83211757340 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -79,3 +79,9 @@ //from /mob/living/carbon/human/proc/check_shields(): (atom/hit_by, damage, attack_text, attack_type, armour_penetration) #define COMSIG_HUMAN_CHECK_SHIELDS "human_check_shields" #define SHIELD_BLOCK (1<<0) + +// Mob transformation signals +///Called when a human turns into a monkey, from /mob/living/carbon/proc/finish_monkeyize() +#define COMSIG_HUMAN_MONKEYIZE "human_monkeyize" +///Called when a monkey turns into a human, from /mob/living/carbon/proc/finish_humanize(species) +#define COMSIG_MONKEY_HUMANIZE "monkey_humanize" diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 4a63cc358ea..e479d3a0a00 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -333,6 +333,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_PLASMABURNT "plasma_burnt" /// Addictions don't tick down, basically they're permanently addicted #define TRAIT_HOPELESSLY_ADDICTED "hopelessly_addicted" +/// This mob has a cult halo. +#define TRAIT_CULT_HALO "cult_halo" /// Their eyes glow an unnatural red colour. Currently used to set special examine text on humans. Does not guarantee the mob's eyes are coloured red, nor that there is any visible glow on their character sprite. #define TRAIT_UNNATURAL_RED_GLOWY_EYES "unnatural_red_glowy_eyes" /// Their eyes are bloodshot. Currently used to set special examine text on humans. Examine text is overridden by TRAIT_UNNATURAL_RED_GLOWY_EYES. diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 10e00734b38..7d4f60143da 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -167,6 +167,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NO_SOUL" = TRAIT_NO_SOUL, "TRAIT_INVISIBLE_MAN" = TRAIT_INVISIBLE_MAN, "TRAIT_HIDE_EXTERNAL_ORGANS" = TRAIT_HIDE_EXTERNAL_ORGANS, + "TRAIT_CULT_HALO" = TRAIT_CULT_HALO, "TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES, "TRAIT_BLOODSHOT_EYES" = TRAIT_BLOODSHOT_EYES, "TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES, diff --git a/code/datums/elements/cult_eyes.dm b/code/datums/elements/cult_eyes.dm new file mode 100644 index 00000000000..3ff5c8d646d --- /dev/null +++ b/code/datums/elements/cult_eyes.dm @@ -0,0 +1,46 @@ +/** + * # Cult eyes element + * + * Applies and removes the glowing cult eyes + */ +/datum/element/cult_eyes + element_flags = ELEMENT_DETACH + +/datum/element/cult_eyes/Attach(datum/target, initial_delay = 20 SECONDS) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + // Register signals for mob transformation to prevent premature halo removal + RegisterSignal(target, list(COMSIG_CHANGELING_TRANSFORM, COMSIG_MONKEY_HUMANIZE, COMSIG_HUMAN_MONKEYIZE), .proc/set_eyes) + addtimer(CALLBACK(src, .proc/set_eyes, target), initial_delay) + +/** + * Cult eye setter proc + * + * Changes the eye color, and adds the glowing eye trait to the mob. + */ +/datum/element/cult_eyes/proc/set_eyes(mob/living/target) + SIGNAL_HANDLER + + ADD_TRAIT(target, TRAIT_UNNATURAL_RED_GLOWY_EYES, CULT_TRAIT) + if (ishuman(target)) + var/mob/living/carbon/human/human_parent = target + human_parent.eye_color = BLOODCULT_EYE + human_parent.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) + human_parent.update_body() + +/** + * Detach proc + * + * Removes the eye color, and trait from the mob + */ +/datum/element/cult_eyes/Detach(mob/living/target, ...) + REMOVE_TRAIT(target, TRAIT_UNNATURAL_RED_GLOWY_EYES, CULT_TRAIT) + if (ishuman(target)) + var/mob/living/carbon/human/human_parent = target + human_parent.eye_color = initial(human_parent.eye_color) + human_parent.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) + human_parent.update_body() + UnregisterSignal(target, list(COMSIG_CHANGELING_TRANSFORM, COMSIG_HUMAN_MONKEYIZE, COMSIG_MONKEY_HUMANIZE)) + return ..() diff --git a/code/datums/elements/cult_halo.dm b/code/datums/elements/cult_halo.dm new file mode 100644 index 00000000000..39a6e2d6a33 --- /dev/null +++ b/code/datums/elements/cult_halo.dm @@ -0,0 +1,50 @@ +/** + * # Cult halo element + * + * Applies and removes the cult halo + */ +/datum/element/cult_halo + element_flags = ELEMENT_DETACH + +/datum/element/cult_halo/Attach(datum/target, initial_delay = 20 SECONDS) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + // Register signals for mob transformation to prevent premature halo removal + RegisterSignal(target, list(COMSIG_CHANGELING_TRANSFORM, COMSIG_MONKEY_HUMANIZE, COMSIG_HUMAN_MONKEYIZE), .proc/set_halo) + addtimer(CALLBACK(src, .proc/set_halo, target), initial_delay) + +/** + * Halo setter proc + * + * Adds the cult halo overlays, and adds the halo trait to the mob. + */ +/datum/element/cult_halo/proc/set_halo(mob/living/target) + SIGNAL_HANDLER + + ADD_TRAIT(target, TRAIT_CULT_HALO, CULT_TRAIT) + var/mutable_appearance/new_halo_overlay = mutable_appearance('icons/effects/32x64.dmi', "halo[rand(1, 6)]", -HALO_LAYER) + if (ishuman(target)) + var/mob/living/carbon/human/human_parent = target + new /obj/effect/temp_visual/cult/sparks(get_turf(human_parent), human_parent.dir) + human_parent.overlays_standing[HALO_LAYER] = new_halo_overlay + human_parent.apply_overlay(HALO_LAYER) + else + target.add_overlay(new_halo_overlay) + +/** + * Detach proc + * + * Removes the halo overlays, and trait from the mob + */ +/datum/element/cult_halo/Detach(mob/living/target, ...) + REMOVE_TRAIT(target, TRAIT_CULT_HALO, CULT_TRAIT) + if (ishuman(target)) + var/mob/living/carbon/human/human_parent = target + human_parent.remove_overlay(HALO_LAYER) + human_parent.update_body() + else + target.cut_overlay(HALO_LAYER) + UnregisterSignal(target, list(COMSIG_CHANGELING_TRANSFORM, COMSIG_HUMAN_MONKEYIZE, COMSIG_MONKEY_HUMANIZE)) + return ..() diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index d4dde7f089c..47b4eb255fb 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -142,6 +142,7 @@ return ..() changeling.transform(user, chosen_prof) + SEND_SIGNAL(user, COMSIG_CHANGELING_TRANSFORM) return TRUE /** diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 254c0db308d..3a1d7f5c762 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -138,9 +138,9 @@ magic.Grant(current) current.throw_alert("bloodsense", /atom/movable/screen/alert/bloodsense) if(cult_team.cult_risen) - cult_team.rise(current) - if(cult_team.cult_ascendent) - cult_team.ascend(current) + current.AddElement(/datum/element/cult_eyes, initial_delay = 0 SECONDS) + if(cult_team.cult_ascendent) + current.AddElement(/datum/element/cult_halo, initial_delay = 0 SECONDS) add_team_hud(current) @@ -156,13 +156,10 @@ communion.Remove(current) magic.Remove(current) current.clear_alert("bloodsense") - if(ishuman(current)) - var/mob/living/carbon/human/H = current - H.eye_color = initial(H.eye_color) - H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - REMOVE_TRAIT(H, TRAIT_UNNATURAL_RED_GLOWY_EYES, CULT_TRAIT) - H.remove_overlay(HALO_LAYER) - H.update_body() + if (HAS_TRAIT(current, TRAIT_UNNATURAL_RED_GLOWY_EYES)) + current.RemoveElement(/datum/element/cult_eyes) + if (HAS_TRAIT(current, TRAIT_CULT_HALO)) + current.RemoveElement(/datum/element/cult_halo) /datum/antagonist/cult/on_mindshield(mob/implanter) if(!silent) @@ -238,9 +235,9 @@ current.update_action_buttons_icon() current.apply_status_effect(/datum/status_effect/cult_master) if(cult_team.cult_risen) - cult_team.rise(current) - if(cult_team.cult_ascendent) - cult_team.ascend(current) + current.AddElement(/datum/element/cult_eyes, initial_delay = 0 SECONDS) + if(cult_team.cult_ascendent) + current.AddElement(/datum/element/cult_halo, initial_delay = 0 SECONDS) add_team_hud(current, /datum/antagonist/cult) /datum/antagonist/cult/master/remove_innate_effects(mob/living/mob_override) @@ -281,41 +278,23 @@ ++alive var/ratio = cultplayers/alive if(ratio > CULT_RISEN && !cult_risen) - for(var/datum/mind/B in members) - if(B.current) - SEND_SOUND(B.current, 'sound/hallucinations/i_see_you2.ogg') - to_chat(B.current, span_cultlarge("The veil weakens as your cult grows, your eyes begin to glow...")) - addtimer(CALLBACK(src, .proc/rise, B.current), 200) + for(var/datum/mind/mind as anything in members) + if(mind.current) + SEND_SOUND(mind.current, 'sound/hallucinations/i_see_you2.ogg') + to_chat(mind.current, span_cultlarge(span_warning("The veil weakens as your cult grows, your eyes begin to glow..."))) + mind.current.AddElement(/datum/element/cult_eyes) cult_risen = TRUE log_game("The blood cult has risen with [cultplayers] players.") if(ratio > CULT_ASCENDENT && !cult_ascendent) - for(var/datum/mind/B in members) - if(B.current) - SEND_SOUND(B.current, 'sound/hallucinations/im_here1.ogg') - to_chat(B.current, span_cultlarge("Your cult is ascendent and the red harvest approaches - you cannot hide your true nature for much longer!!")) - addtimer(CALLBACK(src, .proc/ascend, B.current), 200) + for(var/datum/mind/mind as anything in members) + if(mind.current) + SEND_SOUND(mind.current, 'sound/hallucinations/im_here1.ogg') + to_chat(mind.current, span_cultlarge(span_warning("Your cult is ascendent and the red harvest approaches - you cannot hide your true nature for much longer!!"))) + mind.current.AddElement(/datum/element/cult_halo) cult_ascendent = TRUE log_game("The blood cult has ascended with [cultplayers] players.") - -/datum/team/cult/proc/rise(cultist) - if(ishuman(cultist)) - var/mob/living/carbon/human/H = cultist - H.eye_color = BLOODCULT_EYE - H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - ADD_TRAIT(H, TRAIT_UNNATURAL_RED_GLOWY_EYES, CULT_TRAIT) - H.update_body() - -/datum/team/cult/proc/ascend(cultist) - if(ishuman(cultist)) - var/mob/living/carbon/human/human = cultist - new /obj/effect/temp_visual/cult/sparks(get_turf(human), human.dir) - var/istate = pick("halo1","halo2","halo3","halo4","halo5","halo6") - var/mutable_appearance/new_halo_overlay = mutable_appearance('icons/effects/32x64.dmi', istate, -HALO_LAYER) - human.overlays_standing[HALO_LAYER] = new_halo_overlay - human.apply_overlay(HALO_LAYER) - /datum/team/cult/proc/make_image(datum/objective/sacrifice/sac_objective) var/datum/job/job_of_sacrifice = sac_objective.target.assigned_role var/datum/preferences/prefs_of_sacrifice = sac_objective.target.current.client.prefs diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 8ed79a0cef5..efbc1a0a2b3 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -25,6 +25,7 @@ icon = initial(icon) invisibility = 0 set_species(/datum/species/monkey) + SEND_SIGNAL(src, COMSIG_HUMAN_MONKEYIZE) uncuff() return src @@ -55,6 +56,7 @@ icon = initial(icon) invisibility = 0 set_species(species) + SEND_SIGNAL(src, COMSIG_MONKEY_HUMANIZE) return src /mob/proc/AIize(transfer_after = TRUE, client/preference_source, move = TRUE) diff --git a/tgstation.dme b/tgstation.dme index 1f9a7fac41b..ce43f4b01e6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -184,6 +184,7 @@ #include "code\__DEFINES\dcs\signals\signals_adventure.dm" #include "code\__DEFINES\dcs\signals\signals_area.dm" #include "code\__DEFINES\dcs\signals\signals_bot.dm" +#include "code\__DEFINES\dcs\signals\signals_changeling.dm" #include "code\__DEFINES\dcs\signals\signals_circuit.dm" #include "code\__DEFINES\dcs\signals\signals_clothing.dm" #include "code\__DEFINES\dcs\signals\signals_container.dm" @@ -870,6 +871,8 @@ #include "code\datums\elements\crackable.dm" #include "code\datums\elements\curse_announcement.dm" #include "code\datums\elements\cursed.dm" +#include "code\datums\elements\cult_eyes.dm" +#include "code\datums\elements\cult_halo.dm" #include "code\datums\elements\death_drops.dm" #include "code\datums\elements\deferred_aquarium_content.dm" #include "code\datums\elements\delete_on_drop.dm"