From 3fccc7e24e4029210a638f81f9b6bcc0495abefc Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 14:25:53 +1100 Subject: [PATCH 1/2] 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 6992db4bd50ae945f0bba7e4928c0cf012b008a6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 23 Jan 2025 17:29:55 +1100 Subject: [PATCH 2/2] 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