From 4664b630c56df041136c0141c35b976285d6ce0f Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Fri, 8 Nov 2024 15:12:48 +0000 Subject: [PATCH] Living Flesh limbs won't try to grab underfloor objects (#87736) ## About The Pull Request There were checks in living limbs that were checking the wrong thing, at least one of which was introduced by a feature change in a PR I merged but didn't notice. Notably: - We were checking if the person with the limb was invisible, not the thing they were trying to touch. - We were checking if the person with the limb was anchored, not the thing they were trying to grab. Now your arm will no longer reach out and grab wires that are under the floor. Additionally to this: - I made all of the output say "Your left arm" or "Your left leg" instead of "Your flesh left leg" because it sounded stupid. - I removed an unused argument from `can_be_pulled` because it was confusing me when I looked at the proc. - I reworded some of the user feedback messages because "the thing pretending to be your left arm feels funny" just isn't very evocative. The diff is long because I reversed the order of arm/leg operations because the leg block is much smaller :clueless: ## Why It's Good For The Game Fixes bug. I like it more. ## Changelog :cl: fix: Living Limbs no longer try to grab things that are under the floor. spellcheck: Living Limb feedback messages now don't redundantly specify that they are flesh arms. /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- code/datums/components/wormborn.dm | 2 +- code/game/atoms_movable.dm | 4 +- code/game/machinery/doors/airlock.dm | 2 +- code/game/objects/items/theft_tools.dm | 2 +- .../mob/living/basic/heretic/flesh_worm.dm | 2 +- .../mob/living/basic/pets/orbie/orbie.dm | 2 +- .../mob/living/basic/ruin_defender/flesh.dm | 72 ++++++++++--------- code/modules/mob/living/living.dm | 4 +- code/modules/religion/religion_structures.dm | 2 +- 9 files changed, 50 insertions(+), 42 deletions(-) diff --git a/code/datums/components/wormborn.dm b/code/datums/components/wormborn.dm index 1841dbf38cc3e..05f833fc28fcd 100644 --- a/code/datums/components/wormborn.dm +++ b/code/datums/components/wormborn.dm @@ -50,7 +50,7 @@ /mob/living/basic/wizard_worm/has_gravity(turf/gravity_turf) return TRUE -/mob/living/basic/wizard_worm/can_be_pulled() +/mob/living/basic/wizard_worm/can_be_pulled(user, force) return FALSE /mob/living/basic/wizard_worm/Initialize(mapload, spawn_bodyparts = TRUE) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 8acbf59b4d821..10aa07e624232 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -514,7 +514,7 @@ /atom/movable/proc/start_pulling(atom/movable/pulled_atom, state, force = move_force, supress_message = FALSE) if(QDELETED(pulled_atom)) return FALSE - if(!(pulled_atom.can_be_pulled(src, state, force))) + if(!(pulled_atom.can_be_pulled(src, force))) return FALSE // If we're pulling something then drop what we're currently pulling and pull this instead. @@ -1643,7 +1643,7 @@ /atom/movable/proc/get_cell(atom/movable/interface, mob/user) return -/atom/movable/proc/can_be_pulled(user, grab_state, force) +/atom/movable/proc/can_be_pulled(user, force) if(src == user || !isturf(loc)) return FALSE if(SEND_SIGNAL(src, COMSIG_ATOM_CAN_BE_PULLED, user) & COMSIG_ATOM_CANT_PULL) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 04f67cee1c1ba..39909c64cf994 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1816,7 +1816,7 @@ if(istype(mover) && (mover.pass_flags & PASSGLASS)) return !opacity -/obj/structure/fluff/airlock_filler/can_be_pulled(user, grab_state, force) +/obj/structure/fluff/airlock_filler/can_be_pulled(user, force) return FALSE /obj/structure/fluff/airlock_filler/singularity_act() diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index a2efbe2d4beba..6f09f58169521 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -161,7 +161,7 @@ /obj/item/nuke_core/supermatter_sliver/attack_tk(mob/user) // no TK dusting memes return -/obj/item/nuke_core/supermatter_sliver/can_be_pulled(user) // no drag memes +/obj/item/nuke_core/supermatter_sliver/can_be_pulled(user, force) // no drag memes return FALSE /obj/item/nuke_core/supermatter_sliver/attackby(obj/item/W, mob/living/user, params) diff --git a/code/modules/mob/living/basic/heretic/flesh_worm.dm b/code/modules/mob/living/basic/heretic/flesh_worm.dm index cddd34ba44184..13372c726887e 100644 --- a/code/modules/mob/living/basic/heretic/flesh_worm.dm +++ b/code/modules/mob/living/basic/heretic/flesh_worm.dm @@ -56,7 +56,7 @@ /mob/living/basic/heretic_summon/armsy/has_gravity(turf/gravity_turf) return TRUE -/mob/living/basic/heretic_summon/armsy/can_be_pulled() +/mob/living/basic/heretic_summon/armsy/can_be_pulled(user, force) return FALSE // The component does this but not on the head. We don't want the head to be pulled either. /mob/living/basic/heretic_summon/armsy/proc/build_tail(worm_length) diff --git a/code/modules/mob/living/basic/pets/orbie/orbie.dm b/code/modules/mob/living/basic/pets/orbie/orbie.dm index 85d82e92515f0..b4099a8c6344c 100644 --- a/code/modules/mob/living/basic/pets/orbie/orbie.dm +++ b/code/modules/mob/living/basic/pets/orbie/orbie.dm @@ -77,7 +77,7 @@ happy_state = !happy_state update_appearance() -/mob/living/basic/orbie/can_be_pulled(user, grab_state, force) +/mob/living/basic/orbie/can_be_pulled(user, force) return FALSE /mob/living/basic/orbie/proc/on_level_up(datum/source, new_level) diff --git a/code/modules/mob/living/basic/ruin_defender/flesh.dm b/code/modules/mob/living/basic/ruin_defender/flesh.dm index c5ff2fb90e740..550484a75c51d 100644 --- a/code/modules/mob/living/basic/ruin_defender/flesh.dm +++ b/code/modules/mob/living/basic/ruin_defender/flesh.dm @@ -1,4 +1,10 @@ +/// Chance per second to print a warning text +#define LIVING_FLESH_WARN_CHANCE 3 +/// Chance per second to perform an unwanted interaction +#define LIVING_FLESH_INTERFERENCE_CHANCE 1.5 +/// Chance to caress instead of grab something nearby without combat mode #define LIVING_FLESH_TOUCH_CHANCE 30 +/// Chance to punch instead of grab something nearby in combat mode #define LIVING_FLESH_COMBAT_TOUCH_CHANCE 70 /datum/ai_controller/basic_controller/living_limb_flesh @@ -59,47 +65,47 @@ if(isnull(current_bodypart) || isnull(current_bodypart.owner)) return var/mob/living/carbon/human/victim = current_bodypart.owner - if(SPT_PROB(3, SSMOBS_DT)) - to_chat(victim, span_warning("The thing posing as your limb makes you feel funny...")) //warn em - //firstly as a sideeffect we drain nutrition from our host + if(SPT_PROB(LIVING_FLESH_WARN_CHANCE, SSMOBS_DT)) + to_chat(victim, span_warning("The skin on your [current_bodypart.plaintext_zone] crawls.")) + victim.adjust_nutrition(-1.5) - if(!SPT_PROB(1.5, SSMOBS_DT)) + if(!SPT_PROB(LIVING_FLESH_INTERFERENCE_CHANCE, SSMOBS_DT)) return - if(istype(current_bodypart, /obj/item/bodypart/arm)) - var/list/candidates = list() - for(var/atom/movable/movable in orange(victim, 1)) - if(movable == victim) - continue - if(!victim.CanReach(movable) || victim.invisibility) - continue - candidates += movable - if(!length(candidates)) - return - var/atom/movable/candidate = pick(candidates) - if(isnull(candidate)) - return - - victim.visible_message(span_warning("[victim]'s [current_bodypart.name] instinctively starts feeling [candidate]!")) - if (!victim.anchored && !prob(victim.combat_mode ? LIVING_FLESH_COMBAT_TOUCH_CHANCE : LIVING_FLESH_TOUCH_CHANCE)) - INVOKE_ASYNC(victim, TYPE_PROC_REF(/atom/movable, start_pulling), candidate, supress_message = TRUE) + if(istype(current_bodypart, /obj/item/bodypart/leg)) + if(HAS_TRAIT(victim, TRAIT_IMMOBILIZED)) return + step(victim, pick(GLOB.cardinals)) + to_chat(victim, span_warning("Your [current_bodypart.plaintext_zone] moves on its own!")) + return - var/active_hand = victim.active_hand_index - var/new_index = (current_bodypart.body_zone == BODY_ZONE_L_ARM) ? LEFT_HANDS : RIGHT_HANDS - if (active_hand != new_index) - victim.swap_hand(new_index, TRUE) - victim.resolve_unarmed_attack(candidate) - if (active_hand != victim.active_hand_index) // Different check in case we failed to swap hands previously due to holding a bulky item - victim.swap_hand(active_hand, TRUE) + var/list/candidates = list() + for(var/atom/movable/movable in orange(victim, 1)) + if(movable == victim) + continue + if(!victim.CanReach(movable) || movable.invisibility > victim.see_invisible) + continue + candidates += movable + if(!length(candidates)) + return + var/atom/movable/candidate = pick(candidates) + if(isnull(candidate)) return - if(HAS_TRAIT(victim, TRAIT_IMMOBILIZED)) + if (!prob(victim.combat_mode ? LIVING_FLESH_COMBAT_TOUCH_CHANCE : LIVING_FLESH_TOUCH_CHANCE) && candidate.can_be_pulled(user = victim, force = victim.pull_force)) + victim.visible_message(span_warning("[victim]'s [current_bodypart.plaintext_zone] suddenly fastens around [candidate]!")) + INVOKE_ASYNC(victim, TYPE_PROC_REF(/atom/movable, start_pulling), candidate, supress_message = TRUE) return - step(victim, pick(GLOB.cardinals)) - to_chat(victim, span_warning("Your [current_bodypart] moves on its own!")) + victim.visible_message(span_warning("[victim]'s [current_bodypart.plaintext_zone] suddenly spasms towards [candidate]!")) + var/active_hand = victim.active_hand_index + var/new_index = (current_bodypart.body_zone == BODY_ZONE_L_ARM) ? LEFT_HANDS : RIGHT_HANDS + if (active_hand != new_index) + victim.swap_hand(new_index, TRUE) + victim.resolve_unarmed_attack(candidate) + if (active_hand != victim.active_hand_index) // Different check in case we failed to swap hands previously due to holding a bulky item + victim.swap_hand(active_hand, TRUE) /mob/living/basic/living_limb_flesh/melee_attack(mob/living/carbon/human/target, list/modifiers, ignore_cooldown) . = ..() @@ -157,7 +163,7 @@ if(!detach_self()) return var/turf/our_location = get_turf(src) - our_location.visible_message(span_warning("[part_owner][part_owner.p_s()] [current_bodypart] begins to convulse wildly!")) + our_location.visible_message(span_warning("[part_owner][part_owner.p_s()] [current_bodypart.plaintext_zone] begins to convulse wildly!")) /mob/living/basic/living_limb_flesh/proc/owner_died(datum/source, gibbed) SIGNAL_HANDLER @@ -200,3 +206,5 @@ #undef LIVING_FLESH_TOUCH_CHANCE #undef LIVING_FLESH_COMBAT_TOUCH_CHANCE +#undef LIVING_FLESH_WARN_CHANCE +#undef LIVING_FLESH_INTERFERENCE_CHANCE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 01b8bb300ea3b..c0d2e1d4785c0 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -373,7 +373,7 @@ /mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE) if(!AM || !src) return FALSE - if(!(AM.can_be_pulled(src, state, force))) + if(!(AM.can_be_pulled(src, force))) return FALSE if(throwing || !(mobility_flags & MOBILITY_PULL)) return FALSE @@ -1890,7 +1890,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) "[C] leaps out of [src]'s way!"))) C.Paralyze(40) -/mob/living/can_be_pulled() +/mob/living/can_be_pulled(user, force) return ..() && !(buckled?.buckle_prevents_pull) diff --git a/code/modules/religion/religion_structures.dm b/code/modules/religion/religion_structures.dm index 1b30d021268cf..8c8783f16eb71 100644 --- a/code/modules/religion/religion_structures.dm +++ b/code/modules/religion/religion_structures.dm @@ -109,7 +109,7 @@ new /obj/effect/decal/cleanable/ash(drop_location()) qdel(src) -/obj/item/ritual_totem/can_be_pulled(user, grab_state, force) +/obj/item/ritual_totem/can_be_pulled(user, force) . = ..() return FALSE //no