Files
Bubberstation/code/datums/components/pinnable_accessory.dm
SkyratBot 847b347819 [MIRROR] Adds new black market pin [MDB IGNORE] (#25569)
* Adds new black market pin (#80230)

## About The Pull Request

![image](https://github.com/tgstation/tgstation/assets/7483112/add49cea-8318-475b-985e-3cb14a1d39db)

Adds a fetching red pin which you can wear to visibly align yourself
with the enemies of Nanotrasen, purchaseable from the Black Market
Uplink.
This pin's contained RFID chip will automatically cause you to appear on
Sec HUDs as a wanted criminal and will aggro securitrons, to prove your
dedication to your ideals.

If your convictions are a little less firm, you can also silently pin
this onto _other_ people's clothing if they stand still next to you for
five seconds... though they might notice that they're suddenly wearing a
red badge.

I didn't want this to be a subtype of medal so I made the "you can put
this accessory onto someone else" behaviour into a component to sidestep
object inheritance.
This has been applied to the detective's spy camera, because it makes it
much easier to turn someone into a mole.

This also adds a trait which makes security hate you which I guess
someone could use in a novelty bar drink at some point or something.

## Why It's Good For The Game

It's funny
I think we need more neat things in the black market to make it
sometimes worth using

## Changelog

🆑
add: Added subversive pins to the black market uplink which make
security hate you
add: The detective's spy cam can now be conveniently pinned onto people
in the same manner as medals
/🆑

* Adds new black market pin

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
2023-12-12 12:01:47 -05:00

81 lines
3.1 KiB
Plaintext

/// This accessory can be pinned onto someone else
/datum/component/pinnable_accessory
/// Do we let people know what we're doing?
var/silent
/// How long does it take to pin this onto someone?
var/pinning_time
/// Optional callback invoked before pinning, will cancel if it returns FALSE
var/datum/callback/on_pre_pin
/datum/component/pinnable_accessory/Initialize(silent = FALSE, pinning_time = 2 SECONDS, datum/callback/on_pre_pin = null)
. = ..()
if (!istype(parent, /obj/item/clothing/accessory))
return COMPONENT_INCOMPATIBLE
src.silent = silent
src.pinning_time = pinning_time
src.on_pre_pin = on_pre_pin
/datum/component/pinnable_accessory/RegisterWithParent()
RegisterSignal(parent, COMSIG_ITEM_INTERACTING_WITH_ATOM, PROC_REF(on_atom_interact))
/datum/component/pinnable_accessory/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_ITEM_INTERACTING_WITH_ATOM)
/// Called when you whack someone with this accessory
/datum/component/pinnable_accessory/proc/on_atom_interact(obj/item/clothing/accessory/badge, mob/living/user, atom/target, modifiers)
SIGNAL_HANDLER
if (!ishuman(target) || target == user)
return
INVOKE_ASYNC(src, PROC_REF(try_to_pin), badge, target, user)
return COMPONENT_CANCEL_ATTACK_CHAIN
/// Actually try to pin it on
/datum/component/pinnable_accessory/proc/try_to_pin(obj/item/clothing/accessory/badge, mob/living/carbon/human/distinguished, mob/user)
var/obj/item/clothing/under/distinguished_uniform = distinguished.w_uniform
if(!istype(distinguished_uniform))
distinguished.balloon_alert(user, "no uniform to pin on!")
return
if(!badge.can_attach_accessory(distinguished_uniform, user))
// Check handles feedback messages and etc
return
if (!silent)
user.visible_message(
span_notice("[user] tries to pin [badge] on [distinguished]'s chest."),
span_notice("You try to pin [badge] on [distinguished]'s chest."),
)
if (on_pre_pin && !on_pre_pin.Invoke(distinguished, user))
return
if(!pin_checks(user, distinguished) || !do_after(user, pinning_time, distinguished, extra_checks = CALLBACK(src, PROC_REF(pin_checks), user, distinguished)))
return
var/pinned = distinguished_uniform.attach_accessory(badge, user)
if (silent)
return
if (pinned)
user.visible_message(
span_notice("[user] pins [badge] on [distinguished]'s chest."),
span_notice("You pin [badge] on [distinguished]'s chest."),
)
else
user.visible_message(
span_warning("[user] fails to pin [badge] on [distinguished]'s chest, seemingly unable to part with it."),
span_warning("You fail to pin [badge] on [distinguished]'s chest."),
)
/// Callback for do_after to check if we can still be pinned
/datum/component/pinnable_accessory/proc/pin_checks(mob/living/pinner, mob/living/carbon/human/pinning_on)
if(QDELETED(parent) || QDELETED(pinner) || QDELETED(pinning_on))
return FALSE
if(!pinner.is_holding(parent) || !pinner.Adjacent(pinning_on))
return FALSE
var/obj/item/clothing/accessory/badge = parent
var/obj/item/clothing/under/pinning_on_uniform = pinning_on.w_uniform
if(!istype(pinning_on_uniform) || !badge.can_attach_accessory(pinning_on_uniform, pinner))
return FALSE
return TRUE