Makes your current position clearer while jaunting (#90173)

## About The Pull Request

I was fucking around testing the Voidwalker earlier for a different
issue and didn't like that I couldn't see myself while in space.
This PR makes it so that Voidwalkers and also any variant of Ethereal
Jaunt place an icon visible only to you at your current position (it's
like your _soul_) so that you can see where you are going.
Nobody else can see it.


![dreamseeker_qCXrCwHaUW](https://github.com/user-attachments/assets/3d6d1136-1658-4701-af78-057b2cfeb059)

![dreamseeker_hqH73zu66P](https://github.com/user-attachments/assets/4f620711-9a1a-4f8e-be3b-1c3367b9f9dc)



There are almost certainly some other sources of being invisible which
could use this so let me know if you are aware of one.
Although if you do that I may need to make my code more generic.

## Why It's Good For The Game

It's nice to be able to see where you are precisely rather than just it
being the centre of the screen

## Changelog

🆑
qol: It is now easier to see where you currently are while jaunting
/🆑
This commit is contained in:
Jacquerel
2025-03-23 20:00:23 +01:00
committed by GitHub
parent c370a1a0fa
commit ce669c3924
8 changed files with 93 additions and 8 deletions
+46 -2
View File
@@ -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
+1
View File
@@ -82,3 +82,4 @@
/obj/effect/dummy/phased_mob/space_dive
movespeed = 1
phased_mob_icon_state = "solarflare"
+25 -6
View File
@@ -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
@@ -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
@@ -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
@@ -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"
@@ -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"
@@ -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)