mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-16 12:43:09 +00:00
## About The Pull Request This PR adds an element, for now added to water turfs, that gives passing movables an overlay to make them look immersed in that turf. You can definitely see in the code what sort of stupid stuff I've had to do to work around some of the flaws with the inbuilt features. Why? Because I needed a (vis_contents) overlay that: - can cover the entire width of the movable it's added to, whether it has a 32 px icon, 64, 96 etc, plus some to be safe. - doesn't look misplaced around movables with an icon larger than 32 px. - can be animated, so it doesn't rotate or scale (or rather, do so but in the opposite direction) with living mobs when resized, spinning or lying down or standing up, despite the KEEP_TOGETHER appearance flag, which ignores whether the overlay has the RESET_TRANSFORM flag. - looks inset in the movable and doesn't spill into other movables of the same plane (that's what happened with normal inset overlays without the KEEP_TOGETHER flag) - doesn't render above other movables covering the owner of the overlay. If someone comes with a better and tested solution, go and tell I guess. How visuals are handled by this engine still eludes me at times, but I doubt planes would be a better solution to this. The rest of the PR includes checks to make sure the overlay isn't added to movables with planes lower/higher than FLOOR_PLANE/ABOVE_ALL_MOB_PLANE, that are flying or being thrown, as well as certain types such as effects. ## Why It's Good For The Game Adding some literal immersion to the game, since movables and mobs look like they're treading on water like Jesus right now. You can see a couple screenshots by scrolling down a little. ## Changelog 🆑 image: walking on water will now immerse you in it... visually, at least. /🆑
103 lines
4.2 KiB
Plaintext
103 lines
4.2 KiB
Plaintext
#define CLICKBOX_LAYER FLOAT_LAYER-999
|
|
|
|
/**
|
|
* This component adds a near-invisible underlay to a movable target to expand the clickable surface of its icon without
|
|
* resorting to MOUSE_OPACITY_OPAQUE.
|
|
* The underlay ignores the parent's color and alpha and can be offset.
|
|
* The name is a portmanteau of "click" and "hitbox", because technically this isn't an hitbox,
|
|
* but it helps catch clicks, and I don't want to give it a loooong name like openspace_item_click_handler
|
|
*/
|
|
/datum/component/clickbox
|
|
dupe_mode = COMPONENT_DUPE_ALLOWED
|
|
/// The icon state of the underlay.
|
|
var/icon_state = "sphere"
|
|
/// The offsets of the underlay.
|
|
var/x_offset = 0
|
|
var/y_offset = 0
|
|
/// Maximum width/height of the underlay, in case the attached atom is scaled up.
|
|
var/max_scale = 2
|
|
/// Minimum width/height of the underlay, in case the attached atom is scaled down.
|
|
var/min_scale = 0.5
|
|
/// For simple animals that have different icon states when dead.
|
|
var/dead_state
|
|
/// the underlay that has been added to the parent.
|
|
var/mutable_appearance/clickbox_underlay
|
|
|
|
/datum/component/clickbox/Initialize(icon_state = "sphere", x_offset = 0, y_offset = 0, max_scale = 2, min_scale = 0.5, dead_state)
|
|
if(!isatom(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.icon_state = icon_state
|
|
src.x_offset = x_offset
|
|
src.y_offset = y_offset
|
|
src.max_scale = max_scale
|
|
src.min_scale = min_scale
|
|
|
|
RegisterSignal(parent, COMSIG_ATOM_VV_MODIFY_TRANSFORM, PROC_REF(on_vv_modify_transform))
|
|
|
|
var/clickbox_icon_state = icon_state
|
|
if(isliving(parent))
|
|
var/mob/living/living_parent = parent
|
|
RegisterSignal(living_parent, COMSIG_LIVING_POST_UPDATE_TRANSFORM, PROC_REF(on_update_transform))
|
|
if(dead_state)
|
|
src.dead_state = dead_state
|
|
RegisterSignal(living_parent, COMSIG_LIVING_DEATH, PROC_REF(on_death))
|
|
RegisterSignal(living_parent, COMSIG_LIVING_REVIVE, PROC_REF(on_revive))
|
|
if(living_parent.stat == DEAD)
|
|
clickbox_icon_state = dead_state
|
|
|
|
update_underlay(clickbox_icon_state)
|
|
|
|
/datum/component/clickbox/UnregisterFromParent()
|
|
var/atom/movable/mov_parent = parent
|
|
UnregisterSignal(mov_parent, list(COMSIG_ATOM_VV_MODIFY_TRANSFORM, COMSIG_LIVING_POST_UPDATE_TRANSFORM, COMSIG_LIVING_DEATH, COMSIG_LIVING_REVIVE))
|
|
mov_parent.underlays -= clickbox_underlay
|
|
|
|
/// Removes the old underlay and adds a new one. The underlay is scaled up/down if necessary
|
|
/datum/component/clickbox/proc/update_underlay(clickbox_icon_state, width, height)
|
|
var/atom/movable/mov_parent = parent
|
|
if(!clickbox_icon_state)
|
|
clickbox_icon_state = clickbox_underlay?.icon_state || icon_state
|
|
mov_parent.underlays -= clickbox_underlay // Remove the previous underlay.
|
|
|
|
var/clickbox_width = 1
|
|
var/abs_width = abs(width) //Taking into account inverted transform values.
|
|
if(abs_width > max_scale)
|
|
clickbox_width = max_scale/width
|
|
else if(abs_width && abs_width < min_scale)
|
|
clickbox_width = min_scale/width
|
|
|
|
var/clickbox_height = 1
|
|
var/abs_height = abs(height) //Ditto
|
|
if(abs_height > max_scale)
|
|
clickbox_height = max_scale/height
|
|
else if(abs_height && abs_height < min_scale)
|
|
clickbox_height = min_scale/height
|
|
|
|
clickbox_underlay = mutable_appearance('icons/misc/clickbox.dmi', clickbox_icon_state, CLICKBOX_LAYER, alpha = 1, appearance_flags = RESET_COLOR|RESET_ALPHA)
|
|
clickbox_underlay.transform = clickbox_underlay.transform.Scale(clickbox_width, clickbox_height)
|
|
//Keeps the underlay more or less centered.
|
|
clickbox_underlay.pixel_x = x_offset * 1/clickbox_width
|
|
clickbox_underlay.pixel_y = y_offset * 1/clickbox_height
|
|
mov_parent.underlays += clickbox_underlay
|
|
|
|
/datum/component/clickbox/proc/on_vv_modify_transform(atom/source)
|
|
SIGNAL_HANDLER
|
|
var/width = source.transform.a
|
|
var/height = source.transform.e
|
|
update_underlay(clickbox_underlay.icon_state, width, height)
|
|
|
|
/datum/component/clickbox/proc/on_update_transform(mob/living/source, previous_size)
|
|
SIGNAL_HANDLER
|
|
update_underlay(clickbox_underlay.icon_state , source.current_size, source.current_size)
|
|
|
|
/datum/component/clickbox/proc/on_death(mob/living/source)
|
|
SIGNAL_HANDLER
|
|
update_underlay(dead_state, source.current_size, source.current_size)
|
|
|
|
/datum/component/clickbox/proc/on_revive(mob/living/source)
|
|
SIGNAL_HANDLER
|
|
update_underlay(icon_state, source.current_size, source.current_size)
|
|
|
|
#undef CLICKBOX_LAYER
|