From 7fe8f29fdbd22283cd49f762cd5b7344dfe0acf4 Mon Sep 17 00:00:00 2001 From: Y0SH1M4S73R Date: Tue, 14 Jan 2025 09:50:03 -0500 Subject: [PATCH] Corpses with clients in them can no longer perform mech actions (#88959) ## About The Pull Request Turns out most mech actions only cared about the person attempting to use them being inside the mech, without checking for things such as the mob being alive. This fixes that, but required a slight refactoring to the `ui_status` proc of mechs to account for the three fundamentally different types of mobs that can pilot a mech. ## Why It's Good For The Game Fixes #88933 ## Changelog :cl: fix: Corpses at the pilot seat of mechs can no longer toggle the lights, safeties, cabin sealing, strafing, overclocking, or durand shields, nor can they rename the mech or configure its equipment. /:cl: --- code/modules/tgui/status_composers.dm | 12 +++++++- code/modules/vehicles/mecha/combat/durand.dm | 4 ++- .../modules/vehicles/mecha/combat/marauder.dm | 8 +++-- code/modules/vehicles/mecha/combat/phazon.dm | 8 +++-- .../vehicles/mecha/combat/savannah_ivanov.dm | 6 +++- code/modules/vehicles/mecha/mecha_actions.dm | 30 ++++++++++++++----- code/modules/vehicles/mecha/mecha_ui.dm | 22 ++++++++------ code/modules/vehicles/mecha/working/clarke.dm | 6 +++- code/modules/vehicles/mecha/working/ripley.dm | 2 ++ code/modules/vehicles/sealed.dm | 1 + 10 files changed, 74 insertions(+), 25 deletions(-) diff --git a/code/modules/tgui/status_composers.dm b/code/modules/tgui/status_composers.dm index c4bbb3e7bfc..4222769203b 100644 --- a/code/modules/tgui/status_composers.dm +++ b/code/modules/tgui/status_composers.dm @@ -50,7 +50,9 @@ /// Returns a UI status such that those without blocked hands will be able to interact, /// but everyone else can only watch. -/proc/ui_status_user_has_free_hands(mob/user, atom/source) +/proc/ui_status_user_has_free_hands(mob/user, atom/source, allowed_source) + if(allowed_source) + return HAS_TRAIT_NOT_FROM(user, TRAIT_HANDS_BLOCKED, allowed_source) ? UI_UPDATE : UI_INTERACTIVE return HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) ? UI_UPDATE : UI_INTERACTIVE /// Returns a UI status such that advanced tool users will be able to interact, @@ -110,3 +112,11 @@ return UI_CLOSE return UI_INTERACTIVE + +/// Return UI_INTERACTIVE if the user is inside the target atom, whether they can see it or not. +/// Return UI_CLOSE otherwise. +/proc/ui_status_user_inside(mob/user, atom/target) + if(target.contains(user)) + return UI_INTERACTIVE + + return UI_CLOSE diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm index 69952069429..9095197b93e 100644 --- a/code/modules/vehicles/mecha/combat/durand.dm +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -143,7 +143,9 @@ Expects a turf. Returns true if the attack should be blocked, false if not.*/ button_icon_state = "mech_defense_mode_off" /datum/action/vehicle/sealed/mecha/mech_defense_mode/Trigger(trigger_flags, forced_state = FALSE) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return SEND_SIGNAL(chassis, COMSIG_MECHA_ACTION_TRIGGER, owner, args) //Signal sent to the mech, to be handed to the shield. See durand.dm for more details diff --git a/code/modules/vehicles/mecha/combat/marauder.dm b/code/modules/vehicles/mecha/combat/marauder.dm index 32fd0627c6f..f0f9b7ebf81 100644 --- a/code/modules/vehicles/mecha/combat/marauder.dm +++ b/code/modules/vehicles/mecha/combat/marauder.dm @@ -59,7 +59,9 @@ button_icon_state = "mech_smoke" /datum/action/vehicle/sealed/mecha/mech_smoke/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_SMOKE) && chassis.smoke_charges>0) chassis.smoke_system.start() @@ -71,7 +73,9 @@ button_icon_state = "mech_zoom_off" /datum/action/vehicle/sealed/mecha/mech_zoom/Trigger(trigger_flags) - if(!owner?.client || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!owner.client || !chassis || !(owner in chassis.occupants)) return chassis.zoom_mode = !chassis.zoom_mode button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]" diff --git a/code/modules/vehicles/mecha/combat/phazon.dm b/code/modules/vehicles/mecha/combat/phazon.dm index 8f37b0945ec..1ff67996e79 100644 --- a/code/modules/vehicles/mecha/combat/phazon.dm +++ b/code/modules/vehicles/mecha/combat/phazon.dm @@ -42,7 +42,9 @@ button_icon_state = "mech_damtype_brute" /datum/action/vehicle/sealed/mecha/mech_switch_damtype/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return var/new_damtype switch(chassis.damtype) @@ -65,7 +67,9 @@ button_icon_state = "mech_phasing_off" /datum/action/vehicle/sealed/mecha/mech_toggle_phasing/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.phasing = chassis.phasing ? "" : "phasing" button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm index 6395b39393e..ffc4c61e5a8 100644 --- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm +++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm @@ -81,6 +81,8 @@ var/skyfall_charge_level = 0 /datum/action/vehicle/sealed/mecha/skyfall/Trigger(trigger_flags) + if(!..()) + return if(!owner || !chassis || !(owner in chassis.occupants)) return if(chassis.phasing) @@ -251,7 +253,9 @@ return ..() /datum/action/vehicle/sealed/mecha/ivanov_strike/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(TIMER_COOLDOWN_RUNNING(chassis, COOLDOWN_MECHA_MISSILE_STRIKE)) var/timeleft = S_TIMER_COOLDOWN_TIMELEFT(chassis, COOLDOWN_MECHA_MISSILE_STRIKE) diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm index 5e3c658a525..7c85d047996 100644 --- a/code/modules/vehicles/mecha/mecha_actions.dm +++ b/code/modules/vehicles/mecha/mecha_actions.dm @@ -24,7 +24,7 @@ button_icon_state = "mech_eject" /datum/action/vehicle/sealed/mecha/mech_eject/Trigger(trigger_flags) - if(!owner) + if(!..()) return if(!chassis || !(owner in chassis.occupants)) return @@ -36,7 +36,9 @@ desc = "Airtight cabin preserves internal air and can be pressurized with a mounted air tank." /datum/action/vehicle/sealed/mecha/mech_toggle_cabin_seal/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.set_cabin_seal(owner, !chassis.cabin_sealed) @@ -45,7 +47,9 @@ button_icon_state = "mech_lights_off" /datum/action/vehicle/sealed/mecha/mech_toggle_lights/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.toggle_lights(user = owner) @@ -54,7 +58,9 @@ button_icon_state = "mech_view_stats" /datum/action/vehicle/sealed/mecha/mech_view_stats/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.ui_interact(owner) @@ -68,7 +74,9 @@ RegisterSignal(chassis, COMSIG_MECH_SAFETIES_TOGGLE, PROC_REF(update_action_icon)) /datum/action/vehicle/sealed/mecha/mech_toggle_safeties/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.set_safety(owner) @@ -86,7 +94,9 @@ button_icon_state = "strafe" /datum/action/vehicle/sealed/mecha/strafe/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.toggle_strafe() @@ -114,7 +124,9 @@ button_icon_state = "mech_seat_swap" /datum/action/vehicle/sealed/mecha/swap_seat/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(chassis.occupants.len == chassis.max_occupants) @@ -143,7 +155,9 @@ button_icon_state = "mech_overload_off" /datum/action/vehicle/sealed/mecha/mech_overclock/Trigger(trigger_flags, forced_state = null) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return chassis.toggle_overclock(forced_state) button_icon_state = "mech_overload_[chassis.overclock_mode ? "on" : "off"]" diff --git a/code/modules/vehicles/mecha/mecha_ui.dm b/code/modules/vehicles/mecha/mecha_ui.dm index 3c06c901e4e..ca7f03130e0 100644 --- a/code/modules/vehicles/mecha/mecha_ui.dm +++ b/code/modules/vehicles/mecha/mecha_ui.dm @@ -10,18 +10,22 @@ ui_view.display_to(user) /obj/vehicle/sealed/mecha/ui_status(mob/user, datum/ui_state/state) - if(contains(user)) - return UI_INTERACTIVE - return min( + var/common_status = min( ui_status_user_is_abled(user, src), - ui_status_user_has_free_hands(user, src), - ui_status_user_is_advanced_tool_user(user), ui_status_only_living(user), - max( - ui_status_user_is_adjacent(user, src), - ui_status_silicon_has_access(user, src), - ) ) + var/mob_specific_status = UI_INTERACTIVE + if(ishuman(user)) + mob_specific_status = min( + ui_status_user_inside(user, src), + ui_status_user_has_free_hands(user, src, allowed_source = VEHICLE_TRAIT), + ui_status_user_is_advanced_tool_user(user), + ) + if(isAI(user)) + mob_specific_status = ui_status_silicon_has_access(user, src) + if(isbrain(user)) + mob_specific_status = ui_status_user_inside(user, src) + return min(common_status, mob_specific_status) /obj/vehicle/sealed/mecha/ui_assets(mob/user) return list( diff --git a/code/modules/vehicles/mecha/working/clarke.dm b/code/modules/vehicles/mecha/working/clarke.dm index 1ecf4a9a831..07482cebf82 100644 --- a/code/modules/vehicles/mecha/working/clarke.dm +++ b/code/modules/vehicles/mecha/working/clarke.dm @@ -121,6 +121,8 @@ button_icon_state = "mecha_sleeper_miner" /datum/action/vehicle/sealed/mecha/clarke_scoop_body/Trigger(trigger_flags) + if(!..()) + return var/obj/item/mecha_parts/mecha_equipment/sleeper/clarke/sleeper = locate() in chassis var/mob/living/carbon/human/human_target for(var/mob/living/carbon/human/body in range(1, chassis)) @@ -138,7 +140,9 @@ COOLDOWN_DECLARE(search_cooldown) /datum/action/vehicle/sealed/mecha/mech_search_ruins/Trigger(trigger_flags) - if(!owner || !chassis || !(owner in chassis.occupants)) + if(!..()) + return + if(!chassis || !(owner in chassis.occupants)) return if(!COOLDOWN_FINISHED(src, search_cooldown)) chassis.balloon_alert(owner, "on cooldown!") diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 7d8452893ac..c9fb6b8fdbe 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -181,6 +181,8 @@ button_icon_state = "mech_siren_[secmech?.siren ? "on" : "off"]" /datum/action/vehicle/sealed/mecha/siren/Trigger(trigger_flags, forced_state = FALSE) + if(!..()) + return var/obj/vehicle/sealed/mecha/ripley/paddy/secmech = chassis secmech.togglesiren() diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 1c96c90ae68..a3ea8e3276c 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,5 +1,6 @@ /obj/vehicle/sealed flags_1 = PREVENT_CONTENTS_EXPLOSION_1 + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY interaction_flags_mouse_drop = NEED_HANDS var/enter_delay = 2 SECONDS