Adds in the Tactical Deniability Implant for nukeops. (#77214)

## About The Pull Request

This PR adds in the Tactical Deniability Implant to the nuclear
operative uplink for 6 TC. It's new version of the minibomb, implanted
directly into your brain.
It disables softcrit and hardcrit, making it extremely powerful... For
about 10.7 seconds (without stacked minibombs), before you realize what
the increasing beeping is for, and proceed to explode. Even atropine
can't save you from this one.

There is kind of a buff in that the delay of mini/macrobombs can no
longer reach 30 seconds, since it just makes things a lot more
interesting with a time cap (and also you'd need like 4 macrobombs to
reach it so it mostly only impacts this new feature)

## Why It's Good For The Game

It's an interesting tradeoff where you can survive for a bit after
critical condition, but whenever it triggers you've effectively sealed
your own fate. Even if a helpful operative comes along to heal you, you
WILL explode.

## Changelog

🆑
add: The Syndicate has begun rolling out new Tactical Deniability
Implants for their Nuclear Operative teams. It seems these implants are
designed to make teams "fight harder" by "giving incentives for fighting
to the bitter end", whatever they're talking about.
/🆑
This commit is contained in:
CRITAWAKETS
2023-08-08 15:17:33 +00:00
committed by GitHub
parent 7eb2a00479
commit faf405b083
3 changed files with 100 additions and 26 deletions
@@ -27,6 +27,12 @@
var/explosion_devastate = MICROBOMB_EXPLOSION_DEVASTATE
///Whether the confirmation UI popup is active or not
var/popup = FALSE
///Do we rapidly increase the beeping speed as it gets closer to detonating?
var/panic_beep_sound = FALSE
///Do we disable paralysis upon activation
var/no_paralyze = FALSE
///Do we override other explosive implants?
var/master_implant = FALSE
/obj/item/implant/explosive/proc/on_death(datum/source, gibbed)
@@ -64,34 +70,28 @@
return FALSE
if(cause == "death" && HAS_TRAIT(imp_in, TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION))
return FALSE
explosion_devastate = round(explosion_devastate)
explosion_heavy = round(explosion_heavy)
explosion_light = round(explosion_light)
to_chat(imp_in, span_notice("You activate your [name]."))
active = TRUE
var/turf/boomturf = get_turf(imp_in)
message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
//If the delay is shorter or equal to the default delay, just blow up already jeez
if(delay <= MICROBOMB_DELAY)
explosion(src, devastation_range = explosion_devastate, heavy_impact_range = explosion_heavy, light_impact_range = explosion_light, flame_range = explosion_light, flash_range = explosion_light, explosion_cause = src)
if(imp_in)
imp_in.investigate_log("has been gibbed by an explosive implant.", INVESTIGATE_DEATHS)
imp_in.gib(TRUE)
qdel(src)
explode()
return
timed_explosion()
/obj/item/implant/explosive/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
for(var/target_implant in target.implants)
if(istype(target_implant, /obj/item/implant/explosive)) //we don't use our own type here, because macrobombs inherit this proc and need to be able to upgrade microbombs
//We merge the two implants into a single bigger, badder one by adding the injected implant's values into the already present implant
var/obj/item/implant/explosive/implant_to_upgrade = target_implant
implant_to_upgrade.explosion_devastate += explosion_devastate
implant_to_upgrade.explosion_heavy += explosion_heavy
implant_to_upgrade.explosion_light += explosion_light
implant_to_upgrade.delay += delay
qdel(src)
return TRUE
var/obj/item/implant/explosive/other_implant = target_implant
if(other_implant.master_implant && master_implant) //we cant have two master implants at once
target.balloon_alert(target, "cannot fit implant!")
return FALSE
if(master_implant)
merge_implants(src, other_implant)
else
merge_implants(other_implant, src)
return TRUE
. = ..()
if(.)
@@ -102,6 +102,18 @@
if(.)
UnregisterSignal(target, COMSIG_LIVING_DEATH)
/**
* Merges two explosive implants together, adding the stats of the latter to the former before qdeling the latter implant.
* kept_implant = the implant that is kept
* stat_implant = the implant which has it's stats added to kept_implant, before being deleted.
*/
/obj/item/implant/explosive/proc/merge_implants(obj/item/implant/explosive/kept_implant, obj/item/implant/explosive/stat_implant)
kept_implant.explosion_devastate += stat_implant.explosion_devastate
kept_implant.explosion_heavy += stat_implant.explosion_heavy
kept_implant.explosion_light += stat_implant.explosion_light
kept_implant.delay = min(kept_implant.delay + stat_implant.delay, 30 SECONDS)
qdel(stat_implant)
/**
* Explosive activation sequence for implants with a delay longer than 0.7 seconds.
* Make the implantee beep a few times, keel over and explode. Usually to a devastating effect.
@@ -120,26 +132,44 @@
)
playsound(loc, 'sound/items/timer.ogg', 30, FALSE)
sleep(delay * 0.25)
if(imp_in && !imp_in.stat)
if(!panic_beep_sound)
sleep(delay * 0.25)
if(imp_in && !imp_in.stat && !no_paralyze)
imp_in.visible_message(span_warning("[imp_in] doubles over in pain!"))
imp_in.Paralyze(14 SECONDS)
//total of 4 bomb beeps, and we've already beeped once
var/bomb_beeps_until_boom = 3
while(bomb_beeps_until_boom > 0)
//for extra spice
var/beep_volume = 35
playsound(loc, 'sound/items/timer.ogg', beep_volume, FALSE)
sleep(delay * 0.25)
bomb_beeps_until_boom--
beep_volume += 5
if(!panic_beep_sound)
while(bomb_beeps_until_boom > 0)
//for extra spice
var/beep_volume = 35
playsound(loc, 'sound/items/timer.ogg', beep_volume, vary = FALSE)
sleep(delay * 0.25)
bomb_beeps_until_boom--
beep_volume += 5
explode()
else
addtimer(CALLBACK(src, PROC_REF(explode)), delay)
while(delay > 1) //so we dont accidentally enter an infinite sleep
var/beep_volume = 35
playsound(loc, 'sound/items/timer.ogg', beep_volume, vary = FALSE)
sleep(delay * 0.2)
delay -= delay * 0.2
beep_volume += 5
///When called, just explodes
/obj/item/implant/explosive/proc/explode()
explosion_devastate = round(explosion_devastate)
explosion_heavy = round(explosion_heavy)
explosion_light = round(explosion_light)
explosion(src, devastation_range = explosion_devastate, heavy_impact_range = explosion_heavy, light_impact_range = explosion_light, flame_range = explosion_light, flash_range = explosion_light, explosion_cause = src)
if(imp_in)
imp_in.investigate_log("has been gibbed by an explosive implant.", INVESTIGATE_DEATHS)
imp_in.gib(TRUE)
qdel(src)
//Macrobomb has the strength and delay of 10 microbombs
///Macrobomb has the strength and delay of 10 microbombs
/obj/item/implant/explosive/macro
name = "macrobomb implant"
desc = "And boom goes the weasel. And everything else nearby."
@@ -149,6 +179,33 @@
explosion_heavy = 10 * MICROBOMB_EXPLOSION_HEAVY
explosion_devastate = 10 * MICROBOMB_EXPLOSION_DEVASTATE
///Microbomb which prevents you from going into critical condition but also explodes after a timer when you reach critical condition in the first place.
/obj/item/implant/explosive/deniability
name = "tactical deniability implant"
desc = "An enhanced version of the microbomb that directly plugs into the brain. No downsides, promise!"
delay = 10 SECONDS
panic_beep_sound = TRUE
no_paralyze = TRUE
master_implant = TRUE
/obj/item/implant/explosive/deniability/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
. = ..()
if(.)
RegisterSignal(target, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(check_health))
target.add_traits(list(TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT), IMPLANT_TRAIT)
/obj/item/implant/explosive/deniability/removed(mob/target, silent = FALSE, special = FALSE)
. = ..()
if(.)
UnregisterSignal(target, COMSIG_LIVING_HEALTH_UPDATE)
target.remove_traits(list(TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT), IMPLANT_TRAIT)
/obj/item/implant/explosive/deniability/proc/check_health(mob/living/source)
SIGNAL_HANDLER
if(source.health < source.crit_threshold)
INVOKE_ASYNC(src, PROC_REF(activate), "deniability")
/obj/item/implanter/explosive
name = "implanter (microbomb)"
imp_type = /obj/item/implant/explosive
@@ -162,6 +219,10 @@
name = "implanter (macrobomb)"
imp_type = /obj/item/implant/explosive/macro
/obj/item/implanter/tactical_deniability
name = "implanter (tactical deniability)"
imp_type = /obj/item/implant/explosive/deniability
/datum/action/item_action/explosive_implant
check_flags = NONE
name = "Activate Explosive Implant"