From e46db9941284f0912ded4a7ccb152662ea1d6787 Mon Sep 17 00:00:00 2001 From: grungussuss <96586172+Sadboysuss@users.noreply.github.com> Date: Sun, 29 Dec 2024 10:53:55 +0300 Subject: [PATCH] airlocks and computers are leanable (#88478) ## About The Pull Request - added a signal - `COMSIG_ATOM_DENSITY_CHANGED`, is sent when set_density is called and doesn't early return - changed all manual assignments of .density to use `set_density` so the signal is sent - airlocks get the leanable component, if the airlock opens while you are leaning on it - you will fall - computers get the leanable component ## Why It's Good For The Game can lean on more stuff, roleplay! Immersion! *John Tider leans on the airlock* ## Changelog :cl: grungussuss add: computers and airlocks are now leanable refactor: changed how density/collision of some objects is changed, report any oddities! /:cl: --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> --- .../signals/signals_atom/signals_atom_main.dm | 3 ++ code/datums/components/ground_sinking.dm | 4 +-- code/datums/components/leanable.dm | 31 ++++++++++++++++++- code/game/atom/_atom.dm | 2 +- code/game/machinery/airlock_control.dm | 8 +++++ code/game/machinery/computer/_computer.dm | 5 +++ code/game/machinery/doors/airlock.dm | 4 +-- code/game/machinery/modular_shield.dm | 2 +- .../heretic/status_effects/buffs.dm | 2 +- .../vehicles/mecha/combat/savannah_ivanov.dm | 4 +-- 10 files changed, 55 insertions(+), 10 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index 2e42957aa3a..586a67e2395 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -145,3 +145,6 @@ /// From whoever has been revealed (atom/revealed) #define COMSIG_ATOM_REVEAL "atom_reveal" + +/// From /atom/proc/set_density(new_value) for when an atom changes density +#define COMSIG_ATOM_DENSITY_CHANGED "atom_density_change" diff --git a/code/datums/components/ground_sinking.dm b/code/datums/components/ground_sinking.dm index d29e84908a4..4e846b4cf70 100644 --- a/code/datums/components/ground_sinking.dm +++ b/code/datums/components/ground_sinking.dm @@ -99,7 +99,7 @@ /datum/component/ground_sinking/proc/finish_sinking(mob/living/basic/living_target) sinked = TRUE is_sinking = FALSE - living_target.density = FALSE + living_target.set_density(FALSE) living_target.damage_coeff = damage_res_sinked if(heal_when_sinked) start_regenerating() @@ -113,7 +113,7 @@ stop_regenerating() living_target.icon_state = target_icon_state living_target.damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) - living_target.density = TRUE + living_target.set_density(TRUE) sinked = FALSE /// The mop starts regaining health diff --git a/code/datums/components/leanable.dm b/code/datums/components/leanable.dm index b823cf5ec50..bc0994dcdcd 100644 --- a/code/datums/components/leanable.dm +++ b/code/datums/components/leanable.dm @@ -4,6 +4,8 @@ var/leaning_offset = 11 /// List of mobs currently leaning on our parent var/list/leaning_mobs = list() + /// Is this object currently leanable? + var/is_currently_leanable = TRUE /datum/component/leanable/Initialize(mob/living/leaner, leaning_offset = 11) . = ..() @@ -13,15 +15,32 @@ /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/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_MOUSEDROPPED_ONTO, COMSIG_MOVABLE_MOVED)) /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) leaner.stop_leaning() + if(fall) + to_chat(leaner, span_danger("You lose balance!")) + leaner.Paralyze(0.5 SECONDS) leaning_mobs = null - return ..() /datum/component/leanable/proc/on_moved(datum/source) SIGNAL_HANDLER @@ -42,6 +61,8 @@ var/turf/checked_turf = get_step(leaner, REVERSE_DIR(leaner.dir)) if (checked_turf != get_turf(source)) return + if(!is_currently_leanable) + return COMPONENT_CANCEL_MOUSEDROPPED_ONTO leaner.start_leaning(source, leaning_offset) leaning_mobs += leaner RegisterSignals(leaner, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING), PROC_REF(stopped_leaning)) @@ -118,3 +139,11 @@ if (old_dir != new_dir) INVOKE_ASYNC(src, PROC_REF(stop_leaning)) + +/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() diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index c8c3111889e..a7d057aa9fa 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -722,7 +722,7 @@ return . = density density = new_value - + SEND_SIGNAL(src, COMSIG_ATOM_DENSITY_CHANGED) ///Setter for the `base_pixel_x` variable to append behavior related to its changing. /atom/proc/set_base_pixel_x(new_value) diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 9e089eeaf2b..3b01c40403d 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -6,6 +6,14 @@ var/airlock_state var/frequency + +/obj/machinery/door/airlock/mouse_drop_receive(mob/living/dropping, mob/user, params) + . = ..() + // We add the component only once here & not in Initialize() because there are tons of airlocks & we don't want to add to their init times + // This is on airlock rather than on door because windoors are door and leaning looks whack on windoors + LoadComponent(/datum/component/leanable, dropping) + + /// Forces the airlock to unbolt and open /obj/machinery/door/airlock/proc/secure_open() locked = FALSE diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index d51e197a0bc..6aa33683412 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -30,6 +30,11 @@ . = ..() power_change() +/obj/machinery/computer/mouse_drop_receive(mob/living/dropping, mob/user, params) + . = ..() + // We add the component only once here & not in Initialize() because there are tons of computers & we don't want to add to their init times + LoadComponent(/datum/component/leanable, dropping) + /obj/machinery/computer/CanAllowThrough(atom/movable/mover, border_dir) // allows projectiles to fly over the computer . = ..() if(.) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d57714c1cf3..b562713fe37 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1355,7 +1355,7 @@ if(air_tight) set_density(TRUE) if(multi_tile) - filler.density = TRUE + filler.set_density(TRUE) flags_1 |= PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, TRUE) var/unpassable_delay = animation_segment_delay(AIRLOCK_CLOSING_UNPASSABLE) @@ -1363,7 +1363,7 @@ if(!air_tight) set_density(TRUE) if(multi_tile) - filler.density = TRUE + filler.set_density(TRUE) flags_1 |= PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, TRUE) var/opaque_delay = animation_segment_delay(AIRLOCK_CLOSING_OPAQUE) - unpassable_delay diff --git a/code/game/machinery/modular_shield.dm b/code/game/machinery/modular_shield.dm index b4fa6bed17b..2e8fa632e42 100644 --- a/code/game/machinery/modular_shield.dm +++ b/code/game/machinery/modular_shield.dm @@ -240,7 +240,7 @@ /obj/machinery/modular_shield_generator/proc/finish_field() for(var/obj/structure/emergency_shield/modular/current_shield in deployed_shields) - current_shield.density = TRUE + current_shield.set_density(TRUE) current_shield.alpha = 255 initiating = FALSE diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm index 362e9750b49..d42626871bb 100644 --- a/code/modules/antagonists/heretic/status_effects/buffs.dm +++ b/code/modules/antagonists/heretic/status_effects/buffs.dm @@ -284,7 +284,7 @@ /datum/status_effect/caretaker_refuge/on_apply() animate(owner, alpha = 45,time = 0.5 SECONDS) - owner.density = FALSE + owner.set_density(FALSE) RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost)) RegisterSignal(owner, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(prevent_spell_usage)) RegisterSignal(owner, COMSIG_ATOM_HOLYATTACK, PROC_REF(nullrod_handler)) diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm index dfcf2896b5b..6395b39393e 100644 --- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm +++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm @@ -145,7 +145,7 @@ chassis.mecha_flags |= QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT chassis.phasing = "flying" chassis.movedelay = 1 - chassis.density = FALSE + chassis.set_density(FALSE) chassis.layer = ABOVE_ALL_MOB_LAYER animate(chassis, alpha = 0, time = 8, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_PARALLEL) animate(chassis, pixel_z = 400, time = 10, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_PARALLEL) //Animate our rising mech (just like pods hehe) @@ -176,7 +176,7 @@ chassis.mecha_flags &= ~(QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT) chassis.phasing = initial(chassis.phasing) chassis.movedelay = initial(chassis.movedelay) - chassis.density = TRUE + chassis.set_density(TRUE) chassis.layer = initial(chassis.layer) SET_PLANE(chassis, initial(chassis.plane), landed_on) skyfall_charge_level = 0