Files
Bubberstation/code/datums/components/bullet_intercepting.dm
Jacquerel e2de2046b5 Bibles, Lighters, and Cowboy Hats can block bullets (#76521)
## About The Pull Request

If you are wearing a bible or lighter in your suit slot, or a cowboy hat
on your head, there is a small (2%) chance that bullets (only bullets,
not lasers) will hit them instead of you.
This destroys lighters, removes the storage capacity of the bible, or
sends the hat flying off your head.

The Bounty Hunter's cowboy hat has a significantly higher chance to
intercept bullets.

## Why It's Good For The Game

Adds some fun flavour to these items.

## Changelog

🆑
add: A bible or lighter in your suit slot, or cowboy hat on your head
will occasionally intercept a bullet.
/🆑
2023-07-07 18:36:04 +08:00

68 lines
2.2 KiB
Plaintext

/**
* Component which allows an equipped item to occasionally absorb a projectile.
*/
/datum/component/bullet_intercepting
/// Chance to intercept a projectile
var/block_chance
/// Type of bullet to intercept
var/block_type
/// Slots in which effect can be active
var/active_slots
/// Person currently wearing us
var/mob/wearer
/// Callback called when we catch a projectile
var/datum/callback/on_intercepted
/datum/component/bullet_intercepting/Initialize(block_chance = 2, block_type = BULLET, active_slots, datum/callback/on_intercepted)
. = ..()
if (!isitem(parent))
return COMPONENT_INCOMPATIBLE
src.block_chance = block_chance
src.block_type = block_type
src.active_slots = active_slots
src.on_intercepted = on_intercepted
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_parent_equipped))
RegisterSignal(parent, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(on_unequipped))
/datum/component/bullet_intercepting/Destroy(force, silent)
QDEL_NULL(on_intercepted)
return ..()
/// Called when item changes slots, check if we're in a valid location to take bullets
/datum/component/bullet_intercepting/proc/on_parent_equipped(obj/item/clothing/source, mob/equipper, slot)
SIGNAL_HANDLER
if (wearer)
if (!(active_slots & slot))
on_unequipped()
return
if (!(active_slots & slot))
return
RegisterSignal(equipper, COMSIG_PROJECTILE_PREHIT, PROC_REF(on_wearer_shot))
RegisterSignal(equipper, COMSIG_QDELETING, PROC_REF(on_wearer_deleted))
wearer = equipper
/// Called when item is unequipped, stop tracking bullets
/datum/component/bullet_intercepting/proc/on_unequipped()
SIGNAL_HANDLER
if (!wearer)
return
UnregisterSignal(wearer, list(COMSIG_PROJECTILE_PREHIT, COMSIG_QDELETING))
wearer = null
/// Called when wearer is shot, check if we're going to block the hit
/datum/component/bullet_intercepting/proc/on_wearer_shot(mob/living/victim, list/signal_args, obj/projectile/bullet)
SIGNAL_HANDLER
if (victim != wearer || victim.stat == DEAD || bullet.armor_flag != block_type )
return
if (!prob(block_chance))
return
on_intercepted?.Invoke(victim, bullet)
return PROJECTILE_INTERRUPT_HIT
/// Called when wearer is deleted, stop tracking them
/datum/component/bullet_intercepting/proc/on_wearer_deleted()
SIGNAL_HANDLER
wearer = null