Files
S.P.L.U.R.T-Station-13/code/datums/elements/embed.dm
Timothy Teakettle 95b8cd3956 first port
2020-06-10 20:33:01 +01:00

129 lines
5.1 KiB
Plaintext

/*
The presence of this element allows an item to embed itself in a human or turf when it is thrown into a target (whether by hand, gun, or explosive wave)
with either at least 4 throwspeed (EMBED_THROWSPEED_THRESHOLD) or ignore_throwspeed_threshold set to TRUE.
This element is granted primarily to any /obj/item that has something in its /embedding var, which should be formatted as a list. If you wish to be able to
grant/rescind the ability for an item to embed (say, when activating and deactivating an edagger), you can do so in two ways:
1. Drop the throw_speed var below EMBED_THROWSPEED_THRESHOLD (object will still be able to otherwise embed if thrown at high speed by something else like a blast)
2. Add/Remove the embed element as needed (won't be able to embed at all)
Otherwise non-embeddable or stickable items can be made embeddable/stickable through wizard events/sticky tape/admin memes.
*/
#define STANDARD_WALL_HARDNESS 40
/datum/element/embed
element_flags = ELEMENT_BESPOKE
id_arg_index = 2
// all of this stuff is explained in _DEFINES/combat.dm
var/embed_chance
var/fall_chance
var/pain_chance
var/pain_mult
var/remove_pain_mult
var/impact_pain_mult
var/rip_time
var/ignore_throwspeed_threshold
var/jostle_chance
var/jostle_pain_mult
var/pain_stam_pct
/datum/element/embed/Attach(datum/target, list/embedArgs)
. = ..()
parseArgs(arglist(embedArgs))
if(!isitem(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_MOVABLE_IMPACT_ZONE, .proc/checkEmbedMob)
RegisterSignal(target, COMSIG_MOVABLE_IMPACT, .proc/checkEmbedOther)
RegisterSignal(target, COMSIG_ELEMENT_ATTACH, .proc/severancePackage)
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/examined)
/datum/element/embed/Detach(obj/item/target)
. = ..()
UnregisterSignal(target, list(COMSIG_MOVABLE_IMPACT_ZONE, COMSIG_ELEMENT_ATTACH, COMSIG_MOVABLE_IMPACT, COMSIG_PARENT_EXAMINE))
/// Checking to see if we're gonna embed into a human
/datum/element/embed/proc/checkEmbedMob(obj/item/weapon, mob/living/carbon/human/victim, hit_zone, datum/thrownthing/throwingdatum)
if(!istype(victim))
return
if((((throwingdatum ? throwingdatum.speed : weapon.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || ignore_throwspeed_threshold) && prob(embed_chance) && !HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE))
victim.AddComponent(/datum/component/embedded,\
weapon,\
throwingdatum,\
embed_chance = embed_chance,\
fall_chance = fall_chance,\
pain_chance = pain_chance,\
pain_mult = pain_mult,\
remove_pain_mult = remove_pain_mult,\
rip_time = rip_time,\
ignore_throwspeed_threshold = ignore_throwspeed_threshold,\
jostle_chance = jostle_chance,\
jostle_pain_mult = jostle_pain_mult,\
pain_stam_pct = pain_stam_pct)
/// We need the hit_zone if we're embedding into a human, so this proc only handled if we're embedding into a turf
/datum/element/embed/proc/checkEmbedOther(obj/item/weapon, turf/closed/hit, datum/thrownthing/throwingdatum)
if(!istype(hit))
return
var/chance = embed_chance
if(iswallturf(hit))
var/turf/closed/wall/W = hit
chance += 2 * (W.hardness - STANDARD_WALL_HARDNESS)
if((((throwingdatum ? throwingdatum.speed : weapon.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || ignore_throwspeed_threshold) && prob(chance))
hit.AddComponent(/datum/component/embedded,\
weapon,\
throwingdatum,\
embed_chance = embed_chance,\
fall_chance = fall_chance,\
pain_chance = pain_chance,\
pain_mult = pain_mult,\
remove_pain_mult = remove_pain_mult,\
rip_time = rip_time,\
ignore_throwspeed_threshold = ignore_throwspeed_threshold,\
jostle_chance = jostle_chance,\
jostle_pain_mult = jostle_pain_mult,\
pain_stam_pct = pain_stam_pct)
/datum/element/embed/proc/parseArgs(embed_chance = EMBED_CHANCE,
fall_chance = EMBEDDED_ITEM_FALLOUT,
pain_chance = EMBEDDED_PAIN_CHANCE,
pain_mult = EMBEDDED_PAIN_MULTIPLIER,
remove_pain_mult = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER,
rip_time = EMBEDDED_UNSAFE_REMOVAL_TIME,
impact_pain_mult = EMBEDDED_IMPACT_PAIN_MULTIPLIER,
ignore_throwspeed_threshold = FALSE,
jostle_chance = EMBEDDED_JOSTLE_CHANCE,
jostle_pain_mult = EMBEDDED_JOSTLE_PAIN_MULTIPLIER,
pain_stam_pct = EMBEDDED_PAIN_STAM_PCT)
src.embed_chance = embed_chance
src.fall_chance = fall_chance
src.pain_chance = pain_chance
src.pain_mult = pain_mult
src.remove_pain_mult = remove_pain_mult
src.impact_pain_mult = impact_pain_mult
src.rip_time = rip_time
src.ignore_throwspeed_threshold = ignore_throwspeed_threshold
src.jostle_chance = jostle_chance
src.jostle_pain_mult = jostle_pain_mult
src.pain_stam_pct = pain_stam_pct
///A different embed element has been attached, so we'll detach and let them handle things
/datum/element/embed/proc/severancePackage(obj/item/weapon, datum/element/E)
if(istype(E, /datum/element/embed))
Detach(weapon)
/datum/element/embed/proc/examined(obj/item/I, mob/user, list/examine_list)
if(!pain_mult && !jostle_pain_mult)
examine_list += "[I] feels sticky, and could probably get stuck to someone if thrown properly!"
else
examine_list += "[I] has a fine point, and could probably embed in someone if thrown properly!"