Mechanical Engineering Cross Role Interactions (#22880)

<img width="606" height="144" alt="image"
src="https://github.com/user-attachments/assets/f1c88863-37be-41e0-be79-27fca980a3f3"
/>

This PR adds new "Cross-Role Interactions" for the Mechanical
Engineering skill, with two specific kinds that are aimed at a variety
of different roles.

1. **Bonus damage vs. structures**: Having ranks in MechE makes you deal
bonus damage when melee attacking structures like Airlocks and Windows.
This makes it a desireable niche pick for any kind of job that can see
themself wanting to take a breaching to a room's entrance! For example,
paramedics, shaft miners, and security can all make use of it on
occasion.
2. **Mech Repair Speed**: This one is aimed specifically at Machinists.
Repairing mechs with a welder is no longer instantaneous (That was very
powergamey in practice for 'battle machinists'). Instead it has a repair
speed (and repair amount) that scales with your Mechanical Engineering
skill.

Why MechE and not Robotics? To encourage further "Machinist
Specialization". Machinist players were already pretty naturally
inclined to position their character as either being a Robotics
Specialist, or a Mechatronics Specialist, by sheer virtue of there being
two machinist slots and two noticeably distinctive roles. This
separation of skill interactions is there to further encourage this
degree of separation between machinist skillsets.

As a side note, just so I'm not thoroughly pissing off every machinist
main. As a quality of life improvement, I've made it so that attempting
to repair a mech with a welder will loop the repair until completed or
interrupted.

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
This commit is contained in:
VMSolidus
2026-08-16 16:13:43 +00:00
committed by GitHub
parent 6ae7fc8b2e
commit 27f727b71f
6 changed files with 94 additions and 11 deletions
+5
View File
@@ -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"
@@ -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
+13 -3
View File
@@ -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.<br>" \
+ " - You take 50% longer to craft anything.<br>" \
+ " - You can interact with some Engineering-related machinery.<br>" \
+ " - You deal 10% more damage when attacking structures such as airlocks, windows, and machinery.<br>" \
+ " - You can repair exosuits 25% faster<br>" \
+ " - Each use of a welder on an exosuit repairs 5 more damage.<br>" \
+ " - 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. <br>" \
+ " - You can craft items at the standard speed.<br>" \
+ " - You can craft a wider variety of items.<br>" \
+ " - Items you craft are generally at average quality.<br>" \
+ " - You can interact with most if not all Engineering equipment.<br>" \
+ " - You deal 15% more damage when attacking structures such as airlocks, windows, and machinery.<br>" \
+ " - You can repair exosuits 50% faster<br>" \
+ " - Each use of a welder on an exosuit repairs 10 more damage.<br>" \
+ " - 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.<br>" \
+ " - You can craft items 50% faster.<br>" \
+ " - You can craft a much wider variety of items.<br>" \
+ " - Items you craft are of much higher quality on average.<br>" \
+ " - You deal 20% more damage when attacking structures such as airlocks, windows, and machinery.<br>" \
+ " - You can repair exosuits 75% faster<br>" \
+ " - Each use of a welder on an exosuit repairs 15 more damage.<br>" \
+ " - You can recognize what many wires do in mechanical devices by sight.",
)
+3 -1
View File
@@ -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())
@@ -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))
@@ -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."