Files
Bubberstation/code/datums/components/seethrough_mob.dm
IndieanaJones ed51898942 Replaces Big Mob Tiny Sprites With Togglable Clientside Transparency For Big Mobs (#77361)
## About The Pull Request

This PR replaces the tiny mob sprite abilities for our large mobs with a
Toggle Seethrough ability. What this does when enabled is make yourself
transparent on your own client and makes you unable to click yourself.
With this, any sort of overlays that get added look correct while in
your tiny mob form and you can still appreciate your large size without
giving up the ability to click on targets that would be hiding
underneath your sprite.


![XenoQueen](https://github.com/tgstation/tgstation/assets/47086570/537b7db7-84fd-4202-955f-c5d2bec830c0)


![image](https://github.com/tgstation/tgstation/assets/47086570/1f9272f0-a972-407f-9031-ee87bbc67ead)

In total, this ability is granted to all the mobs who had tiny sprites:

- Xenomorph Queen
- Space Dragon
- Megafauna (not that players ever get access to these normally, but it
might be nice for admins)

Along with all this, I've also gone and expanded the mobs who get access
to the Seethrough ability to mobs that are large but didn't have a
mini-sprite. This includes:

- Jungle giants (leaper and mega arachnid)
- Tree mob
- Festivus pole mob
- Lavaland elites
- Xenomorph Praetorian
- Wumborian Fugu

On top of all this, any simple/basic mob given a fugu gland also
automatically gains this ability.

This solution also fixes all the overlays bugs that tiny mob sprites
introduced to the game, most notably the xenomorph queen overlays being
screwy when in small form and space dragon's overlays being completely
disabled for everyone if he was in small form.

The only issue with this currently is that clicking on any overlays from
your mob will let you still click on yourself, though this issue is
pretty negligible.

## Why It's Good For The Game

Tiny mob sprite abilities clashed very hard with our overlay system,
leading to a lot of buggy and unintended behavior. This replacement
works a lot more smoothly with overlays and also requires much less
setup to give it to a mob than tiny sprites did. I would also imagine it
helps keep the fantasy of being a big monster alive by letting you still
see yourself being a big monster without it getting in your way when
trying to attack things.

## Changelog
🆑
del: Removed tiny mob sprite abilities for large mobs
add: Add a Self Seethrough ability, given to most large mobs and all
mobs affected by a fugu gland
fix: Space Dragon's overlay will no longer vanish at times

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2023-08-17 07:20:38 +02:00

136 lines
4.5 KiB
Plaintext

///A component that lets you turn your character transparent in order to see and click through yourself.
/datum/component/seethrough_mob
///The atom that enables our dark magic
var/atom/movable/render_source_atom
///The fake version of ourselves
var/image/trickery_image
///Which alpha do we animate towards?
var/target_alpha
///How long our faze in/out takes
var/animation_time
///Does this object let clicks from players its transparent to pass through it
var/clickthrough
///Is the seethrough effect currently active
var/is_active
///The mob's original render_target value
var/initial_render_target_value
///This component's personal uid
var/personal_uid
/datum/component/seethrough_mob/Initialize(target_alpha = 100, animation_time = 0.5 SECONDS, clickthrough = TRUE)
. = ..()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
src.target_alpha = target_alpha
src.animation_time = animation_time
src.clickthrough = clickthrough
src.is_active = FALSE
src.render_source_atom = new()
var/static/uid = 0
uid++
src.personal_uid = uid
render_source_atom.appearance_flags |= ( RESET_COLOR | RESET_TRANSFORM)
render_source_atom.vis_flags |= (VIS_INHERIT_ID | VIS_INHERIT_PLANE | VIS_INHERIT_LAYER)
render_source_atom.render_source = "*transparent_bigmob[personal_uid]"
var/datum/action/toggle_seethrough/action = new(src)
action.Grant(parent)
/datum/component/seethrough_mob/Destroy(force, silent)
QDEL_NULL(render_source_atom)
return ..()
///Set up everything we need to trick the client and keep it looking normal for everyone else
/datum/component/seethrough_mob/proc/trick_mob()
SIGNAL_HANDLER
var/mob/fool = parent
var/datum/hud/our_hud = fool.hud_used
for(var/atom/movable/screen/plane_master/seethrough as anything in our_hud.get_true_plane_masters(SEETHROUGH_PLANE))
seethrough.unhide_plane(fool)
var/icon/current_mob_icon = icon(fool.icon, fool.icon_state)
render_source_atom.pixel_x = -fool.pixel_x
render_source_atom.pixel_y = ((current_mob_icon.Height() - 32) * 0.5)
initial_render_target_value = fool.render_target
fool.render_target = "*transparent_bigmob[personal_uid]"
fool.vis_contents.Add(render_source_atom)
trickery_image = new(render_source_atom)
trickery_image.loc = render_source_atom
trickery_image.override = TRUE
trickery_image.pixel_x = 0
trickery_image.pixel_y = 0
if(clickthrough)
//Special plane so we can click through the overlay
SET_PLANE_EXPLICIT(trickery_image, SEETHROUGH_PLANE, fool)
fool.client.images += trickery_image
animate(trickery_image, alpha = target_alpha, time = animation_time)
RegisterSignal(fool, COMSIG_MOB_LOGOUT, PROC_REF(on_client_disconnect))
///Remove the screen object and make us appear solid to ourselves again
/datum/component/seethrough_mob/proc/untrick_mob()
var/mob/fool = parent
animate(trickery_image, alpha = 255, time = animation_time)
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)
//after playing the fade-in animation, remove the image and the trick atom
addtimer(CALLBACK(src, PROC_REF(clear_image), trickery_image, fool.client), animation_time)
///Remove the image and the trick atom
/datum/component/seethrough_mob/proc/clear_image(image/removee, client/remove_from)
var/atom/movable/atom_parent = parent
atom_parent.vis_contents -= render_source_atom
atom_parent.render_target = initial_render_target_value
remove_from?.images -= removee
///Effect is disabled when they log out because client gets deleted
/datum/component/seethrough_mob/proc/on_client_disconnect()
SIGNAL_HANDLER
var/mob/fool = parent
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)
var/datum/hud/our_hud = fool.hud_used
for(var/atom/movable/screen/plane_master/seethrough as anything in our_hud.get_true_plane_masters(SEETHROUGH_PLANE))
seethrough.hide_plane(fool)
clear_image(trickery_image, fool.client)
/datum/component/seethrough_mob/proc/toggle_active()
is_active = !is_active
if(is_active)
trick_mob()
else
untrick_mob()
/datum/action/toggle_seethrough
name = "Toggle Seethrough"
desc = "Allows you to see behind your massive body and click through it."
button_icon = 'icons/mob/actions/actions_xeno.dmi'
button_icon_state = "alien_sneak"
background_icon_state = "bg_alien"
/datum/action/toggle_seethrough/Remove(mob/remove_from)
var/datum/component/seethrough_mob/seethroughComp = target
if(seethroughComp.is_active)
seethroughComp.untrick_mob()
return ..()
/datum/action/toggle_seethrough/Trigger(trigger_flags)
. = ..()
if(!.)
return
var/datum/component/seethrough_mob/seethroughComp = target
seethroughComp.toggle_active()