mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-14 19:51:59 +00:00
126 lines
4.4 KiB
Plaintext
126 lines
4.4 KiB
Plaintext
/// -- Plant backfire element --
|
|
/// Certain high-danger plants, like death-nettles, will backfire and harm the holder if they're not properly protected.
|
|
/// If a user is protected with something like leather gloves, they can handle them normally.
|
|
/// If they're not protected properly, we invoke a callback on the user, harming or inconveniencing them.
|
|
/datum/element/plant_backfire
|
|
element_flags = ELEMENT_BESPOKE
|
|
argument_hash_start_idx = 2
|
|
/// Whether we stop the current action if backfire is triggered (EX: returning CANCEL_ATTACK_CHAIN)
|
|
var/cancel_action = FALSE
|
|
/// Any extra traits we want to check in addition to TRAIT_PLANT_SAFE. Mobs with a trait in this list will be considered safe. List of traits.
|
|
var/extra_traits
|
|
/// Any plant genes we want to check that are required for our plant to be dangerous. Plants without a gene in this list will be considered safe. List of typepaths.
|
|
var/extra_genes
|
|
|
|
/datum/element/plant_backfire/Attach(datum/target, cancel_action = FALSE, extra_traits, extra_genes)
|
|
. = ..()
|
|
if(!isitem(target))
|
|
return ELEMENT_INCOMPATIBLE
|
|
|
|
src.cancel_action = cancel_action
|
|
src.extra_traits = extra_traits
|
|
src.extra_genes = extra_genes
|
|
|
|
RegisterSignal(target, COMSIG_ITEM_PRE_ATTACK, PROC_REF(attack_safety_check))
|
|
RegisterSignal(target, COMSIG_ITEM_PICKUP, PROC_REF(pickup_safety_check))
|
|
RegisterSignal(target, COMSIG_MOVABLE_PRE_THROW, PROC_REF(throw_safety_check))
|
|
|
|
/datum/element/plant_backfire/Detach(datum/target)
|
|
. = ..()
|
|
UnregisterSignal(target, list(COMSIG_ITEM_PRE_ATTACK, COMSIG_ITEM_PICKUP, COMSIG_MOVABLE_PRE_THROW))
|
|
|
|
/**
|
|
* Checks before we attack if we're okay to continue.
|
|
*
|
|
* source - our plant
|
|
* user - the mob wielding our [source]
|
|
*/
|
|
/datum/element/plant_backfire/proc/attack_safety_check(obj/item/source, atom/target, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
// Covers stuff like tk, since we aren't actually touching the plant.
|
|
if(!user.is_holding(source))
|
|
return
|
|
if(!backfire(source, user))
|
|
return
|
|
|
|
return cancel_action ? COMPONENT_CANCEL_ATTACK_CHAIN : NONE
|
|
|
|
/**
|
|
* Checks before we pick up the plant if we're okay to continue.
|
|
*
|
|
* source - our plant
|
|
* user - the mob picking our [source]
|
|
*/
|
|
/datum/element/plant_backfire/proc/pickup_safety_check(obj/item/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
backfire(source, user)
|
|
|
|
/**
|
|
* Checks before we throw the plant if we're okay to continue.
|
|
*
|
|
* source - our plant
|
|
* thrower - the mob throwing our [source]
|
|
*/
|
|
/datum/element/plant_backfire/proc/throw_safety_check(obj/item/source, list/arguments)
|
|
SIGNAL_HANDLER
|
|
|
|
var/mob/living/thrower = arguments[4] // the 4th arg = the mob throwing our item
|
|
if(!istype(thrower) || !thrower.is_holding(source))
|
|
return
|
|
if(!backfire(source, thrower))
|
|
return
|
|
|
|
return cancel_action ? COMPONENT_CANCEL_ATTACK_CHAIN : NONE
|
|
|
|
/**
|
|
* The actual backfire occurs here.
|
|
* Checks if the user is able to safely handle the plant.
|
|
* If not, sends the backfire signal (meaning backfire will occur and be handled by one or multiple genes).
|
|
*
|
|
* Returns FALSE if the user was safe and no backfire occured.
|
|
* Returns TRUE if the user was not safe and a backfire actually happened.
|
|
*/
|
|
/datum/element/plant_backfire/proc/backfire(obj/item/plant, mob/user)
|
|
if(plant_safety_check(plant, user))
|
|
return FALSE
|
|
|
|
SEND_SIGNAL(plant, COMSIG_PLANT_ON_BACKFIRE, user)
|
|
return TRUE
|
|
|
|
/**
|
|
* Actually checks if our user is safely handling our plant.
|
|
*
|
|
* Checks for TRAIT_PLANT_SAFE, and returns TRUE if we have it.
|
|
* Then, any extra traits we need to check (Like TRAIT_PIERCEIMMUNE for nettles) and returns TRUE if we have one of them.
|
|
* Then, any extra genes we need to check (Like liquid contents for bluespace tomatos) and returns TRUE if we don't have the gene.
|
|
*
|
|
* source - our plant
|
|
* user - the carbon handling our [source]
|
|
*
|
|
* returns FALSE if none of the checks are successful.
|
|
*/
|
|
/datum/element/plant_backfire/proc/plant_safety_check(obj/item/plant, mob/living/carbon/user)
|
|
if(!istype(user))
|
|
return TRUE
|
|
|
|
if(HAS_TRAIT(user, TRAIT_PLANT_SAFE))
|
|
return TRUE
|
|
|
|
for(var/checked_trait in extra_traits)
|
|
if(HAS_TRAIT(user, checked_trait))
|
|
return TRUE
|
|
|
|
var/obj/item/seeds/our_seed = plant.get_plant_seed()
|
|
if(our_seed)
|
|
for(var/checked_gene in extra_genes)
|
|
if(!our_seed.get_gene(checked_gene))
|
|
return TRUE
|
|
|
|
for(var/obj/item/clothing/worn_item in user.get_equipped_items())
|
|
if((worn_item.body_parts_covered & HANDS) && (worn_item.clothing_flags & THICKMATERIAL))
|
|
return TRUE
|
|
|
|
return FALSE
|