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."