diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 5d65a9b0ee6..e9c14ab99e7 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -124,6 +124,8 @@
// Armed Combat Signals
#define COMSIG_APPLY_HIT_EFFECT "apply_hit_effect"
+/// Signal raised against a mob attempting to attack a structure, used to query components for structure damage modifiers.
+#define COMSIG_ATTACK_STRUCTURE "attack_structure"
// Various computer signals for interrupting via skill or other effects.
#define COMSIG_USE_REACTOR_COMPUTER "use_reactor_computer"
@@ -146,3 +148,6 @@
// Crafting Signals
#define COMSIG_GET_CRAFTING_MODIFIERS "get_crafting_modifiers"
+
+/// Signal raised on a person attempting to repair a mech.
+#define COMSIG_GET_MECH_WELD_MODIFIERS "mech_weld_modifiers"
diff --git a/code/datums/components/skills/engineering/mechanical_engineering_skill_component.dm b/code/datums/components/skills/engineering/mechanical_engineering_skill_component.dm
index a3207c66fa0..10e642fc486 100644
--- a/code/datums/components/skills/engineering/mechanical_engineering_skill_component.dm
+++ b/code/datums/components/skills/engineering/mechanical_engineering_skill_component.dm
@@ -1 +1,34 @@
/datum/component/skill/mechanical_engineering
+ /// +%bonus damage versus Structures
+ var/bonus_damage_per_rank = 0.05
+
+/datum/component/skill/mechanical_engineering/Initialize(level)
+ . = ..()
+ RegisterSignal(parent, COMSIG_ATTACK_STRUCTURE, PROC_REF(modify_structure_damage), override = TRUE)
+ RegisterSignal(parent, COMSIG_GET_MECH_WELD_MODIFIERS, PROC_REF(modify_mech_weld), override = TRUE)
+
+/datum/component/skill/mechanical_engineering/Destroy(force)
+ UnregisterSignal(parent, COMSIG_ATTACK_STRUCTURE)
+ UnregisterSignal(parent, COMSIG_GET_MECH_WELD_MODIFIERS)
+ return ..()
+
+/datum/component/skill/mechanical_engineering/proc/modify_structure_damage(owner, obj/structure/target, damage)
+ SIGNAL_HANDLER
+ if (skill_level == SKILL_LEVEL_UNFAMILIAR)
+ return
+
+ if (prob(20))
+ // Give the player some feedback that the skill is providing a damage bonus, but no need to spam the chat.
+ to_chat(owner, SPAN_NOTICE("Your attack exploits a structural weakness of \the [target]"))
+
+ *damage = *damage * (1 + bonus_damage_per_rank * (skill_level))
+
+/datum/component/skill/mechanical_engineering/proc/modify_mech_weld(mob/owner, obj/item/mech_component/mech_part, do_after_time, repair_value)
+ SIGNAL_HANDLER
+ if (skill_level == SKILL_LEVEL_UNFAMILIAR)
+ return
+
+ var/effective_skill = skill_level - 1
+ to_chat(owner, SPAN_NOTICE("Your skill with mechanical engineering makes repairing \the [mech_part] easier."))
+ *do_after_time = *do_after_time * (1 - 0.25 * effective_skill)
+ *repair_value = *repair_value * skill_level
diff --git a/code/datums/skills/occupational/engineering.dm b/code/datums/skills/occupational/engineering.dm
index 9cb68dc6dad..3e9167f97b8 100644
--- a/code/datums/skills/occupational/engineering.dm
+++ b/code/datums/skills/occupational/engineering.dm
@@ -22,7 +22,8 @@
/singleton/skill/mechanical_engineering
name = "Mechanical Engineering"
description = "Mechanical engineering has to do with general construction of objects, walls, windows, and so on. It is also necessary for the usage of heavy machinery \
- such as emitters. This skill is also commonly used for crafting items out of raw materials, and heavily governs the quality of said objects."
+ such as emitters. This skill is also commonly used for crafting items out of raw materials, and heavily governs the quality of said objects. \
+ It also modifies the damage you deal when attacking structures such as airlocks and windows."
maximum_level = SKILL_LEVEL_PROFESSIONAL
uneducated_skill_cap = SKILL_LEVEL_FAMILIAR
category = /singleton/skill_category/occupational
@@ -39,15 +40,24 @@
+ " - Items you craft will be of slightly lower than average quality.
" \
+ " - You take 50% longer to craft anything.
" \
+ " - You can interact with some Engineering-related machinery.
" \
+ + " - You deal 10% more damage when attacking structures such as airlocks, windows, and machinery.
" \
+ + " - You can repair exosuits 25% faster
" \
+ + " - Each use of a welder on an exosuit repairs 5 more damage.
" \
+ " - You can recognize what a few wires do in mechanical devices by sight.",
SKILL_LEVEL_TRAINED = "You have formal training in general Engineering concepts, equivalent to a Bachelor's Degree.
" \
+ " - You can craft items at the standard speed.
" \
- + " - You can craft a wider variety of items.
" \
+ + " - Items you craft are generally at average quality.
" \
+ " - You can interact with most if not all Engineering equipment.
" \
+ + " - You deal 15% more damage when attacking structures such as airlocks, windows, and machinery.
" \
+ + " - You can repair exosuits 50% faster
" \
+ + " - Each use of a welder on an exosuit repairs 10 more damage.
" \
+ " - You can recognize what several wires do in mechanical devices by sight.",
SKILL_LEVEL_PROFESSIONAL = "You have many years of training in general Engineering concepts, equivalent to a Master's Degree or better.
" \
+ " - You can craft items 50% faster.
" \
- + " - You can craft a much wider variety of items.
" \
+ + " - Items you craft are of much higher quality on average.
" \
+ + " - You deal 20% more damage when attacking structures such as airlocks, windows, and machinery.
" \
+ + " - You can repair exosuits 75% faster
" \
+ + " - Each use of a welder on an exosuit repairs 15 more damage.
" \
+ " - You can recognize what many wires do in mechanical devices by sight.",
)
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index cedc02ef270..9cdba155fb3 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -54,9 +54,11 @@
/obj/structure/attackby(obj/item/attacking_item, mob/user, params)
. = ..()
if(user?.a_intent == I_HURT && maxhealth)
+ var/damage = attacking_item.force
+ SEND_SIGNAL(user, COMSIG_ATTACK_STRUCTURE, src, &damage)
user.do_attack_animation(src)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- add_damage(attacking_item.force, attacking_item.damage_flags(), attacking_item.damtype, attacking_item.armor_penetration, attacking_item)
+ add_damage(damage, attacking_item.damage_flags(), attacking_item.damtype, attacking_item.armor_penetration, attacking_item)
if(hitsound)
playsound(user, hitsound, attacking_item.get_clamped_volume())
diff --git a/code/modules/heavy_vehicle/components/_components.dm b/code/modules/heavy_vehicle/components/_components.dm
index ab94bdb1d65..fb23d1238c7 100644
--- a/code/modules/heavy_vehicle/components/_components.dm
+++ b/code/modules/heavy_vehicle/components/_components.dm
@@ -139,7 +139,7 @@
/obj/item/mech_component/proc/update_components()
return
-/obj/item/mech_component/proc/repair_brute_generic(var/obj/item/weldingtool/WT, var/mob/user)
+/obj/item/mech_component/proc/repair_brute_generic(obj/item/weldingtool/WT, var/mob/user)
if(!istype(WT))
return
if(!brute_damage)
@@ -148,12 +148,38 @@
if(!WT.isOn())
to_chat(user, SPAN_WARNING("Turn \the [WT] on, first."))
return
- if(WT.use(0, user))
- var/repair_value = 15
- if(brute_damage)
- repair_brute_damage(repair_value)
- to_chat(user, SPAN_NOTICE("You mend the damage to \the [src]."))
- playsound(user.loc, 'sound/items/Welder.ogg', 25, 1)
+
+ var/do_after_time = 5 SECONDS
+ var/repair_value = 5
+ // Get modifiers only once before entering the loop.
+ SEND_SIGNAL(user, COMSIG_GET_MECH_WELD_MODIFIERS, src, &do_after_time, &repair_value)
+ if (repair_value <= 0) // Sanity check just in case to prevent an infinite loop after we start.
+ to_chat(user, SPAN_NOTICE("You can't repair \the [src]"))
+ return
+
+ to_chat(user, SPAN_NOTICE("You start welding \the [src]"))
+ playsound(user.loc, 'sound/items/Welder.ogg', 25, 1)
+
+ // Loop until finished fixing it.
+ while (TRUE)
+ if (!src || !WT || !user) // Any one of the three failed to exist.
+ return
+
+ if (!brute_damage) // Check damage both before and after do_after
+ to_chat(user, SPAN_NOTICE("You finish welding \the [src]."))
+ return
+
+ if (!do_after(user, do_after_time, src, DO_DEFAULT | DO_USER_UNIQUE_ACT | DO_SHOW_PROGRESS))
+ to_chat(user, SPAN_NOTICE("You were interrupted while welding \the [src]"))
+ return
+
+ if (!brute_damage || !WT.use(0, user))
+ to_chat(user, SPAN_NOTICE("You finish welding \the [src]."))
+ return
+
+ repair_brute_damage(repair_value)
+ to_chat(user, SPAN_NOTICE("You mend the damage to \the [src]."))
+ playsound(user.loc, 'sound/items/Welder.ogg', 25, 1)
/obj/item/mech_component/proc/repair_burn_generic(var/obj/item/stack/cable_coil/CC, var/mob/user)
if(!istype(CC))
diff --git a/html/changelogs/hellfirejag-mech-e-cross-roles.yml b/html/changelogs/hellfirejag-mech-e-cross-roles.yml
new file mode 100644
index 00000000000..9c833d95969
--- /dev/null
+++ b/html/changelogs/hellfirejag-mech-e-cross-roles.yml
@@ -0,0 +1,7 @@
+author: Hellfirejag
+delete-after: True
+changes:
+ - rscadd: "The mechanical engineering skill now provides a situational damage bonus for attacking structures such as airlocks and windows."
+ - rscadd: "The mechanical engineering skill now modifies the speed and repair amount when repairing a mech with a welder."
+ - rscadd: "Repairing mechs is now no longer instantaneous."
+ - rscadd: "Attempting to repair a mech with a welder will now automatically repeat the repair action until either completed, or interrupted."