mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 09:08:30 +01:00
[MIRROR] Bibles, Lighters, and Cowboy Hats can block bullets [MDB IGNORE] (#22282)
* 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. /🆑 * Bibles, Lighters, and Cowboy Hats can block bullets --------- Co-authored-by: Jacquerel <hnevard@gmail.com> Co-authored-by: Bloop <vinylspiders@gmail.com>
This commit is contained in:
co-authored by
Jacquerel
Bloop
parent
08ddf2a09e
commit
4a779bb4b6
@@ -352,6 +352,7 @@
|
||||
#define COMSIG_PROJECTILE_FIRE "projectile_fire"
|
||||
///sent to targets during the process_hit proc of projectiles
|
||||
#define COMSIG_PROJECTILE_PREHIT "com_proj_prehit"
|
||||
#define PROJECTILE_INTERRUPT_HIT (1<<0)
|
||||
///from the base of /obj/projectile/Range(): ()
|
||||
#define COMSIG_PROJECTILE_RANGE "projectile_range"
|
||||
///from the base of /obj/projectile/on_range(): ()
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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
|
||||
@@ -740,8 +740,23 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
. = ..()
|
||||
if(!overlay_state)
|
||||
overlay_state = pick(overlay_list)
|
||||
AddComponent(\
|
||||
/datum/component/bullet_intercepting,\
|
||||
block_chance = 0.5,\
|
||||
active_slots = ITEM_SLOT_SUITSTORE,\
|
||||
on_intercepted = CALLBACK(src, PROC_REF(on_intercepted_bullet)),\
|
||||
)
|
||||
update_appearance()
|
||||
|
||||
/// Destroy the lighter when it's shot by a bullet
|
||||
/obj/item/lighter/proc/on_intercepted_bullet(mob/living/victim, obj/projectile/bullet)
|
||||
victim.visible_message(span_warning("\The [bullet] shatters on [victim]'s lighter!"))
|
||||
playsound(victim, get_sfx(SFX_RICOCHET), 100, TRUE)
|
||||
new /obj/effect/decal/cleanable/oil(get_turf(src))
|
||||
do_sparks(1, TRUE, src)
|
||||
victim.dropItemToGround(src, force = TRUE, silent = TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/lighter/cyborg_unequip(mob/user)
|
||||
if(!lit)
|
||||
return
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
name = "Bounty Hunter - Armored"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
back = /obj/item/storage/backpack
|
||||
head = /obj/item/clothing/head/cowboy
|
||||
head = /obj/item/clothing/head/cowboy/bounty
|
||||
suit = /obj/item/clothing/suit/space/hunter
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol/fire_mag
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
|
||||
@@ -99,6 +99,24 @@
|
||||
inhand_icon_state = null
|
||||
armor_type = /datum/armor/head_cowboy
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
/// Chance that the hat will catch a bullet for you
|
||||
var/deflect_chance = 2
|
||||
|
||||
/obj/item/clothing/head/cowboy/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(\
|
||||
/datum/component/bullet_intercepting,\
|
||||
block_chance = deflect_chance,\
|
||||
active_slots = ITEM_SLOT_HEAD,\
|
||||
on_intercepted = CALLBACK(src, PROC_REF(on_intercepted_bullet)),\
|
||||
)
|
||||
|
||||
/// When we catch a bullet, fling away
|
||||
/obj/item/clothing/head/cowboy/proc/on_intercepted_bullet(mob/living/victim, obj/projectile/bullet)
|
||||
victim.visible_message(span_warning("\The [bullet] sends [victim]'s hat flying!"))
|
||||
victim.dropItemToGround(src, force = TRUE, silent = TRUE)
|
||||
throw_at(get_edge_target_turf(loc, pick(GLOB.alldirs)), range = 3, speed = 3)
|
||||
playsound(victim, get_sfx(SFX_RICOCHET), 100, TRUE)
|
||||
|
||||
/datum/armor/head_cowboy
|
||||
melee = 5
|
||||
@@ -106,6 +124,10 @@
|
||||
laser = 5
|
||||
energy = 15
|
||||
|
||||
/// Bounty hunter's hat, very likely to intercept bullets
|
||||
/obj/item/clothing/head/cowboy/bounty
|
||||
deflect_chance = 50
|
||||
|
||||
/obj/item/clothing/head/cowboy/black
|
||||
name = "desperado hat"
|
||||
desc = "People with ropes around their necks don't always hang."
|
||||
|
||||
@@ -77,12 +77,39 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
unique = TRUE
|
||||
/// Deity this bible is related to
|
||||
var/deity_name = "Space Jesus"
|
||||
/// Component which catches bullets for us
|
||||
var/datum/component/bullet_catcher
|
||||
|
||||
/obj/item/book/bible/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, MAGIC_RESISTANCE_HOLY)
|
||||
bullet_catcher = AddComponent(\
|
||||
/datum/component/bullet_intercepting,\
|
||||
active_slots = ITEM_SLOT_SUITSTORE,\
|
||||
on_intercepted = CALLBACK(src, PROC_REF(on_intercepted_bullet)),\
|
||||
)
|
||||
carve_out()
|
||||
|
||||
/obj/item/book/bible/Destroy(force)
|
||||
QDEL_NULL(bullet_catcher)
|
||||
return ..()
|
||||
|
||||
/// Destroy the bible when it's shot by a bullet
|
||||
/obj/item/book/bible/proc/on_intercepted_bullet(mob/living/victim, obj/projectile/bullet)
|
||||
victim.add_mood_event("blessing", /datum/mood_event/blessing)
|
||||
playsound(victim, 'sound/magic/magic_block_holy.ogg', 50, TRUE)
|
||||
victim.visible_message(span_warning("\The [src] takes \the [bullet] in [victim]'s place!"))
|
||||
var/obj/structure/fluff/paper/stack/pages = new(get_turf(src))
|
||||
pages.dir = pick(GLOB.alldirs)
|
||||
name = "punctured bible"
|
||||
desc = "A memento of good luck, or perhaps divine intervention?"
|
||||
icon_state = "shot"
|
||||
if (!GLOB.bible_icon_state)
|
||||
GLOB.bible_icon_state = "shot" // New symbol of your religion if you hadn't picked one
|
||||
atom_storage?.remove_all(get_turf(src))
|
||||
QDEL_NULL(atom_storage)
|
||||
QDEL_NULL(bullet_catcher)
|
||||
|
||||
/obj/item/book/bible/examine(mob/user)
|
||||
. = ..()
|
||||
if(deity_name)
|
||||
|
||||
@@ -503,7 +503,9 @@
|
||||
return process_hit(T, select_target(T, target, bumped), bumped, hit_something) // try to hit something else
|
||||
// at this point we are going to hit the thing
|
||||
// in which case send signal to it
|
||||
SEND_SIGNAL(target, COMSIG_PROJECTILE_PREHIT, args)
|
||||
if (SEND_SIGNAL(target, COMSIG_PROJECTILE_PREHIT, args, src) & PROJECTILE_INTERRUPT_HIT)
|
||||
qdel(src)
|
||||
return BULLET_ACT_BLOCK
|
||||
if(mode == PROJECTILE_PIERCE_HIT)
|
||||
++pierces
|
||||
hit_something = TRUE
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.7 KiB |
@@ -961,6 +961,7 @@
|
||||
#include "code\datums\components\blood_walk.dm"
|
||||
#include "code\datums\components\bloodysoles.dm"
|
||||
#include "code\datums\components\boomerang.dm"
|
||||
#include "code\datums\components\bullet_intercepting.dm"
|
||||
#include "code\datums\components\bumpattack.dm"
|
||||
#include "code\datums\components\burning.dm"
|
||||
#include "code\datums\components\butchering.dm"
|
||||
|
||||
Reference in New Issue
Block a user