diff --git a/code/datums/components/space_camo.dm b/code/datums/components/space_camo.dm index 08b6c106494..50ccab7b181 100644 --- a/code/datums/components/space_camo.dm +++ b/code/datums/components/space_camo.dm @@ -8,6 +8,12 @@ var/reveal_after_combat /// The world time after we can camo again VAR_PRIVATE/next_camo + /// Image we show to our jaunter so they can see where they are + var/image/position_indicator + /// Icon we draw our position indicator from + var/phased_mob_icon = 'icons/obj/weapons/guns/projectiles.dmi' + /// Icon state we use for our position indicator + var/phased_mob_icon_state = "solarflare" /datum/component/space_camo/Initialize(space_alpha, non_space_alpha, reveal_after_combat) if(!ismovable(parent)) @@ -17,10 +23,36 @@ src.non_space_alpha = non_space_alpha src.reveal_after_combat = reveal_after_combat +/datum/component/space_camo/RegisterWithParent() RegisterSignal(parent, COMSIG_ATOM_ENTERING, PROC_REF(on_atom_entering)) + if(!isliving(parent)) + return - if(isliving(parent)) - RegisterSignals(parent, list(COMSIG_ATOM_WAS_ATTACKED, COMSIG_MOB_ITEM_ATTACK, COMSIG_LIVING_UNARMED_ATTACK, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_REVEAL), PROC_REF(force_exit_camo)) + var/mob/living/living_parent = parent + position_indicator = image(phased_mob_icon, living_parent, phased_mob_icon_state, ABOVE_LIGHTING_PLANE) + SET_PLANE_EXPLICIT(position_indicator, ABOVE_LIGHTING_PLANE, living_parent) + position_indicator.appearance_flags |= RESET_ALPHA + position_indicator.alpha = 0 + + RegisterSignals(parent, list(COMSIG_ATOM_WAS_ATTACKED, COMSIG_MOB_ITEM_ATTACK, COMSIG_LIVING_UNARMED_ATTACK, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_REVEAL), PROC_REF(force_exit_camo)) + RegisterSignal(parent, COMSIG_MOB_LOGIN, PROC_REF(show_client_image)) + show_client_image(parent) + +/datum/component/space_camo/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_ENTERING, + COMSIG_ATOM_WAS_ATTACKED, + COMSIG_MOB_ITEM_ATTACK, + COMSIG_LIVING_UNARMED_ATTACK, + COMSIG_ATOM_BULLET_ACT, + COMSIG_ATOM_REVEAL, + COMSIG_MOB_LOGIN, + )) + remove_client_image(parent) + +/datum/component/space_camo/Destroy(force) + . = ..() + position_indicator = null /datum/component/space_camo/proc/on_atom_entering(atom/movable/entering, atom/entered) SIGNAL_HANDLER @@ -45,10 +77,22 @@ /datum/component/space_camo/proc/enter_camo(atom/movable/parent) if(parent.alpha != space_alpha) animate(parent, alpha = space_alpha, time = 0.5 SECONDS) + if (position_indicator) + animate(position_indicator, alpha = 255, time = 0.5 SECONDS) parent.remove_from_all_data_huds() parent.add_atom_colour(SSparallax.get_parallax_color(), TEMPORARY_COLOUR_PRIORITY) /datum/component/space_camo/proc/exit_camo(atom/movable/parent) animate(parent, alpha = non_space_alpha, time = 0.5 SECONDS) + if (position_indicator) + animate(position_indicator, alpha = 0, time = 0.5 SECONDS) parent.add_to_all_human_data_huds() parent.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + +/datum/component/space_camo/proc/show_client_image(mob/show_to) + SIGNAL_HANDLER + show_to.client?.images |= position_indicator + +/datum/component/space_camo/proc/remove_client_image(mob/remove_from) + SIGNAL_HANDLER + remove_from.client?.images -= position_indicator diff --git a/code/datums/components/space_dive.dm b/code/datums/components/space_dive.dm index bbbeb0bb168..3a172307aab 100644 --- a/code/datums/components/space_dive.dm +++ b/code/datums/components/space_dive.dm @@ -82,3 +82,4 @@ /obj/effect/dummy/phased_mob/space_dive movespeed = 1 + phased_mob_icon_state = "solarflare" diff --git a/code/game/objects/effects/phased_mob.dm b/code/game/objects/effects/phased_mob.dm index 357e9683072..69fe4cb2250 100644 --- a/code/game/objects/effects/phased_mob.dm +++ b/code/game/objects/effects/phased_mob.dm @@ -1,16 +1,22 @@ /obj/effect/dummy/phased_mob - name = "water" + name = "ethereal form" anchored = TRUE flags_1 = PREVENT_CONTENTS_EXPLOSION_1 resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | SHUTTLE_CRUSH_PROOF invisibility = INVISIBILITY_OBSERVER movement_type = FLOATING - /// The movable which's jaunting in this dummy + /// The movable which is jaunting in this dummy var/atom/movable/jaunter /// The delay between moves while jaunted var/movedelay = 0 /// The speed of movement while jaunted var/movespeed = 0 + /// Image we show to our jaunter so they can see where they are + var/image/position_indicator + /// Icon we draw our position indicator from + var/phased_mob_icon = 'icons/obj/weapons/guns/projectiles.dmi' + /// Icon state we use for our position indicator + var/phased_mob_icon_state = "ice_1" /obj/effect/dummy/phased_mob/Initialize(mapload, atom/movable/jaunter) . = ..() @@ -21,13 +27,25 @@ /obj/effect/dummy/phased_mob/proc/set_jaunter(atom/movable/new_jaunter) jaunter = new_jaunter jaunter.forceMove(src) - if(ismob(jaunter)) - var/mob/mob_jaunter = jaunter - RegisterSignal(mob_jaunter, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change)) - mob_jaunter.reset_perspective(src) + if(!ismob(jaunter)) + return + var/mob/mob_jaunter = jaunter + position_indicator = image(phased_mob_icon, src, phased_mob_icon_state, ABOVE_LIGHTING_PLANE) + position_indicator.appearance_flags |= RESET_ALPHA + SET_PLANE_EXPLICIT(position_indicator, ABOVE_LIGHTING_PLANE, src) + RegisterSignal(mob_jaunter, COMSIG_MOB_LOGIN, PROC_REF(show_client_image)) + RegisterSignal(mob_jaunter, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change)) + mob_jaunter.reset_perspective(src) + show_client_image(mob_jaunter) + +/// Displays our position indicator to a client +/obj/effect/dummy/phased_mob/proc/show_client_image(mob/show_to) + SIGNAL_HANDLER + show_to.client?.images |= position_indicator /obj/effect/dummy/phased_mob/Destroy() jaunter = null // If a mob was left in the jaunter on qdel, they'll be dumped into nullspace + position_indicator = null return ..() /// Removes [jaunter] from our phased mob @@ -57,6 +75,7 @@ . = ..() if(gone == jaunter) UnregisterSignal(jaunter, COMSIG_MOB_STATCHANGE) + UnregisterSignal(jaunter, COMSIG_MOB_LOGIN) SEND_SIGNAL(src, COMSIG_MOB_EJECTED_FROM_JAUNT, jaunter) jaunter = null diff --git a/code/modules/antagonists/heretic/magic/ash_jaunt.dm b/code/modules/antagonists/heretic/magic/ash_jaunt.dm index 41242063a90..4db891a38c7 100644 --- a/code/modules/antagonists/heretic/magic/ash_jaunt.dm +++ b/code/modules/antagonists/heretic/magic/ash_jaunt.dm @@ -18,6 +18,7 @@ jaunt_duration = 1.1 SECONDS jaunt_in_time = 1.3 SECONDS jaunt_out_time = 0.6 SECONDS + jaunt_type = /obj/effect/dummy/phased_mob/spell_jaunt/red jaunt_in_type = /obj/effect/temp_visual/dir_setting/ash_shift jaunt_out_type = /obj/effect/temp_visual/dir_setting/ash_shift/out diff --git a/code/modules/antagonists/heretic/magic/space_crawl.dm b/code/modules/antagonists/heretic/magic/space_crawl.dm index 74b02c59c10..6a170247937 100644 --- a/code/modules/antagonists/heretic/magic/space_crawl.dm +++ b/code/modules/antagonists/heretic/magic/space_crawl.dm @@ -18,6 +18,8 @@ invocation_type = INVOCATION_NONE spell_requirements = NONE + + jaunt_type = /obj/effect/dummy/phased_mob/spell_jaunt/space ///List of traits that are added to the heretic while in space phase jaunt var/static/list/jaunting_traits = list(TRAIT_RESISTLOWPRESSURE, TRAIT_RESISTCOLD, TRAIT_NOBREATH) @@ -138,4 +140,8 @@ . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) +/// Different graphic for position indicator +/obj/effect/dummy/phased_mob/spell_jaunt/space + phased_mob_icon_state = "solarflare" + #undef SPACE_PHASING diff --git a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm index ea9cdc27a44..56fcc898767 100644 --- a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm +++ b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm @@ -14,6 +14,8 @@ spell_requirements = NONE + jaunt_type = /obj/effect/dummy/phased_mob/blood + /// The time it takes to enter blood var/enter_blood_time = 0 SECONDS /// The time it takes to exit blood @@ -375,3 +377,7 @@ /obj/item/bloodcrawl/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + +/// Different graphic for the position indicator +/obj/effect/dummy/phased_mob/blood + phased_mob_icon_state = "mini_leaper" diff --git a/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm b/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm index e020ec1d5b1..6592660474e 100644 --- a/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm +++ b/code/modules/spells/spell_types/jaunt/ethereal_jaunt.dm @@ -153,6 +153,7 @@ cast_on.setDir(holder.dir) if(jaunt_in_time > 0) + cast_on.Immobilize(jaunt_in_time, ignore_canstun = TRUE) addtimer(CALLBACK(src, PROC_REF(end_jaunt), cast_on, holder, final_point), jaunt_in_time) else end_jaunt(cast_on, holder, final_point) @@ -219,6 +220,7 @@ jaunt_duration = 5 SECONDS jaunt_in_time = 0.6 SECONDS jaunt_out_time = 0.6 SECONDS + jaunt_type = /obj/effect/dummy/phased_mob/spell_jaunt/red jaunt_in_type = /obj/effect/temp_visual/dir_setting/wraith jaunt_out_type = /obj/effect/temp_visual/dir_setting/wraith/out @@ -238,6 +240,7 @@ /datum/action/cooldown/spell/jaunt/ethereal_jaunt/shift/golem name = "Runic Phase Shift" cooldown_time = 80 SECONDS + jaunt_type = /obj/effect/dummy/phased_mob/spell_jaunt/red jaunt_in_type = /obj/effect/temp_visual/dir_setting/cult/phase jaunt_out_type = /obj/effect/temp_visual/dir_setting/cult/phase/out @@ -257,3 +260,7 @@ if (locate(/obj/effect/blessing) in .) to_chat(user, span_warning("Holy energies block your path!")) return null + +/// Red coloured variant +/obj/effect/dummy/phased_mob/spell_jaunt/red + phased_mob_icon_state = "red_1" diff --git a/code/modules/spells/spell_types/jaunt/shadow_walk.dm b/code/modules/spells/spell_types/jaunt/shadow_walk.dm index c869fb19913..33215acb1e9 100644 --- a/code/modules/spells/spell_types/jaunt/shadow_walk.dm +++ b/code/modules/spells/spell_types/jaunt/shadow_walk.dm @@ -53,6 +53,7 @@ /obj/effect/dummy/phased_mob/shadow name = "shadows" + phased_mob_icon_state = "purple_laser" /// Max amount of light permitted before being kicked out var/light_max = SHADOW_SPECIES_LIGHT_THRESHOLD /// The amount that shadow heals us per SSobj tick (times seconds_per_tick)