Files
Bubberstation/code/datums/components/itempicky.dm
Joshua Kidder 240e397b95 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>
2024-09-18 23:38:07 +02:00

45 lines
1.6 KiB
Plaintext

/// You can only hold whitelisted items
/datum/component/itempicky
can_transfer = TRUE
/// Typecache of items you can hold
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, 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))
/datum/component/itempicky/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_LIVING_TRY_PUT_IN_HAND)
/datum/component/itempicky/PostTransfer()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
/datum/component/itempicky/InheritComponent(datum/component/itempicky/friend, i_am_original, list/arguments)
if(i_am_original)
whitelist = friend.whitelist
message = friend.message
/datum/component/itempicky/proc/particularly(datum/source, obj/item/pickingup)
SIGNAL_HANDLER
// 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