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

🆑
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.
/🆑
This commit is contained in:
Y0SH1M4S73R
2025-01-14 09:50:03 -05:00
committed by GitHub
parent 81d2e97104
commit 7fe8f29fdb
10 changed files with 74 additions and 25 deletions
+11 -1
View File
@@ -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
+3 -1
View File
@@ -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
@@ -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"]"
+6 -2
View File
@@ -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"]"
@@ -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)
+22 -8
View File
@@ -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"]"
+13 -9
View File
@@ -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(
@@ -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!")
@@ -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()
+1
View File
@@ -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