Fixes xenos being able to pick up items that they shouldn't by most means, expands itempicky component functionality (#86714)

## About The Pull Request

Xenos can apparently use shenanigans such as
https://github.com/tgstation/tgstation/issues/86703 to put some items in
their hand, and there are likely methods like this dotted around the
codebase. However, the signal to put something in their hand is called
consistently across any process that would cause them to pick up or
otherwise have something to put in their hand, so instead I added
/datum/component/itempicky to xenos.

While I was in there, I expanded the functionality of itempicky; it can
run a callback to determine a condition that needs to be met now.

## Why It's Good For The Game

Fixes https://github.com/tgstation/tgstation/issues/86703
Expands a component's usefulness
## Changelog
🆑 Bisar
fix: Xenomorph restrictions on items they can pick up have had their
determining logic made more _robust_.
code: The itempicky component (restricts what can be picked up via a
whitelist) can now, optionally, have a callback fed to it to determine
cases of bypassing that whitelist.
/🆑

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
This commit is contained in:
Joshua Kidder
2024-09-18 17:38:07 -04:00
committed by GitHub
parent 9af9189615
commit 240e397b95
8 changed files with 26 additions and 11 deletions

View File

@@ -5,13 +5,21 @@
var/whitelist
/// Message shown if you try to pick up an item not in the whitelist
var/message = "You don't like %TARGET, why would you hold it?"
/// An optional callback we check for overriding our whitelist
var/datum/callback/tertiary_condition = null
/datum/component/itempicky/Initialize(whitelist, message)
/datum/component/itempicky/Initialize(whitelist, message, tertiary_condition)
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
src.whitelist = whitelist
if(message)
src.message = message
if(tertiary_condition)
src.tertiary_condition = tertiary_condition
/datum/component/itempicky/Destroy(force)
tertiary_condition = null
return ..()
/datum/component/itempicky/RegisterWithParent()
RegisterSignal(parent, COMSIG_LIVING_TRY_PUT_IN_HAND, PROC_REF(particularly))
@@ -30,6 +38,7 @@
/datum/component/itempicky/proc/particularly(datum/source, obj/item/pickingup)
SIGNAL_HANDLER
if(!is_type_in_typecache(pickingup, whitelist))
// if we were passed the output of a callback, check against that
if(!tertiary_condition?.Invoke() && !is_type_in_typecache(pickingup, whitelist))
to_chat(source, span_warning("[replacetext(message, "%TARGET", pickingup)]"))
return COMPONENT_LIVING_CANT_PUT_IN_HAND

View File

@@ -633,7 +633,7 @@
/obj/item/attack_alien(mob/user, list/modifiers)
var/mob/living/carbon/alien/ayy = user
if(!user.can_hold_items(src))
if(!ayy.can_hold_items(src))
if(src in ayy.contents) // To stop Aliens having items stuck in their pockets
ayy.dropItemToGround(src)
to_chat(user, span_warning("Your claws aren't capable of such fine manipulation!"))

View File

@@ -25,7 +25,7 @@
throw_range = 3
pressure_resistance = 0
item_flags = NOBLUDGEON | XENOMORPH_HOLDABLE //funny ~Jimmyl
item_flags = NOBLUDGEON
w_class = WEIGHT_CLASS_TINY
/// `list` or `null`, contains possible alternate `icon_states`.

View File

@@ -1134,7 +1134,6 @@
name = "xenomorph action figure"
desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use."
w_class = WEIGHT_CLASS_SMALL
item_flags = XENOMORPH_HOLDABLE
var/cooldown = 0
/obj/item/toy/toy_xeno/attack_self(mob/user)

View File

@@ -8,7 +8,6 @@
inhand_icon_state = "basketball"
desc = "Here's your chance, do your dance at the Space Jam."
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
item_flags = XENOMORPH_HOLDABLE // playing ball against a xeno is rigged since they cannot be disarmed
/// The person dribbling the basketball
var/mob/living/wielder
/// So the basketball doesn't make sound every step

View File

@@ -23,6 +23,13 @@
unique_name = TRUE
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
var/static/list/xeno_allowed_items = typecacheof(list(
/obj/item/clothing/mask/facehugger,
/obj/item/toy/basketball, // playing ball against a xeno is rigged since they cannot be disarmed, their game is out of this world
/obj/item/toy/toy_xeno,
/obj/item/sticker, //funny ~Jimmyl
/obj/item/toy/plush/rouny,
))
/mob/living/carbon/alien/Initialize(mapload)
add_verb(src, /mob/living/proc/mob_sleep)
@@ -37,6 +44,11 @@
. = ..()
if(alien_speed)
update_alien_speed()
LoadComponent( \
/datum/component/itempicky, \
xeno_allowed_items, \
span_alien("Your claws lack the dexterity to hold %TARGET."), \
CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_has_trait), src, TRAIT_ADVANCEDTOOLUSER))
/mob/living/carbon/alien/create_internal_organs()
organs += new /obj/item/organ/internal/brain/alien
@@ -154,9 +166,6 @@ Des: Removes all infected images from the alien.
set_name()
/mob/living/carbon/alien/can_hold_items(obj/item/I)
return (I && (I.item_flags & XENOMORPH_HOLDABLE || ISADVANCEDTOOLUSER(src)) && ..())
/mob/living/carbon/alien/on_lying_down(new_lying_angle)
. = ..()
update_icons()

View File

@@ -23,7 +23,6 @@
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
layer = MOB_LAYER
max_integrity = 100
item_flags = XENOMORPH_HOLDABLE
slowdown = 2
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case

View File

@@ -181,7 +181,7 @@
/obj/item/modular_computer/pda/proc/remove_pen(mob/user)
if(issilicon(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) //TK doesn't work even with this removed but here for readability
if(issilicon(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH | NEED_DEXTERITY)) //TK doesn't work even with this removed but here for readability
return
if(inserted_item)