Yet Another Mech Quality Of Life PR (#22916)

This was originally just going to be a PR that improves quality of life
for the mining mech, which *STILL* felt worse than mining by hand even
after my last time buffing it. But then I got sidetracked with adding
more sound effects to mechs, and now they have a "bitching betty" as
well as a reactor hum sound loop. Including even more audible feedback
for when the mech takes damage.


https://github.com/user-attachments/assets/5f2020f4-55fd-4e36-8368-471522aad4fa
This commit is contained in:
VMSolidus
2026-08-02 01:24:42 +00:00
committed by GitHub
parent 103b12087a
commit 886ca9237f
10 changed files with 103 additions and 19 deletions
@@ -196,3 +196,16 @@
mid_length = 3 SECONDS
volume = 75 // This sounds is rather quiet and needs a higher volume then anticipated for a background noise
ignore_walls = FALSE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/mech_power
start_sound = 'sound/mecha/nominal.ogg'
start_length = 0.5 SECONDS
start_volume = 100
mid_sounds = list('sound/mecha/mechambience.ogg' = 1)
mid_length = 5 SECONDS
falloff_exponent = SOUND_FALLOFF_EXPONENT + 4 // Makes the reactor hum loud inside the cockpit, and quiet outside it.
end_sound = 'sound/mecha/mech-shutdown.ogg'
end_volume = 100
volume = 50
+2 -2
View File
@@ -57,8 +57,8 @@
desc = "Kinetic blasts explode in a massively increased AoE radius at significantly increased power drain per shot, leveraging the exosuit's internal power core to sustain itself."
icon_state = "upgrade_chip"
cost_increase = 10
aoe_increase = 4
range_increase = 2
aoe_increase = 2
range_increase = 3
/obj/item/custom_ka_upgrade/upgrade_chips/illegal
name = "illegal custom KA upgrade chip"
@@ -111,6 +111,9 @@
if(!damageable_components.len) return
var/obj/item/robot_parts/robot_component/RC = pick(damageable_components)
if(RC.take_damage(brute, burn))
playsound(src, 'sound/mecha/internaldmgalarm.ogg', 100, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
playsound(src, 'sound/mecha/critdestr.ogg', 100, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
spark(src, 8)
qdel(RC)
update_components()
@@ -77,11 +77,13 @@
return
/obj/item/mecha_equipment/proc/installed(var/mob/living/heavy_vehicle/_owner)
SHOULD_CALL_PARENT(TRUE)
owner = _owner
//generally attached. Nothing should be able to grab it
canremove = FALSE
/obj/item/mecha_equipment/proc/uninstalled()
SHOULD_CALL_PARENT(TRUE)
if(active)
deactivate()
owner = null
@@ -89,7 +91,7 @@
/obj/item/mecha_equipment/Destroy()
owner = null
. = ..()
return ..()
/obj/item/mecha_equipment/mob_can_unequip(mob/M, slot, disable_warning)
. = ..()
+54 -11
View File
@@ -121,7 +121,7 @@ ABSTRACT_TYPE(/obj/item/mecha_equipment/mounted_system/mining)
holding_type = /obj/item/gun/custom_ka/exosuit/heavy
module_hints = list(
"<b>Left Click:</b> Fire a kinetic blast in the target direction.",
"<b>WARNING: This weapon produces a mining blast eight tiles in radius.</b>",
"<b>WARNING: This weapon produces a mining blast six tiles in radius.</b>",
"A mech can only fire within a 90 degree arc in the direction it is currently facing.",
"This weapon passively regenerates its ammunition using the mech's power supply.",
)
@@ -162,23 +162,24 @@ ABSTRACT_TYPE(/obj/item/mecha_equipment/mounted_system/mining)
/// How long the cooldown is before the ore can be pulsed again
var/cooldown_time = 5 SECONDS
/// How many chunks of ore can be moved at one time
var/static/ore_limit = 50
/// Radius of the summoner's pickup range.
var/pickup_range = 7
/// The maximum number of ores that can be picked up per pulse.
var/ore_limit = 150
/// The linked warp extraction ore box.
var/obj/structure/ore_box/linked_box
module_hints = list(
"<b>Left Click (Target Ore Box):</b> If the the target has a warp extraction beacon, link the summoner to it.",
"<b>Alt Click (Icon):</b> Teleport up to 50 ores within a radius of 7 tiles to the user.",
"<b>Alt Click (Icon):</b> Teleport up to 150 ores within a radius of 10 tiles to the user.",
"If a warp ore box has been linked, it will teleport ores there.",
"Otherwise if the mech is also equipped with a mounted clamp that contains an ore box, ores will be teleported to said box.",
"If linked to an ore box, walking over ores will also teleport them into the crate"
)
/obj/item/mecha_equipment/ore_summoner/afterattack(var/atom/target, var/mob/living/user, var/inrange, var/params)
/obj/item/mecha_equipment/ore_summoner/afterattack(atom/target, mob/living/user, inrange, params)
if(istype(target, /obj/structure/ore_box))
var/obj/structure/ore_box/box = target
if (box.warp_core)
@@ -186,12 +187,12 @@ ABSTRACT_TYPE(/obj/item/mecha_equipment/mounted_system/mining)
to_chat(user, SPAN_NOTICE("You link \the [src] to \the [target]"))
return FALSE
/obj/item/mecha_equipment/ore_summoner/attack_self(var/mob/user)
/obj/item/mecha_equipment/ore_summoner/attack_self(mob/user)
. = ..()
if(.)
summon_ore(user)
/obj/item/mecha_equipment/ore_summoner/proc/summon_ore(var/mob/user)
/obj/item/mecha_equipment/ore_summoner/proc/summon_ore(mob/user)
if(last_use + cooldown_time >= world.time)
to_chat(user, SPAN_WARNING("The ore summoner is recalibrating..."))
return
@@ -219,7 +220,7 @@ ABSTRACT_TYPE(/obj/item/mecha_equipment/mounted_system/mining)
ore.forceMove(ore_box)
else
ore.forceMove(our_turf)
limit -= 1
limit--
CHECK_TICK
last_use = world.time
@@ -230,12 +231,13 @@ ABSTRACT_TYPE(/obj/item/mecha_equipment/mounted_system/mining)
/obj/item/mecha_equipment/ore_summoner/get_hardpoint_maptext()
return last_use + cooldown_time < world.time ? "Ready" : "Recharging"
/obj/item/mecha_equipment/ore_summoner/proc/check_linked_box(var/mob/user)
/obj/item/mecha_equipment/ore_summoner/proc/check_linked_box(mob/user)
if(!linked_box)
return FALSE
if(!linked_box.warp_core)
to_chat(user, SPAN_WARNING("\The [linked_box] lost its warp beacon!"))
if (user)
to_chat(user, SPAN_WARNING("\The [linked_box] lost its warp beacon!"))
linked_box = null
return FALSE
@@ -243,4 +245,45 @@ ABSTRACT_TYPE(/obj/item/mecha_equipment/mounted_system/mining)
/obj/item/mecha_equipment/ore_summoner/Destroy()
linked_box = null // Clear the reference to prevent hard deletes.
if (owner)
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
return ..()
/obj/item/mecha_equipment/ore_summoner/installed()
. = ..()
if (!owner)
return
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(pickup_ores))
/obj/item/mecha_equipment/ore_summoner/uninstalled()
if (owner)
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
return ..()
/obj/item/mecha_equipment/ore_summoner/proc/pickup_ores()
SIGNAL_HANDLER
if (!owner)
return
var/obj/structure/ore_box/ore_box
if(check_linked_box())
ore_box = linked_box
else
for(var/hardpoint in owner.hardpoints)
var/obj/item/mecha_equipment/clamp/clamp = owner.hardpoints[hardpoint]
if(!istype(clamp))
continue
var/obj/structure/ore_box/box = locate() in clamp
if(box)
ore_box = box
break
if (!ore_box)
return
var/turf/our_turf = get_turf(owner)
if (!our_turf)
return
for (var/obj/item/ore/ore in our_turf)
ore.forceMove(ore_box)
@@ -160,6 +160,7 @@
else
if(owner.set_hardpoint(hardpoint_tag))
icon_state = "hardpoint_selected"
playsound(owner, 'sound/weapons/laser_safetyon.ogg', 50, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
/atom/movable/screen/mecha/eject
name = "eject"
@@ -216,6 +217,7 @@
var/main_color = owner.use_air ? "#d1d1d1" : "#525252"
maptext = "<span style=\"font-family: 'Small Fonts'; color: [main_color]; -dm-text-outline: 1 #242424; font-size: 6px;\">AIR</span>"
notify_user(usr, SPAN_NOTICE("Auxiliary atmospheric system [owner.use_air ? "enabled" : "disabled"]."))
playsound(owner, 'sound/weapons/laser_safetyon.ogg', 50, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
/atom/movable/screen/mecha/toggle/maint
name = "toggle maintenance protocol"
@@ -230,6 +232,7 @@
var/main_color = owner.maintenance_protocols ? "#d1d1d1" : "#525252"
maptext = "<span style=\"font-family: 'Small Fonts'; color: [main_color]; -dm-text-outline: 1 #242424; font-size: 6px;\">MAINT</span>"
notify_user(usr, SPAN_NOTICE("Maintenance protocols [owner.maintenance_protocols ? "enabled" : "disabled"]."))
playsound(owner, 'sound/weapons/laser_safetyon.ogg', 50, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
/atom/movable/screen/mecha/toggle/power_control
name = "power control"
@@ -263,6 +266,7 @@
var/main_color = owner.hardpoints_locked ? "#d1d1d1" : "#525252"
maptext = "<span style=\"font-family: 'Small Fonts'; color: [main_color]; -dm-text-outline: 1 #242424; font-size: 6px;\">GEAR</span>"
notify_user(usr, SPAN_NOTICE("Hardpoint system access is now [owner.hardpoints_locked ? "disabled" : "enabled"]."))
playsound(owner, 'sound/weapons/laser_safetyon.ogg', 50, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
/atom/movable/screen/mecha/toggle/hatch
name = "toggle hatch lock"
@@ -318,7 +322,7 @@
toggled = !toggled
owner.hatch_closed = toggled
playsound(owner.loc, owner.hatch_closed ? 'sound/effects/metal_close.ogg' : 'sound/effects/air_seal.ogg', 75, 1)
playsound(owner.loc, owner.hatch_closed ? 'sound/mecha/hatch-door-close.ogg' : 'sound/effects/air_seal.ogg', 75, 1)
if(notify_user)
notify_user(usr, SPAN_NOTICE("The [owner.body.hatch_descriptor] is now [owner.hatch_closed ? "closed" : "open" ]."))
update_icon()
@@ -90,6 +90,9 @@
adjustFireLoss(damage, target)
if((damagetype == DAMAGE_BRUTE || damagetype == DAMAGE_BURN) && prob(25+(damage*2)))
if(prob(damage))
playsound(src, 'sound/mecha/internaldmgalarm.ogg', 100, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
playsound(src, 'sound/mecha/critdestrnano.ogg', 100, 0, falloff_exponent = (SOUND_FALLOFF_EXPONENT+4))
spark(src, 3)
updatehealth()
+3
View File
@@ -37,6 +37,9 @@
if(!powered)
//Shut down all systems
if (!power && sound_looping) // This is stupid why is this a second var?
soundloop.stop()
sound_looping = FALSE
if(head)
head.active_sensors = FALSE
for(var/hardpoint in hardpoints)
+9 -4
View File
@@ -95,6 +95,11 @@
//POWER
var/power = MECH_POWER_OFF
/// Sound effect used for mech ambience.
var/datum/looping_sound/mech_power/soundloop
/// Separate tracking of current sound looping so we aren't hammering the sound loop system on every tick.
var/sound_looping = FALSE
/mob/living/heavy_vehicle/Destroy()
unassign_leader()
unassign_following()
@@ -137,7 +142,7 @@
QDEL_NULL(camera)
QDEL_NULL(radio)
QDEL_NULL(soundloop)
. = ..()
/mob/living/heavy_vehicle/IsAdvancedToolUser()
@@ -246,7 +251,7 @@
add_language(LANGUAGE_TCB)
default_language = GLOB.all_languages[LANGUAGE_TCB]
soundloop = new(src)
. = INITIALIZE_HINT_LATELOAD
/mob/living/heavy_vehicle/LateInitialize()
@@ -278,15 +283,15 @@
if(power == MECH_POWER_TRANSITION)
to_chat(reciever, SPAN_NOTICE("Power transition in progress. Please wait."))
else if(power == MECH_POWER_ON) //Turning it off is instant
playsound(src, 'sound/mecha/mech-shutdown.ogg', 100, 0)
power = MECH_POWER_OFF
else if(get_cell(TRUE))
//Start power up sequence
power = MECH_POWER_TRANSITION
playsound(src, 'sound/mecha/powerup.ogg', 50, 0)
if(do_after(reciever, 1.5 SECONDS) && power == MECH_POWER_TRANSITION)
playsound(src, 'sound/mecha/nominal.ogg', 50, 0)
power = MECH_POWER_ON
sound_looping = TRUE
soundloop.start()
else
to_chat(reciever, SPAN_WARNING("You abort the powerup sequence."))
power = MECH_POWER_OFF
@@ -0,0 +1,8 @@
author: Hellfirejag
delete-after: True
changes:
- rscadd: "Mech mounted ore summoners will now pick up ores that the mech walks over."
- balance: "Mounted ore summoners can now pick up up to 150 ores when actively pulsed, up from 50."
- balance: "Reduced the explosion radius of the mech heavy kinetic accelerator by 2"
- balance: "Increased the range of the mech heavy kinetic accelerator by 1"
- rscadd: "Added more sound effects for mechs, including a looping reactor hum, and warning sounds for critical damage."