From 3fccc7e24e4029210a638f81f9b6bcc0495abefc Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 14:25:53 +1100 Subject: [PATCH 1/8] Fixing borer infestation logic. --- .../modules/mob/living/human/human_defense.dm | 14 ----- code/modules/mob/mob_eating.dm | 13 ++++- mods/mobs/borers/mob/borer/borer_attacks.dm | 58 +++++++++---------- mods/mobs/borers/mob/borer/borer_hud.dm | 1 + 4 files changed, 38 insertions(+), 48 deletions(-) diff --git a/code/modules/mob/living/human/human_defense.dm b/code/modules/mob/living/human/human_defense.dm index 1014326d217..30ea13667b6 100644 --- a/code/modules/mob/living/human/human_defense.dm +++ b/code/modules/mob/living/human/human_defense.dm @@ -85,20 +85,6 @@ meteor_act // Add inherent armor to the end of list so that protective equipment is checked first . += ..() -/mob/living/human/proc/check_head_coverage() - for(var/slot in global.standard_headgear_slots) - var/obj/item/clothing/clothes = get_equipped_item(slot) - if(istype(clothes) && (clothes.body_parts_covered & SLOT_HEAD)) - return TRUE - return FALSE - -//Used to check if they can be fed food/drinks/pills -/mob/living/human/check_mouth_coverage() - for(var/slot in global.standard_headgear_slots) - var/obj/item/gear = get_equipped_item(slot) - if(istype(gear) && (gear.body_parts_covered & SLOT_FACE) && !(gear.item_flags & ITEM_FLAG_FLEXIBLEMATERIAL)) - return gear - /mob/living/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone) for (var/obj/item/grab/grab as anything in grabbed_by) diff --git a/code/modules/mob/mob_eating.dm b/code/modules/mob/mob_eating.dm index 2d9170878b8..c4fb19e2854 100644 --- a/code/modules/mob/mob_eating.dm +++ b/code/modules/mob/mob_eating.dm @@ -1,6 +1,15 @@ -// mobs do not have blocked mouths by default -// overridden in human_defense.dm +//Used to check if they can be fed food/drinks/pills /mob/proc/check_mouth_coverage() + return get_covering_head_item(SLOT_FACE) + +/mob/proc/check_head_coverage() + return !!get_covering_head_item(SLOT_HEAD) + +/mob/proc/get_covering_head_item(slot_flags) + for(var/slot in global.standard_headgear_slots) + var/obj/item/clothes = get_equipped_item(slot) + if(istype(clothes) && (clothes.body_parts_covered & slot_flags) && !(clothes.item_flags & ITEM_FLAG_FLEXIBLEMATERIAL)) + return clothes return null /mob/proc/get_eaten_transfer_amount(var/default) diff --git a/mods/mobs/borers/mob/borer/borer_attacks.dm b/mods/mobs/borers/mob/borer/borer_attacks.dm index 43358767a9e..1cd2b76ceaf 100644 --- a/mods/mobs/borers/mob/borer/borer_attacks.dm +++ b/mods/mobs/borers/mob/borer/borer_attacks.dm @@ -1,50 +1,44 @@ /mob/living/simple_animal/borer/UnarmedAttack(atom/A, proximity) - . = ..() - if(.) - return + if(host) + return TRUE // We cannot click things outside of our host. - if(!isliving(A) || a_intent != I_GRAB) - return FALSE + if(!isliving(A) || a_intent != I_GRAB || stat || !proximity) + return ..() - if(host || !can_use_borer_ability(requires_host_value = FALSE, check_last_special = FALSE)) - return FALSE + if(!can_use_borer_ability(requires_host_value = FALSE, check_last_special = FALSE)) + return TRUE - var/mob/living/M = A - if(M.has_brain_worms()) + var/mob/living/victim = A + if(victim.has_brain_worms()) to_chat(src, SPAN_WARNING("You cannot take a host who already has a passenger!")) return TRUE - - //TODO generalize borers to enter any mob. Until then, return early. - if(!ishuman(M)) - to_chat(src, SPAN_WARNING("This creature is not sufficiently intelligent to host you.")) + var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(victim, BP_HEAD) + if(!limb) + to_chat(src, SPAN_WARNING("\The [victim] does not have anatomy compatible with your lifecycle!")) return TRUE - // end TODO - - var/mob/living/human/H = M - var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(H, BP_HEAD) - if(!E) - to_chat(src, SPAN_WARNING("\The [H] does not have a head!")) + if(BP_IS_PROSTHETIC(limb)) + to_chat(src, SPAN_WARNING("\The [victim]'s head is prosthetic and cannot support your lifecycle!")) return TRUE - if(!H.should_have_organ(BP_BRAIN)) - to_chat(src, SPAN_WARNING("\The [H] does not seem to have a brain cavity to enter.")) + if(!victim.should_have_organ(BP_BRAIN)) + to_chat(src, SPAN_WARNING("\The [victim] does not seem to have a brain cavity to enter.")) return TRUE - if(H.check_head_coverage()) + if(victim.check_head_coverage()) to_chat(src, SPAN_WARNING("You cannot get through that host's protective gear.")) return TRUE - to_chat(M, SPAN_WARNING("Something slimy begins probing at the opening of your ear canal...")) - to_chat(src, SPAN_NOTICE("You slither up [M] and begin probing at their ear canal...")) + to_chat(victim, SPAN_WARNING("Something slimy begins probing at the opening of your ear canal...")) + to_chat(src, SPAN_NOTICE("You slither up [victim] and begin probing at their ear canal...")) set_ability_cooldown(5 SECONDS) - if(!do_after(src, 3 SECONDS, M)) + if(!do_after(src, 3 SECONDS, victim) || host || GET_EXTERNAL_ORGAN(victim, BP_HEAD) != limb || BP_IS_PROSTHETIC(limb) || victim.check_head_coverage()) return TRUE - to_chat(src, SPAN_NOTICE("You wiggle into \the [M]'s ear.")) - if(M.stat == CONSCIOUS) - to_chat(M, SPAN_DANGER("Something wet, cold and slimy wiggles into your ear!")) + to_chat(src, SPAN_NOTICE("You wiggle into \the [victim]'s ear.")) + if(victim.stat == CONSCIOUS) + to_chat(victim, SPAN_DANGER("Something wet, cold and slimy wiggles into your ear!")) - host = M + host = victim host.status_flags |= PASSEMOTES forceMove(host) @@ -60,9 +54,9 @@ borers.add_antagonist_mind(host.mind, 1, borers.faction_name, borers.faction_welcome) if(ishuman(host)) - var/obj/item/organ/internal/I = GET_INTERNAL_ORGAN(H, BP_BRAIN) + var/obj/item/organ/internal/I = GET_INTERNAL_ORGAN(victim, BP_BRAIN) if(!I) // No brain organ, so the borer moves in and replaces it permanently. replace_brain() - else if(E) // If they're in normally, implant removal can get them out. - LAZYDISTINCTADD(E.implants, src) + else if(limb) // If they're in normally, implant removal can get them out. + LAZYDISTINCTADD(limb.implants, src) return TRUE diff --git a/mods/mobs/borers/mob/borer/borer_hud.dm b/mods/mobs/borers/mob/borer/borer_hud.dm index 8b9a155e5d4..ff0479086ad 100644 --- a/mods/mobs/borers/mob/borer/borer_hud.dm +++ b/mods/mobs/borers/mob/borer/borer_hud.dm @@ -50,6 +50,7 @@ icon = 'mods/mobs/borers/icons/borer_ui.dmi' alpha = 0 invisibility = INVISIBILITY_MAXIMUM + requires_ui_style = FALSE /obj/screen/borer/handle_click(mob/user, params) if(!isborer(user)) From e6f947baf776d0a10e87ac6ff9a5d3fa9397fb05 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 15:46:16 +1100 Subject: [PATCH 2/8] Updating holster code, adding quick interaction for holsters and holster accessories. --- code/_onclick/click.dm | 4 +- code/datums/extensions/holster/holster.dm | 63 ++++++++++++++++++- .../objects/items/weapons/storage/belt.dm | 37 +++++------ code/modules/clothing/webbing/holster.dm | 17 +++-- 4 files changed, 86 insertions(+), 35 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 96c1880c828..42298a21d64 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -282,10 +282,10 @@ return A.CtrlClick(src) /atom/proc/CtrlClick(var/mob/user) - if(loc == user) + if(get_recursive_loc_of_type(/mob) == user) var/decl/interaction_handler/handler = get_quick_interaction_handler(user) if(handler) - var/using_item = user.get_active_held_item() || user.get_usable_hand_slot_organ() + var/using_item = user.get_active_held_item() if(handler.is_possible(src, user, using_item)) return handler.invoked(src, user, using_item) return FALSE diff --git a/code/datums/extensions/holster/holster.dm b/code/datums/extensions/holster/holster.dm index f83a5ac67a9..88ddb7399b9 100644 --- a/code/datums/extensions/holster/holster.dm +++ b/code/datums/extensions/holster/holster.dm @@ -111,7 +111,7 @@ to_chat(user, "It is empty.") /datum/extension/holster/proc/check_holster() - if(holstered.loc != storage) + if(holstered.loc != storage.holder) clear_holster() /atom/proc/holster_verb(var/holster_name in get_holsters()) @@ -154,4 +154,63 @@ else for(var/i = 1 to holster_accessories.len) var/holster_name = "[accessory_name] [i]" - .[holster_name] = get_extension(holster_accessories[i], /datum/extension/holster) \ No newline at end of file + .[holster_name] = get_extension(holster_accessories[i], /datum/extension/holster) + +// Basic unholster for an item at the top level. +/decl/interaction_handler/unholster + name = "Unholster" + +/decl/interaction_handler/unholster/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() && !prop + if(.) + var/datum/extension/holster/holster = get_extension(target, /datum/extension/holster) + return !!holster?.holstered + +/decl/interaction_handler/unholster/invoked(atom/target, mob/user, obj/item/prop) + var/datum/extension/holster/holster = get_extension(target, /datum/extension/holster) + return holster?.unholster(user, avoid_intent = TRUE) + +// Interaction procs for getting this interaction for basic items. +/obj/item/get_quick_interaction_handler(mob/user) + if(!(. = ..())) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster?.holstered) + return GET_DECL(/decl/interaction_handler/unholster) + +// More complex version of the above that iterates clothing accessories. +/decl/interaction_handler/unholster_accessory + name = "Unholster From Accessory" + expected_target_type = /obj/item/clothing + +/decl/interaction_handler/unholster_accessory/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() && !prop + if(.) + var/obj/item/clothing/clothes = target + for(var/obj/item/thing in clothes.accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.holstered) + return TRUE + return FALSE + +/decl/interaction_handler/unholster_accessory/invoked(atom/target, mob/user, obj/item/prop) + var/obj/item/clothing/clothes = target + for(var/obj/item/thing in clothes.accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.unholster(user, avoid_intent = TRUE)) + return TRUE + return FALSE + +// Interaction procs for getting this interaction for clothing accessories. +/obj/item/clothing/get_alt_interactions(mob/user) + . = ..() + for(var/obj/item/thing in accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.holstered) + LAZYADD(., GET_DECL(/decl/interaction_handler/unholster_accessory)) + +/obj/item/clothing/get_quick_interaction_handler(mob/user) + if(!(. = ..())) + for(var/obj/item/thing in accessories) + var/datum/extension/holster/holster = get_extension(thing, /datum/extension/holster) + if(holster?.holstered) + return GET_DECL(/decl/interaction_handler/unholster_accessory) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 641a512ce20..e53ef9f89e0 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -24,11 +24,11 @@ . = ..() if(overlay_flags & BELT_OVERLAY_ITEMS) var/list/cur_overlays - for(var/obj/item/I in contents) - if(I.use_single_icon) - LAZYADD(cur_overlays, I.get_on_belt_overlay()) + for(var/obj/item/thing in contents) + if(thing.use_single_icon) + LAZYADD(cur_overlays, thing.get_on_belt_overlay()) else - LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', I.icon_state)) + LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', thing.icon_state)) if(LAZYLEN(cur_overlays)) add_overlay(cur_overlays) @@ -37,8 +37,8 @@ /obj/item/belt/get_mob_overlay(mob/user_mob, slot, bodypart, use_fallback_if_icon_missing = TRUE, skip_adjustment = FALSE) var/image/ret = ..() if(ret && slot == slot_belt_str && length(contents)) - for(var/obj/item/I in contents) - var/image/new_overlay = I.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) + for(var/obj/item/thing in contents) + var/image/new_overlay = thing.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) if(new_overlay) ret.overlays += new_overlay return ret @@ -57,13 +57,6 @@ . = ..() set_extension(src, /datum/extension/holster, storage, sound_in, sound_out, can_holster) -/obj/item/belt/holster/get_stored_inventory() - . = ..() - if(length(.)) - var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) - if(holster.holstered) - . -= holster.holstered - /obj/item/belt/holster/attackby(obj/item/used_item, mob/user) var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) if(holster?.holster(used_item, user)) @@ -73,27 +66,27 @@ /obj/item/belt/holster/attack_hand(mob/user) if(!user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - if(H.unholster(user)) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster?.unholster(user)) return TRUE return ..() /obj/item/belt/holster/examine(mob/user) . = ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - H.examine_holster(user) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + holster.examine_holster(user) /obj/item/belt/holster/on_update_icon() . = ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) if(overlay_flags) var/list/cur_overlays - for(var/obj/item/I in contents) - if(I == H.holstered) + for(var/obj/item/thing in contents) + if(thing == holster.holstered) if(overlay_flags & BELT_OVERLAY_HOLSTER) - LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', I.icon_state)) + LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', thing.icon_state)) else if(overlay_flags & BELT_OVERLAY_ITEMS) - LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', I.icon_state)) + LAZYADD(cur_overlays, overlay_image('icons/obj/clothing/obj_belt_overlays.dmi', thing.icon_state)) if(LAZYLEN(cur_overlays)) add_overlay(cur_overlays) diff --git a/code/modules/clothing/webbing/holster.dm b/code/modules/clothing/webbing/holster.dm index 47ca037c939..1d49eaabc2b 100644 --- a/code/modules/clothing/webbing/holster.dm +++ b/code/modules/clothing/webbing/holster.dm @@ -12,25 +12,24 @@ . = ..() set_extension(src, /datum/extension/holster, storage, sound_in, sound_out, can_holster) -/obj/item/clothing/webbing/holster/attackby(obj/item/W, mob/user) - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - if(H.holster(W, user)) +/obj/item/clothing/webbing/holster/attackby(obj/item/used_item, mob/user) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster.holster(used_item, user)) return TRUE - else - . = ..(W, user) + return ..(used_item, user) /obj/item/clothing/webbing/holster/attack_hand(mob/user) if(!user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - if(H.unholster(user)) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + if(holster.unholster(user)) return TRUE return ..() /obj/item/clothing/webbing/holster/examine(mob/user) . = ..(user) - var/datum/extension/holster/H = get_extension(src, /datum/extension/holster) - H.examine_holster(user) + var/datum/extension/holster/holster = get_extension(src, /datum/extension/holster) + holster.examine_holster(user) /obj/item/clothing/webbing/holster/on_attached(var/obj/item/clothing/holder, var/mob/user) . = ..() From 6992db4bd50ae945f0bba7e4928c0cf012b008a6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 17:29:55 +1100 Subject: [PATCH 3/8] Prevents borers moving in a host from breaking them completely. --- mods/mobs/borers/mob/borer/borer.dm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mods/mobs/borers/mob/borer/borer.dm b/mods/mobs/borers/mob/borer/borer.dm index 5529384f774..6fe781f44d1 100644 --- a/mods/mobs/borers/mob/borer/borer.dm +++ b/mods/mobs/borers/mob/borer/borer.dm @@ -20,6 +20,22 @@ bleed_colour = "#816e12" ai = /datum/mob_controller/borer + // Defined here to remove relaymove handlers as being + // directly in mob contents breaks relaymove spectacularly. + movement_handlers = list( + /datum/movement_handler/mob/death, + /datum/movement_handler/mob/borer_in_host, + /datum/movement_handler/mob/conscious, + /datum/movement_handler/mob/eye, + /datum/movement_handler/mob/delay, + /datum/movement_handler/mob/stop_effect, + /datum/movement_handler/mob/physically_capable, + /datum/movement_handler/mob/physically_restrained, + /datum/movement_handler/mob/space, + /datum/movement_handler/mob/multiz, + /datum/movement_handler/mob/movement + ) + var/static/list/chemical_types = list( "anti-trauma" = /decl/material/liquid/brute_meds, "amphetamines" = /decl/material/liquid/amphetamines, @@ -42,6 +58,9 @@ var/mob/living/human/host // Human host for the brain worm. var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth. +/datum/movement_handler/mob/borer_in_host/MayMove(mob/mover, is_external) + return ismob(mob.loc) ? MOVEMENT_STOP : MOVEMENT_PROCEED + /datum/mob_controller/borer emote_hear = list("chirrups") do_wander = FALSE From aa75817ed35ad3060f611310d42f4186dcb908ed Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 21 Jan 2025 11:24:18 -0500 Subject: [PATCH 4/8] Fix missing phase argument in add_to_reagents --- code/game/turfs/turf_fluids.dm | 2 +- code/modules/reagents/Chemistry-Holder.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm index 13e48d99052..fafce1d44ff 100644 --- a/code/game/turfs/turf_fluids.dm +++ b/code/game/turfs/turf_fluids.dm @@ -110,7 +110,7 @@ create_reagents(FLUID_MAX_DEPTH) return ..() -/turf/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase) +/turf/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase = null) if(!reagents) create_reagents(FLUID_MAX_DEPTH) return ..() diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 88cbb17aa8c..c8872711cd3 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -1,8 +1,8 @@ var/global/obj/temp_reagents_holder = new var/global/datum/reagents/sink/infinite_reagent_sink = new -/atom/proc/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE) - return reagents?.add_reagent(reagent_type, amount, data, safety, defer_update) +/atom/proc/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase = null) + return reagents?.add_reagent(reagent_type, amount, data, safety, defer_update, phase) /atom/proc/remove_from_reagents(reagent_type, amount, safety = FALSE, defer_update = FALSE) return reagents?.remove_reagent(reagent_type, amount, safety, defer_update) From 3bb4000373c1d889dd76218a1ce75a7dcaff6b32 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 21 Jan 2025 11:35:31 -0500 Subject: [PATCH 5/8] Fix clothing ensemble examine name missing an article --- code/modules/clothing/_clothing.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index be67a2323ee..31e8219e033 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -303,12 +303,12 @@ update_clothing_icon() /obj/item/clothing/get_examine_name() - var/list/ensemble = list(name) + var/list/ensemble = list(..()) for(var/obj/item/clothing/accessory in accessories) if(accessory.accessory_visibility == ACCESSORY_VISIBILITY_ENSEMBLE) - LAZYADD(ensemble, accessory.get_examine_name()) - if(length(ensemble) <= 1) - return ..() + ensemble += accessory.get_examine_name() + if(length(ensemble) == 1) // don't worry about it being empty, we always have a minimum of one + return ensemble[1] return english_list(ensemble, summarize = TRUE) /obj/item/clothing/get_examine_line() From 4f4f496a59572e359e6d4d5cb106d4ee1283d7ac Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 10:46:25 +1100 Subject: [PATCH 6/8] Fixes bad istype() in hand slot code. --- code/modules/mob/mob.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3a465515aa4..98985b3add8 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1401,8 +1401,8 @@ /// THIS DOES NOT RELATE TO HELD ITEM SLOTS. It is very specifically a functional BP_L_HAND or BP_R_HAND organ, not necessarily a gripper. /mob/proc/get_usable_hand_slot_organ() - var/obj/item/organ/external/paw = GET_EXTERNAL_ORGAN(src, BP_L_HAND) - if(!istype(paw) && !paw.is_usable()) - paw = GET_EXTERNAL_ORGAN(src, BP_R_HAND) - if(istype(paw) && paw.is_usable()) - return paw + var/static/list/hand_slots = list(BP_L_HAND, BP_R_HAND) + for(var/slot in shuffle(hand_slots)) + var/obj/item/organ/external/hand = GET_EXTERNAL_ORGAN(src, slot) + if(istype(hand) && hand.is_usable()) + return hand From 01133c35ad6b088dc11561b5b54f985e1fc85bf7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 13:27:22 +1100 Subject: [PATCH 7/8] Fixing issues with robot brainmobs. --- code/modules/mob/living/brain/brain.dm | 2 +- code/modules/mob/living/death.dm | 6 +++ code/modules/mob/living/human/death.dm | 3 -- .../modules/mob/living/silicon/robot/robot.dm | 40 ++++++++++++------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 35b97e4880b..fe3e16913e8 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -44,7 +44,7 @@ container.queue_icon_update() /mob/living/brain/proc/get_container() - . = loc?.loc + return get_recursive_loc_of_type(/obj/item/organ/internal) /mob/living/brain/Login() . = ..() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 8855bd1ecd7..8a31af021dc 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -11,3 +11,9 @@ stop_aiming(no_message=1) if(istype(ai)) ai.handle_death(gibbed) + + var/decl/species/my_species = get_species() + if(my_species) + if(!gibbed && my_species.death_sound) + playsound(loc, my_species.death_sound, 80, 1, 1) + my_species.handle_death(src) diff --git a/code/modules/mob/living/human/death.dm b/code/modules/mob/living/human/death.dm index e06f550ae42..8f21775624a 100644 --- a/code/modules/mob/living/human/death.dm +++ b/code/modules/mob/living/human/death.dm @@ -33,11 +33,8 @@ if(!gibbed) set_tail_animation_state(null, TRUE) handle_organs() - if(species.death_sound) - playsound(loc, species.death_sound, 80, 1, 1) if(SSticker.mode) SSticker.mode.check_win() - species.handle_death(src) /mob/living/human/physically_destroyed(var/skip_qdel, var/droplimb_type = DISMEMBER_METHOD_BLUNT) for(var/obj/item/organ/external/limb in get_external_organs()) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f2b3335bc46..0953228225a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -190,14 +190,7 @@ return 0 /mob/living/silicon/robot/Destroy() - if(central_processor) - central_processor.dropInto(loc) - var/mob/living/brainmob = central_processor.get_brainmob() - if(mind && brainmob) - mind.transfer_to(brainmob) - else - ghostize() - central_processor = null + QDEL_NULL(central_processor) if(connected_ai) connected_ai.connected_robots -= src connected_ai = null @@ -518,8 +511,8 @@ SPAN_NOTICE("\The [user] begins ripping \the [central_processor] out of \the [src]."), SPAN_NOTICE("You jam the crowbar into the robot and begin levering out \the [central_processor].")) - if(do_after(user, 50, src)) - dismantle(user) + if(do_after(user, 5 SECONDS, src)) + dismantle_robot(user) else // Okay we're not removing the cell or a CPU, but maybe something else? var/list/removable_components = list() @@ -1042,10 +1035,29 @@ return 1 return ..() -/mob/living/silicon/robot/proc/dismantle(var/mob/user) - to_chat(user, SPAN_NOTICE("You damage some parts of the chassis, but eventually manage to rip out the central processor.")) - var/obj/item/robot_parts/robot_suit/C = new dismantle_type(loc) - C.dismantled_from(src) +/mob/living/silicon/robot/gib(do_gibs) + SHOULD_CALL_PARENT(FALSE) + var/lastloc = loc + dismantle_robot() + if(lastloc && do_gibs) + spawn_gibber(lastloc) + +/mob/living/silicon/robot/proc/dismantle_robot(var/mob/user) + + if(central_processor) + if(user) + to_chat(user, SPAN_NOTICE("You damage some parts of the chassis, but eventually manage to rip out \the [central_processor].")) + central_processor.dropInto(loc) + var/mob/living/brainmob = central_processor.get_brainmob(create_if_missing = TRUE) + if(mind && brainmob) + mind.transfer_to(brainmob) + else + ghostize() + central_processor.update_icon() + central_processor = null + + var/obj/item/robot_parts/robot_suit/chassis = new dismantle_type(loc) + chassis.dismantled_from(src) qdel(src) /mob/living/silicon/robot/try_stock_parts_install(obj/item/stock_parts/W, mob/user) From c86a66c784e293ec7fcd219523790fe7be616f4f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 22 Jan 2025 23:05:45 +1100 Subject: [PATCH 8/8] Cleaning up/generalizing some procs for electrical shock to handle mobs not using their hands. --- code/__defines/species.dm | 1 + code/datums/wires/smes.dm | 78 +++++++++---------- .../objects/items/weapons/material/shards.dm | 2 +- code/game/objects/structures/grille.dm | 33 ++++---- code/modules/mob/inventory.dm | 6 ++ code/modules/mob/living/carbon/carbon.dm | 28 +++---- .../mob/living/carbon/human/human_defense.dm | 31 -------- code/modules/mob/living/living_defense.dm | 10 ++- code/modules/mob/living/silicon/silicon.dm | 26 ++++--- code/modules/mob/mob_damage.dm | 21 +++++ code/modules/power/power.dm | 15 ++-- code/modules/species/species_helpers.dm | 6 +- 12 files changed, 129 insertions(+), 128 deletions(-) diff --git a/code/__defines/species.dm b/code/__defines/species.dm index 0ff09486031..791e81cd17d 100644 --- a/code/__defines/species.dm +++ b/code/__defines/species.dm @@ -8,6 +8,7 @@ #define SPECIES_FLAG_NO_BLOCK BITFLAG(6) // Unable to block or defend itself from attackers. #define SPECIES_FLAG_NEED_DIRECT_ABSORB BITFLAG(7) // This species can only have their DNA taken by direct absorption. #define SPECIES_FLAG_LOW_GRAV_ADAPTED BITFLAG(8) // This species is used to lower than standard gravity, affecting stamina in high-grav +#define SPECIES_FLAG_ABSORB_ELECTRICITY BITFLAG(9) // This species can absorb electricity; snowflake flag for old slime people. // Species spawn flags #define SPECIES_IS_WHITELISTED BITFLAG(0) // Must be whitelisted to play. diff --git a/code/datums/wires/smes.dm b/code/datums/wires/smes.dm index 15eff146d15..7cc90b2d664 100644 --- a/code/datums/wires/smes.dm +++ b/code/datums/wires/smes.dm @@ -9,68 +9,68 @@ new /datum/wire_description(SMES_WIRE_FAILSAFES, "This wire appears to connect to a failsafe mechanism.") ) -var/global/const/SMES_WIRE_RCON = 1 // Remote control (AI and consoles), cut to disable -var/global/const/SMES_WIRE_INPUT = 2 // Input wire, cut to disable input, pulse to disable for 60s -var/global/const/SMES_WIRE_OUTPUT = 4 // Output wire, cut to disable output, pulse to disable for 60s -var/global/const/SMES_WIRE_GROUNDING = 8 // Cut to quickly discharge causing sparks, pulse to only create few sparks -var/global/const/SMES_WIRE_FAILSAFES = 16 // Cut to disable failsafes, mend to reenable - - -/datum/wires/smes/CanUse(var/mob/living/L) - var/obj/machinery/power/smes/buildable/S = holder - if(!S.grounding && S.powernet && S.powernet.avail) - electrocute_mob(L, S.powernet, S, S.safeties_enabled? 0.1 : 1) - if(S.panel_open) - return 1 - return 0 +/// Remote control (AI and consoles), cut to disable +var/global/const/SMES_WIRE_RCON = BITFLAG(0) +/// Input wire, cut to disable input, pulse to disable for 60s +var/global/const/SMES_WIRE_INPUT = BITFLAG(1) +/// Output wire, cut to disable output, pulse to disable for 60s +var/global/const/SMES_WIRE_OUTPUT = BITFLAG(2) +/// Cut to quickly discharge causing sparks, pulse to only create few sparks +var/global/const/SMES_WIRE_GROUNDING = BITFLAG(3) +/// Cut to disable failsafes, mend to reenable +var/global/const/SMES_WIRE_FAILSAFES = BITFLAG(4) +/datum/wires/smes/CanUse(var/mob/living/user) + var/obj/machinery/power/smes/buildable/storage = holder + if(!storage.grounding && storage.powernet && storage.powernet.avail) + electrocute_mob(user, storage.powernet, storage, (storage.safeties_enabled? 0.1 : 1)) + return storage.panel_open /datum/wires/smes/GetInteractWindow(mob/user) - var/obj/machinery/power/smes/buildable/S = holder + var/obj/machinery/power/smes/buildable/storage = holder . += ..() - . += "The green light is [(S.input_cut || S.input_pulsed || S.output_cut || S.output_pulsed) ? "off" : "on"]
" - . += "The red light is [(S.safeties_enabled || S.grounding) ? "off" : "blinking"]
" - . += "The blue light is [S.RCon ? "on" : "off"]" - + . += "The green light is [(storage.input_cut || storage.input_pulsed || storage.output_cut || storage.output_pulsed) ? "off" : "on"]
" + . += "The red light is [(storage.safeties_enabled || storage.grounding) ? "off" : "blinking"]
" + . += "The blue light is [storage.RCon ? "on" : "off"]" /datum/wires/smes/UpdateCut(var/index, var/mended) - var/obj/machinery/power/smes/buildable/S = holder + var/obj/machinery/power/smes/buildable/storage = holder switch(index) if(SMES_WIRE_RCON) - S.RCon = mended + storage.RCon = mended if(SMES_WIRE_INPUT) - S.input_cut = !mended + storage.input_cut = !mended if(SMES_WIRE_OUTPUT) - S.output_cut = !mended + storage.output_cut = !mended if(SMES_WIRE_GROUNDING) - S.grounding = mended + storage.grounding = mended if(SMES_WIRE_FAILSAFES) - S.safeties_enabled = mended + storage.safeties_enabled = mended /datum/wires/smes/proc/reset_rcon() - var/obj/machinery/power/smes/buildable/S = holder - if(S) - S.RCon = TRUE + var/obj/machinery/power/smes/buildable/storage = holder + if(storage) + storage.RCon = TRUE /datum/wires/smes/proc/reset_safeties() - var/obj/machinery/power/smes/buildable/S = holder - if(S) - S.safeties_enabled = TRUE + var/obj/machinery/power/smes/buildable/storage = holder + if(storage) + storage.safeties_enabled = TRUE /datum/wires/smes/UpdatePulsed(var/index) - var/obj/machinery/power/smes/buildable/S = holder + var/obj/machinery/power/smes/buildable/storage = holder switch(index) if(SMES_WIRE_RCON) - if(S.RCon) - S.RCon = 0 + if(storage.RCon) + storage.RCon = 0 addtimer(CALLBACK(src, PROC_REF(reset_rcon)), 1 SECOND) if(SMES_WIRE_INPUT) - S.toggle_input() + storage.toggle_input() if(SMES_WIRE_OUTPUT) - S.toggle_output() + storage.toggle_output() if(SMES_WIRE_GROUNDING) - S.grounding = 0 + storage.grounding = 0 if(SMES_WIRE_FAILSAFES) - if(S.safeties_enabled) - S.safeties_enabled = 0 + if(storage.safeties_enabled) + storage.safeties_enabled = 0 addtimer(CALLBACK(src, PROC_REF(reset_safeties)), 1 SECOND) diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index cfad08854a4..5035124e1b9 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -104,7 +104,7 @@ playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds var/decl/species/walker_species = M.get_species() - if(walker_species && (walker_species.siemens_coefficient<0.5 || (walker_species.species_flags & (SPECIES_FLAG_NO_EMBED|SPECIES_FLAG_NO_MINOR_CUT)))) //Thick skin. + if(walker_species?.species_flags & (SPECIES_FLAG_NO_EMBED|SPECIES_FLAG_NO_MINOR_CUT)) //Thick skin. return var/obj/item/shoes = M.get_equipped_item(slot_shoes_str) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index c5231af0360..43a18ba6657 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -85,7 +85,8 @@ add_overlay(I) /obj/structure/grille/Bumped(atom/user) - if(ismob(user)) shock(user, 70) + if(ismob(user)) + shock(user, 70) /obj/structure/grille/attack_hand(mob/user) @@ -226,25 +227,23 @@ // returns 1 if shocked, 0 otherwise /obj/structure/grille/proc/shock(mob/user, prb) if(!anchored || destroyed) // anchored/destroyed grilles are never connected - return 0 + return FALSE if(!(material.conductive)) - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE if(!in_range(src, user))//To prevent TK and exosuit users from getting shocked - return 0 - var/turf/T = get_turf(src) - var/obj/structure/cable/C = T.get_cable_node() - if(C) - if(electrocute_mob(user, C, src)) - if(C.powernet) - C.powernet.trigger_warning() - spark_at(src, cardinal_only = TRUE) - if(HAS_STATUS(user, STAT_STUN)) - return 1 - else - return 0 - return 0 + return FALSE + var/turf/my_turf = get_turf(src) + var/obj/structure/cable/cable = my_turf.get_cable_node() + if(!cable) + return FALSE + if(!electrocute_mob(user, cable, src)) + return FALSE + if(cable.powernet) + cable.powernet.trigger_warning() + spark_at(src, cardinal_only = TRUE) + return !!HAS_STATUS(user, STAT_STUN) /obj/structure/grille/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(!destroyed) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 1cde56a39dc..6c737fb8fee 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -405,3 +405,9 @@ var/org = GET_EXTERNAL_ORGAN(src, hand_slot) if(org) LAZYDISTINCTADD(., org) + +/mob/proc/get_active_hand_bodypart_flags() + var/datum/inventory_slot/gripper/inv_slot = get_inventory_slot_datum(get_active_held_item_slot()) + if(istype(inv_slot)) + . = inv_slot.covering_slot_flags + . ||= SLOT_HANDS diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index bcfa4ea3505..018ea79c0dc 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -66,29 +66,26 @@ gib() /mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) - if(status_flags & GODMODE) return 0 //godmode - shock_damage = apply_shock(shock_damage, def_zone, siemens_coeff) - - if(!shock_damage) + shock_damage = ..() + if(shock_damage <= 0) return 0 + shock_damage = apply_shock(shock_damage, def_zone, siemens_coeff) stun_effect_act(agony_amount=shock_damage, def_zone=def_zone) - playsound(loc, "sparks", 50, 1, -1) if (shock_damage > 15) - src.visible_message( - "[src] was electrocuted[source ? " by the [source]" : ""]!", \ - "You feel a powerful shock course through your body!", \ - "You hear a heavy electrical crack." \ + visible_message( + SPAN_DANGER("\The [src] was electrocuted[source ? " by the [source]" : ""]!"), + SPAN_DANGER("You feel a powerful shock course through your body!"), + SPAN_DANGER("You hear a heavy electrical crack.") ) else - src.visible_message( - "[src] was shocked[source ? " by the [source]" : ""].", \ - "You feel a shock course through your body.", \ - "You hear a zapping sound." \ + visible_message( + SPAN_DANGER("\The [src] was shocked[source ? " by the [source]" : ""]."), + SPAN_DANGER("You feel a shock course through your body."), + SPAN_DANGER("You hear a zapping sound.") ) - switch(shock_damage) if(11 to 15) SET_STATUS_MAX(src, STAT_STUN, 1) @@ -100,11 +97,8 @@ SET_STATUS_MAX(src, STAT_WEAK, 5) if(31 to INFINITY) SET_STATUS_MAX(src, STAT_WEAK, 10) //This should work for now, more is really silly and makes you lay there forever - set_status(STAT_JITTER, min(shock_damage*5, 200)) - spark_at(loc, amount=5, cardinal_only = TRUE) - return shock_damage /mob/living/carbon/proc/apply_shock(var/shock_damage, var/def_zone, var/siemens_coeff = 1.0) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 7d337970d53..26bb3c64f94 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -85,19 +85,6 @@ meteor_act // Add inherent armor to the end of list so that protective equipment is checked first . += ..() -//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ. -/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone) - if (!def_zone) - return 1.0 - - var/siemens_coefficient = max(species.siemens_coefficient,0) - for(var/slot in global.standard_clothing_slots) - var/obj/item/clothing/C = get_equipped_item(slot) - if(istype(C) && (C.body_parts_covered & def_zone.body_part)) // Is that body part being targeted covered? - siemens_coefficient *= C.siemens_coefficient - - return siemens_coefficient - /mob/living/carbon/human/proc/check_head_coverage() for(var/slot in global.standard_headgear_slots) var/obj/item/clothing/clothes = get_equipped_item(slot) @@ -373,24 +360,6 @@ meteor_act fire_act(air, temperature) return FALSE -//Removed the horrible safety parameter. It was only being used by ninja code anyways. -//Now checks siemens_coefficient of the affected area by default -/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null) - - if(status_flags & GODMODE) return 0 //godmode - - if(species.siemens_coefficient == -1) - if(stored_shock_by_ref["\ref[src]"]) - stored_shock_by_ref["\ref[src]"] += shock_damage - else - stored_shock_by_ref["\ref[src]"] = shock_damage - return - - if (!def_zone) - def_zone = pick(BP_L_HAND, BP_R_HAND) - - return ..(shock_damage, source, base_siemens_coeff, def_zone) - /mob/living/carbon/human/explosion_act(severity) ..() if(QDELETED(src)) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index ddc6d17d8b0..a33044b3ad5 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -97,7 +97,15 @@ apply_effect(agony_amount/10, EYE_BLUR) /mob/living/proc/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, def_zone = null) - return 0 //only carbon liveforms have this proc + SHOULD_CALL_PARENT(TRUE) + if(status_flags & GODMODE) + return 0 + var/decl/species/my_species = get_species() + if(my_species?.species_flags & SPECIES_FLAG_ABSORB_ELECTRICITY) + spark_at(loc, amount=5, cardinal_only = TRUE) + LAZYADD(global.stored_shock_by_ref["\ref[src]"], shock_damage) + return 0 + return shock_damage /mob/living/emp_act(severity) var/list/L = src.get_contents() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index c23a0e0faa4..12ddf623401 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -124,17 +124,21 @@ /mob/living/silicon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, def_zone = null) - if (istype(source, /obj/effect/containment_field)) - spark_at(loc, amount=5, cardinal_only = TRUE) - - shock_damage *= 0.75 //take reduced damage - take_overall_damage(0, shock_damage) - visible_message("\The [src] was shocked by \the [source]!", \ - "Energy pulse detected, system damaged!", \ - "You hear an electrical crack") - if(prob(20)) - SET_STATUS_MAX(src, STAT_STUN, 2) - return + shock_damage = ..() + if(shock_damage <= 0 || !istype(source, /obj/effect/containment_field)) + return 0 + + spark_at(loc, amount=5, cardinal_only = TRUE) + shock_damage *= 0.75 //take reduced damage + take_overall_damage(0, shock_damage) + visible_message( + SPAN_DANGER("\The [src] was shocked by \the [source]!"), + SPAN_DANGER("Energy pulse detected, system damaged!"), + SPAN_DANGER("You hear an electrical crack.") + ) + if(prob(20)) + SET_STATUS_MAX(src, STAT_STUN, 2) + return shock_damage /mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0) return diff --git a/code/modules/mob/mob_damage.dm b/code/modules/mob/mob_damage.dm index 94adae932a9..f52cc527f4c 100644 --- a/code/modules/mob/mob_damage.dm +++ b/code/modules/mob/mob_damage.dm @@ -58,3 +58,24 @@ SHOULD_CALL_PARENT(TRUE) if(do_update_health) update_health() + +// Calculates the Siemen's coefficient for a given area of the body. +// 1 is 100% vulnerability, 0 is immune. +/mob/proc/get_siemens_coefficient_for_coverage(coverage_flags = SLOT_HANDS) + var/decl/species/my_species = get_species() + . = my_species ? my_species.siemens_coefficient : 1 + if(. <= 0) + return 0 + if(coverage_flags) + for(var/obj/item/clothing/clothes in get_equipped_items(include_carried = FALSE)) + if(clothes.body_parts_covered & coverage_flags) + if(clothes.siemens_coefficient <= 0) + return 0 + . *= clothes.siemens_coefficient + if(. <= 0) + return 0 + . = max(round(., 0.1), 0) + +//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ. +/mob/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone) + return (istype(def_zone) && def_zone.body_part) ? get_siemens_coefficient_for_coverage(def_zone.body_part) : 1 diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index d2db88a1164..9642a5abcc7 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -183,7 +183,10 @@ //power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null //source is an object caused electrocuting (airlock, grille, etc) //No animations will be performed by this proc. -/proc/electrocute_mob(mob/living/carbon/M, var/power_source, var/obj/source, var/siemens_coeff = 1.0) +/proc/electrocute_mob(mob/living/carbon/M, power_source, obj/source, siemens_coeff = 1.0, coverage_flags = SLOT_HANDS) + + coverage_flags = M?.get_active_hand_bodypart_flags() || coverage_flags + var/area/source_area if(istype(power_source,/area)) source_area = power_source @@ -214,13 +217,9 @@ //If following checks determine user is protected we won't alarm for long. if(PN) PN.trigger_warning(5) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.species.siemens_coefficient <= 0) - return - var/obj/item/clothing/gloves/G = H.get_equipped_item(slot_gloves_str) - if(istype(G) && G.siemens_coefficient == 0) - return 0 //to avoid spamming with insulated glvoes on + + if(M.get_siemens_coefficient_for_coverage(coverage_flags) <= 0) + return //Checks again. If we are still here subject will be shocked, trigger standard 20 tick warning //Since this one is longer it will override the original one. diff --git a/code/modules/species/species_helpers.dm b/code/modules/species/species_helpers.dm index 5ac85615ad4..6be3e01dd47 100644 --- a/code/modules/species/species_helpers.dm +++ b/code/modules/species/species_helpers.dm @@ -1,9 +1,9 @@ var/global/list/stored_shock_by_ref = list() /mob/living/proc/apply_stored_shock_to(var/mob/living/target) - if(stored_shock_by_ref["\ref[src]"]) - target.electrocute_act(stored_shock_by_ref["\ref[src]"]*0.9, src) - stored_shock_by_ref["\ref[src]"] = 0 + if(global.stored_shock_by_ref["\ref[src]"]) + target.electrocute_act(global.stored_shock_by_ref["\ref[src]"]*0.9, src) + global.stored_shock_by_ref["\ref[src]"] = 0 /decl/species/proc/toggle_stance(var/mob/living/carbon/human/H) if(!H.incapacitated())