mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-11 16:07:36 +01:00
483674ac59
fixes #22249 - bugfix: "Leaning on the north side of a wall now correctly hides your lower body behind the wall instead of drawing you on top of it." - code_imp: "Adds a COMSIG_MOB_LYING_DOWN signal, sent when a mob transitions into lying down." Cutout was previously only cutting out the base because KEEP_TOGETHER wasn't being applied. Adds the flag on lean, removes it on stop_lean. Animated the cutout while here. Applies a mask to the whole sprite, then animates it upwards in step with the lean itself, so the feet progressively disappear as they should. https://github.com/user-attachments/assets/fec0a852-247a-4570-a6d1-60dda6fe6a3c
142 lines
4.5 KiB
Plaintext
142 lines
4.5 KiB
Plaintext
/// Things with this component can be leaned onto
|
|
/datum/component/leanable
|
|
/// How much will mobs that lean onto this object be offset
|
|
var/leaning_offset = 11
|
|
/// List of mobs currently leaning on our parent
|
|
var/list/leaning_mobs
|
|
/// Is this object currently leanable?
|
|
var/is_currently_leanable = TRUE
|
|
|
|
/datum/component/leanable/Initialize(mob/living/leaner, leaning_offset = 11)
|
|
. = ..()
|
|
src.leaning_offset = leaning_offset
|
|
mousedrop_receive(parent, leaner, leaner)
|
|
|
|
/datum/component/leanable/RegisterWithParent()
|
|
RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
|
RegisterSignal(parent, COMSIG_ATOM_DENSITY_CHANGED, PROC_REF(on_density_change))
|
|
var/atom/leanable_atom = parent
|
|
is_currently_leanable = leanable_atom.density
|
|
|
|
/datum/component/leanable/UnregisterFromParent()
|
|
. = ..()
|
|
UnregisterSignal(parent, list(
|
|
COMSIG_MOVABLE_MOVED,
|
|
COMSIG_MOUSEDROPPED_ONTO,
|
|
COMSIG_ATOM_DENSITY_CHANGED,
|
|
))
|
|
|
|
/datum/component/leanable/Destroy(force)
|
|
stop_leaning_leaners()
|
|
return ..()
|
|
|
|
/datum/component/leanable/proc/stop_leaning_leaners(fall)
|
|
for (var/mob/living/leaner as anything in leaning_mobs)
|
|
if(fall)
|
|
leaner.visible_message(SPAN_WARNING("[leaner] loses their balance!"), SPAN_DANGER("You lose balance!"))
|
|
leaner.Weaken(rand(3,5))
|
|
leaner.stop_leaning()
|
|
LAZYCLEARLIST(leaning_mobs)
|
|
|
|
/datum/component/leanable/proc/on_moved(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
for (var/mob/living/leaner as anything in leaning_mobs)
|
|
leaner.stop_leaning()
|
|
|
|
/datum/component/leanable/proc/mousedrop_receive(atom/source, atom/movable/dropped, mob/user, params)
|
|
if (dropped != user)
|
|
return
|
|
if (!iscarbon(dropped))
|
|
return
|
|
var/mob/living/leaner = dropped
|
|
var/can_lean = TRUE
|
|
|
|
if (HAS_TRAIT_FROM(leaner, TRAIT_UNDENSE, TRAIT_LEANING))
|
|
return
|
|
|
|
if(istype(leaner.l_hand, /obj/item/grab) || istype(leaner.r_hand, /obj/item/grab))
|
|
can_lean = FALSE
|
|
if(leaner.incapacitated())
|
|
can_lean = FALSE
|
|
if(leaner.resting)
|
|
can_lean = FALSE
|
|
if(leaner.buckled_to)
|
|
can_lean = FALSE
|
|
|
|
if(!is_currently_leanable || !can_lean)
|
|
return COMPONENT_CANCEL_MOUSEDROPPED_ONTO
|
|
leaner.start_leaning(source, leaning_offset)
|
|
LAZYADD(leaning_mobs, leaner)
|
|
RegisterSignals(leaner, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING), PROC_REF(stopped_leaning), override = TRUE)
|
|
return COMPONENT_CANCEL_MOUSEDROPPED_ONTO
|
|
|
|
/**
|
|
* Makes the mob lean on an atom
|
|
* Arguments
|
|
*
|
|
* * atom/lean_target - the target the mob is trying to lean on
|
|
* * leaning_offset - pixel offset to apply on the mob when leaning
|
|
*/
|
|
/mob/living/proc/start_leaning(atom/lean_target, leaning_offset)
|
|
var/direction = get_dir(lean_target, src)
|
|
var/shift_pixel_x = 0
|
|
var/shift_pixel_y = 0
|
|
set_dir(direction)
|
|
switch(dir)
|
|
if(NORTH)
|
|
shift_pixel_y = -10
|
|
if(SOUTH)
|
|
shift_pixel_y = 16
|
|
if(EAST)
|
|
shift_pixel_x = -10
|
|
if(WEST)
|
|
shift_pixel_x = 10
|
|
animate(src, pixel_x = shift_pixel_x, pixel_y = shift_pixel_y, time = 1)
|
|
if(direction == NORTH)
|
|
src.appearance_flags |= KEEP_TOGETHER
|
|
src.add_filter("cutout", 1, alpha_mask_filter(y = 0, icon = icon('icons/effects/effects.dmi', "white")))
|
|
animate(src.get_filter("cutout"), y = 10, time = 1, flags = ANIMATION_PARALLEL)
|
|
if(direction == SOUTH)
|
|
src.layer = ABOVE_DOOR_LAYER
|
|
set_density(FALSE)
|
|
ADD_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_WALL_LEANING)
|
|
ADD_TRAIT(src, TRAIT_LEANING, TRAIT_SOURCE_WALL_LEANING)
|
|
visible_message(
|
|
SPAN_NOTICE("[src] leans against [lean_target]."),
|
|
SPAN_NOTICE("You lean against [lean_target]."),
|
|
)
|
|
RegisterSignals(src, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_RESISTED, COMSIG_MOB_LYING_DOWN), PROC_REF(stop_leaning), src)
|
|
|
|
/mob/living/proc/stop_leaning()
|
|
SIGNAL_HANDLER
|
|
set_density(TRUE)
|
|
pixel_x = initial(pixel_x)
|
|
pixel_y = initial(pixel_y)
|
|
layer = initial(layer)
|
|
UnregisterSignal(src, list(
|
|
COMSIG_MOVABLE_MOVED,
|
|
COMSIG_MOB_RESISTED,
|
|
COMSIG_MOB_LYING_DOWN,
|
|
))
|
|
SEND_SIGNAL(src, COMSIG_LIVING_STOPPED_LEANING)
|
|
to_chat(src, SPAN_NOTICE("You stop leaning on the wall."))
|
|
REMOVE_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_WALL_LEANING)
|
|
REMOVE_TRAIT(src, TRAIT_LEANING, TRAIT_SOURCE_WALL_LEANING)
|
|
appearance_flags &= ~KEEP_TOGETHER
|
|
remove_filter("cutout")
|
|
|
|
/datum/component/leanable/proc/stopped_leaning(datum/source)
|
|
SIGNAL_HANDLER
|
|
LAZYREMOVE(leaning_mobs, source)
|
|
UnregisterSignal(source, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING))
|
|
|
|
/datum/component/leanable/proc/on_density_change()
|
|
SIGNAL_HANDLER
|
|
is_currently_leanable = !is_currently_leanable
|
|
if(!is_currently_leanable)
|
|
stop_leaning_leaners(fall = TRUE)
|
|
return
|
|
stop_leaning_leaners()
|