Merge remote-tracking branch 'citadel/master' into mobility_flags

This commit is contained in:
kevinz000
2020-02-21 13:35:26 -07:00
180 changed files with 4392 additions and 2132 deletions
@@ -18,23 +18,16 @@
var/mob/living/carbon/human/H = host_mob
H.physiology.stun_mod *= 2
/datum/nanite_program/triggered/adrenaline
/datum/nanite_program/adrenaline
name = "Adrenaline Burst"
desc = "The nanites cause a burst of adrenaline when triggered, waking the host from stuns and temporarily increasing their speed."
can_trigger = TRUE
trigger_cost = 25
trigger_cooldown = 1200
rogue_types = list(/datum/nanite_program/toxic, /datum/nanite_program/nerve_decay)
/datum/nanite_program/triggered/adrenaline/trigger()
if(!..())
return
to_chat(host_mob, "<span class='notice'>You feel a sudden surge of energy!</span>")
host_mob.SetAllImmobility(0, FALSE)
host_mob.SetUnconscious(0, FALSE)
host_mob.adjustStaminaLoss(-10) //stimulants give stamina heal now
host_mob.set_resting(FALSE, TRUE, FALSE)
host_mob.update_mobility()
host_mob.reagents.add_reagent(/datum/reagent/medicine/stimulants, 1.5)
/datum/nanite_program/adrenaline/on_trigger()
host_mob.do_adrenaline(-10, TRUE, TRUE, FALSE, TRUE, list(/datum/reagent/medicine/stimulants = 1.5), "<span class='notice'>You feel a sudden surge of energy!</span>", FALSE, FALSE, FALSE)
/datum/nanite_program/hardening
name = "Dermal Hardening"
@@ -119,7 +112,7 @@
/datum/nanite_program/mindshield/enable_passive_effect()
. = ..()
if(!host_mob.mind.has_antag_datum(/datum/antagonist/rev)) //won't work if on a rev, to avoid having implanted revs
if(!host_mob.mind.has_antag_datum(/datum/antagonist/rev, TRUE)) //won't work if on a rev, to avoid having implanted revs.
ADD_TRAIT(host_mob, TRAIT_MINDSHIELD, "nanites")
host_mob.sec_hud_set_implants()
@@ -23,7 +23,7 @@
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(0.5/parts.len, 0.5/parts.len, null, BODYPART_ORGANIC))
if(L.heal_damage(0.5/parts.len, 0.5/parts.len))
host_mob.update_damage_overlays()
else
host_mob.adjustBruteLoss(-0.5, TRUE)
@@ -48,12 +48,12 @@
/datum/nanite_program/purging
name = "Blood Purification"
desc = "The nanites purge toxins and chemicals from the host's bloodstream, however it is dangerous to slimepeople biology due to inaccuracy."
desc = "The nanites purge toxins and chemicals from the host's bloodstream, however it is dangerous to slime biology due to inaccuracy."
use_rate = 1
rogue_types = list(/datum/nanite_program/suffocating, /datum/nanite_program/necrotic)
/datum/nanite_program/purging/check_conditions()
var/foreign_reagent = LAZYLEN(host_mob.reagents.reagent_list)
var/foreign_reagent = length(host_mob.reagents?.reagent_list)
if(!host_mob.getToxLoss() && !foreign_reagent)
return FALSE
return ..()
@@ -73,18 +73,17 @@
rogue_types = list(/datum/nanite_program/brain_decay)
/datum/nanite_program/brain_heal/check_conditions()
var/problems = FALSE
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
for(var/X in C.get_traumas())
var/datum/brain_trauma/BT = X
if(BT.resilience <= TRAUMA_RESILIENCE_BASIC)
return ..()
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN))
return ..()
return FALSE
if(length(C.get_traumas()))
problems = TRUE
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN) > 0)
problems = TRUE
return problems ? ..() : FALSE
/datum/nanite_program/brain_heal/active_effect()
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1, TRUE)
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1)
if(iscarbon(host_mob) && prob(10))
var/mob/living/carbon/C = host_mob
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
@@ -137,7 +136,7 @@
return
var/update = FALSE
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(1.5/parts.len, 1.5/parts.len, null, BODYPART_ROBOTIC)) //much faster than organic healing
if(L.heal_damage(1.5/parts.len, 1.5/parts.len, null, TRUE, FALSE)) //much faster than organic healing
update = TRUE
if(update)
host_mob.update_damage_overlays()
@@ -148,7 +147,7 @@
/datum/nanite_program/purging_advanced
name = "Selective Blood Purification"
desc = "The nanites purge toxins and dangerous chemicals from the host's bloodstream, while ignoring beneficial chemicals. \
The added processing power required to analyze the chemicals severely increases the nanite consumption rate. Due to added complexity, it is safe with slimepeople biology."
The added processing power required to analyze the chemicals severely increases the nanite consumption rate. This program is safe with slime biology due to the increased precision."
use_rate = 2
rogue_types = list(/datum/nanite_program/suffocating, /datum/nanite_program/necrotic)
@@ -181,7 +180,7 @@
return
var/update = FALSE
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(3/parts.len, 3/parts.len))
if(L.heal_damage(3/parts.len, 3/parts.len, FALSE))
update = TRUE
if(update)
host_mob.update_damage_overlays()
@@ -196,70 +195,54 @@
rogue_types = list(/datum/nanite_program/brain_decay, /datum/nanite_program/brain_misfire)
/datum/nanite_program/brain_heal_advanced/check_conditions()
var/problems = FALSE
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
for(var/X in C.get_traumas())
var/datum/brain_trauma/BT = X
if(BT.resilience <= TRAUMA_RESILIENCE_LOBOTOMY)
return ..()
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN))
return ..()
return FALSE
if(length(C.get_traumas()))
problems = TRUE
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN) > 0)
problems = TRUE
return problems ? ..() : FALSE
/datum/nanite_program/brain_heal_advanced/active_effect()
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2, TRUE)
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2)
if(iscarbon(host_mob) && prob(10))
var/mob/living/carbon/C = host_mob
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_LOBOTOMY)
/datum/nanite_program/triggered/defib
/datum/nanite_program/defib
name = "Defibrillation"
desc = "The nanites shock the host's heart when triggered, bringing them back to life if the body can sustain it."
can_trigger = TRUE
trigger_cost = 25
trigger_cooldown = 120
rogue_types = list(/datum/nanite_program/triggered/shocking)
/datum/nanite_program/triggered/defib/trigger()
if(!..())
return
rogue_types = list(/datum/nanite_program/shocking)
/datum/nanite_program/defib/on_trigger(comm_message)
host_mob.notify_ghost_cloning("Your heart is being defibrillated by nanites. Re-enter your corpse if you want to be revived!")
addtimer(CALLBACK(src, .proc/zap), 50)
/datum/nanite_program/triggered/defib/proc/check_revivable()
/datum/nanite_program/defib/proc/check_revivable()
if(!iscarbon(host_mob)) //nonstandard biology
return FALSE
var/mob/living/carbon/C = host_mob
if(C.suiciding || HAS_TRAIT(C, TRAIT_NOCLONE) || C.hellbound) //can't revive
return FALSE
if((world.time - C.timeofdeath) > 1800) //too late
return FALSE
if((C.getBruteLoss() > 180) || (C.getFireLoss() > 180) || !C.can_be_revived()) //too damaged
return FALSE
if(!C.getorgan(/obj/item/organ/heart)) //what are we even shocking
return FALSE
var/obj/item/organ/brain/BR = C.getorgan(/obj/item/organ/brain)
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || C.suiciding)
return FALSE
if(C.get_ghost())
return FALSE
return TRUE
return C.can_defib()
/datum/nanite_program/triggered/defib/proc/zap()
/datum/nanite_program/defib/proc/zap()
var/mob/living/carbon/C = host_mob
playsound(C, 'sound/machines/defib_charge.ogg', 50, 0)
playsound(C, 'sound/machines/defib_charge.ogg', 50, FALSE)
sleep(30)
playsound(C, 'sound/machines/defib_zap.ogg', 50, 0)
playsound(C, 'sound/machines/defib_zap.ogg', 50, FALSE)
if(check_revivable())
playsound(C, 'sound/machines/defib_success.ogg', 50, 0)
playsound(C, 'sound/machines/defib_success.ogg', 50, FALSE)
C.set_heartattack(FALSE)
C.revive()
C.revive(full_heal = FALSE, admin_revive = FALSE)
C.emote("gasp")
C.Jitter(100)
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
var/tplus = world.time - C.timeofdeath
if(tplus > 600)
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, max(0, ((1800 - tplus) / 1800 * 150)), 150)
log_game("[C] has been successfully defibrillated by nanites.")
else
playsound(C, 'sound/machines/defib_failed.ogg', 50, 0)
playsound(C, 'sound/machines/defib_failed.ogg', 50, FALSE)
@@ -0,0 +1,107 @@
//Replication Protocols
/datum/nanite_program/protocol/kickstart
name = "Kickstart Protocol"
desc = "Replication Protocol: the nanites focus on early growth, heavily boosting replication rate for a few minutes after the initial implantation."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_REPLICATION
var/boost_duration = 1200
/datum/nanite_program/protocol/kickstart/check_conditions()
if(!(world.time < nanites.start_time + boost_duration))
return FALSE
return ..()
/datum/nanite_program/protocol/kickstart/active_effect()
nanites.adjust_nanites(null, 3.5)
/datum/nanite_program/protocol/factory
name = "Factory Protocol"
desc = "Replication Protocol: the nanites build a factory matrix within the host, gradually increasing replication speed over time. \
The factory decays if the protocol is not active, or if the nanites are disrupted by shocks or EMPs."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_REPLICATION
var/factory_efficiency = 0
var/max_efficiency = 1000 //Goes up to 2 bonus regen per tick after 16 minutes and 40 seconds
/datum/nanite_program/protocol/factory/on_process()
if(!activated || !check_conditions())
factory_efficiency = max(0, factory_efficiency - 5)
..()
/datum/nanite_program/protocol/factory/on_emp(severity)
..()
factory_efficiency = max(0, factory_efficiency - 300)
/datum/nanite_program/protocol/factory/on_shock(shock_damage)
..()
factory_efficiency = max(0, factory_efficiency - 200)
/datum/nanite_program/protocol/factory/on_minor_shock()
..()
factory_efficiency = max(0, factory_efficiency - 100)
/datum/nanite_program/protocol/factory/active_effect()
factory_efficiency = min(factory_efficiency + 1, max_efficiency)
nanites.adjust_nanites(null, round(0.002 * factory_efficiency, 0.1))
/datum/nanite_program/protocol/tinker
name = "Tinker Protocol"
desc = "Replication Protocol: the nanites learn to use metallic material in the host's bloodstream to speed up the replication process."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_REPLICATION
var/boost = 2
var/list/valid_reagents = list(
/datum/reagent/iron,
/datum/reagent/copper,
/datum/reagent/gold,
/datum/reagent/silver,
/datum/reagent/mercury,
/datum/reagent/aluminium,
/datum/reagent/silicon)
/datum/nanite_program/protocol/tinker/check_conditions()
if(!nanites.host_mob.reagents)
return FALSE
var/found_reagent = FALSE
var/datum/reagents/R = nanites.host_mob.reagents
for(var/VR in valid_reagents)
if(R.has_reagent(VR, 0.5))
R.remove_reagent(VR, 0.5)
found_reagent = TRUE
break
if(!found_reagent)
return FALSE
return ..()
/datum/nanite_program/protocol/tinker/active_effect()
nanites.adjust_nanites(null, boost)
/datum/nanite_program/protocol/offline
name = "Offline Production Protocol"
desc = "Replication Protocol: while the host is asleep or otherwise unconcious, the nanites exploit the reduced interference to replicate more quickly."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_REPLICATION
var/boost = 3
/datum/nanite_program/protocol/offline/check_conditions()
var/is_offline = FALSE
if(nanites.host_mob.IsSleeping() || nanites.host_mob.IsUnconscious())
is_offline = TRUE
if(nanites.host_mob.stat == DEAD || HAS_TRAIT(nanites.host_mob, TRAIT_DEATHCOMA))
is_offline = TRUE
if(nanites.host_mob.InCritical() && !HAS_TRAIT(nanites.host_mob, TRAIT_NOSOFTCRIT))
is_offline = TRUE
if(nanites.host_mob.InFullCritical() && !HAS_TRAIT(nanites.host_mob, TRAIT_NOHARDCRIT))
is_offline = TRUE
if(!is_offline)
return FALSE
return ..()
/datum/nanite_program/protocol/offline/active_effect()
nanites.adjust_nanites(null, boost)
@@ -2,71 +2,41 @@
name = "Sensor Nanites"
desc = "These nanites send a signal code when a certain condition is met."
unique = FALSE
extra_settings = list("Sent Code")
var/can_rule = FALSE
var/sent_code = 0
/datum/nanite_program/sensor/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
/datum/nanite_program/sensor/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
/datum/nanite_program/sensor/copy_extra_settings_to(datum/nanite_program/sensor/target)
target.sent_code = sent_code
/datum/nanite_program/sensor/register_extra_settings()
extra_settings[NES_SENT_CODE] = new /datum/nanite_extra_setting/number(0, 1, 9999)
/datum/nanite_program/sensor/proc/check_event()
return FALSE
/datum/nanite_program/sensor/proc/send_code()
if(activated)
SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, sent_code, "a [name] program")
var/datum/nanite_extra_setting/ES = extra_settings[NES_SENT_CODE]
SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, ES.value, "a [name] program")
/datum/nanite_program/sensor/active_effect()
if(sent_code && check_event())
if(check_event())
send_code()
/datum/nanite_program/sensor/proc/make_rule(datum/nanite_program/target)
return
/datum/nanite_program/sensor/repeat
name = "Signal Repeater"
desc = "When triggered, sends another signal to the nanites, optionally with a delay."
can_trigger = TRUE
trigger_cost = 0
trigger_cooldown = 10
extra_settings = list("Sent Code","Delay")
var/spent = FALSE
var/delay = 0
/datum/nanite_program/sensor/repeat/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Delay")
var/new_delay = input(user, "Set the delay in seconds:", name, null) as null|num
if(isnull(new_delay))
return
delay = (CLAMP(round(new_delay, 1), 0, 3600)) * 10 //max 1 hour
/datum/nanite_program/sensor/repeat/register_extra_settings()
. = ..()
extra_settings[NES_DELAY] = new /datum/nanite_extra_setting/number(0, 0, 3600, "s")
/datum/nanite_program/sensor/repeat/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Delay")
return "[delay/10] seconds"
/datum/nanite_program/sensor/repeat/copy_extra_settings_to(datum/nanite_program/sensor/repeat/target)
target.sent_code = sent_code
target.delay = delay
/datum/nanite_program/sensor/repeat/trigger()
if(!..())
return
addtimer(CALLBACK(src, .proc/send_code), delay)
/datum/nanite_program/sensor/repeat/on_trigger(comm_message)
var/datum/nanite_extra_setting/ES = extra_settings[NES_DELAY]
addtimer(CALLBACK(src, .proc/send_code), ES.get_value() * 10)
/datum/nanite_program/sensor/relay_repeat
name = "Relay Signal Repeater"
@@ -74,98 +44,46 @@
can_trigger = TRUE
trigger_cost = 0
trigger_cooldown = 10
extra_settings = list("Sent Code","Relay Channel","Delay")
var/spent = FALSE
var/delay = 0
var/relay_channel = 0
/datum/nanite_program/sensor/relay_repeat/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Relay Channel")
var/new_channel = input(user, "Set the relay channel (1-9999):", name, null) as null|num
if(isnull(new_channel))
return
relay_channel = CLAMP(round(new_channel, 1), 1, 9999)
if(setting == "Delay")
var/new_delay = input(user, "Set the delay in seconds:", name, null) as null|num
if(isnull(new_delay))
return
delay = (CLAMP(round(new_delay, 1), 0, 3600)) * 10 //max 1 hour
/datum/nanite_program/sensor/relay_repeat/register_extra_settings()
. = ..()
extra_settings[NES_RELAY_CHANNEL] = new /datum/nanite_extra_setting/number(1, 1, 9999)
extra_settings[NES_DELAY] = new /datum/nanite_extra_setting/number(0, 0, 3600, "s")
/datum/nanite_program/sensor/relay_repeat/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Relay Channel")
return relay_channel
if(setting == "Delay")
return "[delay/10] seconds"
/datum/nanite_program/sensor/relay_repeat/copy_extra_settings_to(datum/nanite_program/sensor/relay_repeat/target)
target.sent_code = sent_code
target.delay = delay
target.relay_channel = relay_channel
/datum/nanite_program/sensor/relay_repeat/trigger()
if(!..())
return
addtimer(CALLBACK(src, .proc/send_code), delay)
/datum/nanite_program/sensor/relay_repeat/on_trigger(comm_message)
var/datum/nanite_extra_setting/ES = extra_settings[NES_DELAY]
addtimer(CALLBACK(src, .proc/send_code), ES.get_value() * 10)
/datum/nanite_program/sensor/relay_repeat/send_code()
if(activated && relay_channel)
var/datum/nanite_extra_setting/relay = extra_settings[NES_RELAY_CHANNEL]
if(activated && relay.get_value())
for(var/X in SSnanites.nanite_relays)
var/datum/nanite_program/relay/N = X
N.relay_signal(sent_code, relay_channel, "a [name] program")
var/datum/nanite_extra_setting/code = extra_settings[NES_SENT_CODE]
N.relay_signal(code.get_value(), relay.get_value(), "a [name] program")
/datum/nanite_program/sensor/health
name = "Health Sensor"
desc = "The nanites receive a signal when the host's health is above/below a target percentage."
extra_settings = list("Sent Code","Health Percent","Direction")
can_rule = TRUE
var/spent = FALSE
var/percent = 50
var/direction = "Above"
/datum/nanite_program/sensor/health/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Health Percent")
var/new_percent = input(user, "Set the health percentage:", name, null) as null|num
if(isnull(new_percent))
return
percent = CLAMP(round(new_percent, 1), -99, 100)
if(setting == "Direction")
if(direction == "Above")
direction = "Below"
else
direction = "Above"
/datum/nanite_program/sensor/health/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Health Percent")
return "[percent]%"
if(setting == "Direction")
return direction
/datum/nanite_program/sensor/health/copy_extra_settings_to(datum/nanite_program/sensor/health/target)
target.sent_code = sent_code
target.percent = percent
target.direction = direction
/datum/nanite_program/sensor/health/register_extra_settings()
. = ..()
extra_settings[NES_HEALTH_PERCENT] = new /datum/nanite_extra_setting/number(50, -99, 100, "%")
extra_settings[NES_DIRECTION] = new /datum/nanite_extra_setting/boolean(TRUE, "Above", "Below")
/datum/nanite_program/sensor/health/check_event()
var/health_percent = host_mob.health / host_mob.maxHealth * 100
var/datum/nanite_extra_setting/percent = extra_settings[NES_HEALTH_PERCENT]
var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
var/detected = FALSE
if(direction == "Above")
if(health_percent >= percent)
if(direction.get_value())
if(health_percent >= percent.get_value())
detected = TRUE
else
if(health_percent < percent)
if(health_percent < percent.get_value())
detected = TRUE
if(detected)
@@ -177,9 +95,18 @@
spent = FALSE
return FALSE
/datum/nanite_program/sensor/health/make_rule(datum/nanite_program/target)
var/datum/nanite_rule/health/rule = new(target)
var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
var/datum/nanite_extra_setting/percent = extra_settings[NES_HEALTH_PERCENT]
rule.above = direction.get_value()
rule.threshold = percent.get_value()
return rule
/datum/nanite_program/sensor/crit
name = "Critical Health Sensor"
desc = "The nanites receive a signal when the host first reaches critical health."
can_rule = TRUE
var/spent = FALSE
/datum/nanite_program/sensor/crit/check_event()
@@ -192,61 +119,44 @@
spent = FALSE
return FALSE
/datum/nanite_program/sensor/crit/make_rule(datum/nanite_program/target)
var/datum/nanite_rule/crit/rule = new(target)
return rule
/datum/nanite_program/sensor/death
name = "Death Sensor"
desc = "The nanites receive a signal when they detect the host is dead."
can_rule = TRUE
var/spent = FALSE
/datum/nanite_program/sensor/death/on_death()
send_code()
/datum/nanite_program/sensor/death/make_rule(datum/nanite_program/target)
var/datum/nanite_rule/death/rule = new(target)
return rule
/datum/nanite_program/sensor/nanite_volume
name = "Nanite Volume Sensor"
desc = "The nanites receive a signal when the nanite supply is above/below a certain percentage."
extra_settings = list("Sent Code","Nanite Percent","Direction")
can_rule = TRUE
var/spent = FALSE
var/percent = 50
var/direction = "Above"
/datum/nanite_program/sensor/nanite_volume/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Nanite Percent")
var/new_percent = input(user, "Set the nanite percentage:", name, null) as null|num
if(isnull(new_percent))
return
percent = CLAMP(round(new_percent, 1), 1, 100)
if(setting == "Direction")
if(direction == "Above")
direction = "Below"
else
direction = "Above"
/datum/nanite_program/sensor/nanite_volume/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Nanite Percent")
return "[percent]%"
if(setting == "Direction")
return direction
/datum/nanite_program/sensor/nanite_volume/copy_extra_settings_to(datum/nanite_program/sensor/nanite_volume/target)
target.sent_code = sent_code
target.percent = percent
target.direction = direction
/datum/nanite_program/sensor/nanite_volume/register_extra_settings()
. = ..()
extra_settings[NES_NANITE_PERCENT] = new /datum/nanite_extra_setting/number(50, -99, 100, "%")
extra_settings[NES_DIRECTION] = new /datum/nanite_extra_setting/boolean(TRUE, "Above", "Below")
/datum/nanite_program/sensor/nanite_volume/check_event()
var/nanite_percent = (nanites.nanite_volume - nanites.safety_threshold)/(nanites.max_nanites - nanites.safety_threshold)*100
var/datum/nanite_extra_setting/percent = extra_settings[NES_NANITE_PERCENT]
var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
var/detected = FALSE
if(direction == "Above")
if(nanite_percent >= percent)
if(direction.get_value())
if(nanite_percent >= percent.get_value())
detected = TRUE
else
if(nanite_percent < percent)
if(nanite_percent < percent.get_value())
detected = TRUE
if(detected)
@@ -258,75 +168,51 @@
spent = FALSE
return FALSE
/datum/nanite_program/sensor/nanite_volume/make_rule(datum/nanite_program/target)
var/datum/nanite_rule/nanites/rule = new(target)
var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
var/datum/nanite_extra_setting/percent = extra_settings[NES_NANITE_PERCENT]
rule.above = direction.get_value()
rule.threshold = percent.get_value()
return rule
/datum/nanite_program/sensor/damage
name = "Damage Sensor"
desc = "The nanites receive a signal when a host's specific damage type is above/below a target value."
extra_settings = list("Sent Code","Damage Type","Damage","Direction")
can_rule = TRUE
var/spent = FALSE
var/damage_type = "Brute"
var/damage = 50
var/direction = "Above"
/datum/nanite_program/sensor/damage/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Damage")
var/new_damage = input(user, "Set the damage threshold:", name, null) as null|num
if(isnull(new_damage))
return
damage = CLAMP(round(new_damage, 1), 0, 500)
if(setting == "Damage Type")
var/list/damage_types = list("Brute","Burn","Toxin","Oxygen","Cellular")
var/new_damage_type = input("Choose the damage type", name) as null|anything in damage_types
if(!new_damage_type)
return
damage_type = new_damage_type
if(setting == "Direction")
if(direction == "Above")
direction = "Below"
else
direction = "Above"
/datum/nanite_program/sensor/damage/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Damage")
return damage
if(setting == "Damage Type")
return damage_type
if(setting == "Direction")
return direction
/datum/nanite_program/sensor/damage/copy_extra_settings_to(datum/nanite_program/sensor/damage/target)
target.sent_code = sent_code
target.damage = damage
target.damage_type = damage_type
target.direction = direction
/datum/nanite_program/sensor/damage/register_extra_settings()
. = ..()
extra_settings[NES_DAMAGE_TYPE] = new /datum/nanite_extra_setting/type(BRUTE, list(BRUTE, BURN, TOX, OXY, CLONE))
extra_settings[NES_DAMAGE] = new /datum/nanite_extra_setting/number(50, 0, 500)
extra_settings[NES_DIRECTION] = new /datum/nanite_extra_setting/boolean(TRUE, "Above", "Below")
/datum/nanite_program/sensor/damage/check_event()
var/reached_threshold = FALSE
var/check_above = (direction == "Above")
var/datum/nanite_extra_setting/type = extra_settings[NES_DAMAGE_TYPE]
var/datum/nanite_extra_setting/damage = extra_settings[NES_DAMAGE]
var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
var/check_above = direction.get_value()
var/damage_amt = 0
switch(damage_type)
if("Brute")
switch(type.get_value())
if(BRUTE)
damage_amt = host_mob.getBruteLoss()
if("Burn")
if(BURN)
damage_amt = host_mob.getFireLoss()
if("Toxin")
if(TOX)
damage_amt = host_mob.getToxLoss()
if("Oxygen")
if(OXY)
damage_amt = host_mob.getOxyLoss()
if("Cellular")
if(CLONE)
damage_amt = host_mob.getCloneLoss()
if(damage_amt >= damage)
if(check_above)
if(check_above)
if(damage_amt >= damage.get_value())
reached_threshold = TRUE
else
if(damage_amt < damage.get_value())
reached_threshold = TRUE
else if(!check_above)
reached_threshold = TRUE
if(reached_threshold)
if(!spent)
@@ -337,14 +223,25 @@
spent = FALSE
return FALSE
/datum/nanite_program/sensor/damage/make_rule(datum/nanite_program/target)
var/datum/nanite_rule/damage/rule = new(target)
var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
var/datum/nanite_extra_setting/damage_type = extra_settings[NES_DAMAGE_TYPE]
var/datum/nanite_extra_setting/damage = extra_settings[NES_DAMAGE]
rule.above = direction.get_value()
rule.threshold = damage.get_value()
rule.damage_type = damage_type.get_value()
return rule
/datum/nanite_program/sensor/voice
name = "Voice Sensor"
desc = "Sends a signal when the nanites hear a determined word or sentence."
extra_settings = list("Sent Code","Sentence","Inclusive Mode")
var/spent = FALSE
var/sentence = ""
var/inclusive = TRUE
/datum/nanite_program/sensor/voice/register_extra_settings()
. = ..()
extra_settings[NES_SENTENCE] = new /datum/nanite_extra_setting/text("")
extra_settings[NES_INCLUSIVE_MODE] = new /datum/nanite_extra_setting/boolean(TRUE, "Inclusive", "Exclusive")
/datum/nanite_program/sensor/voice/on_mob_add()
. = ..()
@@ -353,45 +250,14 @@
/datum/nanite_program/sensor/voice/on_mob_remove()
UnregisterSignal(host_mob, COMSIG_MOVABLE_HEAR, .proc/on_hear)
/datum/nanite_program/sensor/voice/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Sentence")
var/new_sentence = stripped_input(user, "Choose the sentence that triggers the sensor.", "Sentence", sentence, MAX_MESSAGE_LEN)
if(!new_sentence)
return
sentence = new_sentence
if(setting == "Inclusive Mode")
var/new_inclusive = input("Should the sensor detect the sentence if contained within another sentence?", name) as null|anything in list("Inclusive","Exclusive")
if(!new_inclusive)
return
inclusive = (new_inclusive == "Inclusive")
/datum/nanite_program/sensor/voice/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Sentence")
return sentence
if(setting == "Inclusive Mode")
if(inclusive)
return "Inclusive"
else
return "Exclusive"
/datum/nanite_program/sensor/voice/copy_extra_settings_to(datum/nanite_program/sensor/voice/target)
target.sent_code = sent_code
target.sentence = sentence
target.inclusive = inclusive
/datum/nanite_program/sensor/voice/proc/on_hear(datum/source, list/hearing_args)
if(!sentence)
var/datum/nanite_extra_setting/sentence = extra_settings[NES_SENTENCE]
var/datum/nanite_extra_setting/inclusive = extra_settings[NES_INCLUSIVE_MODE]
if(!sentence.get_value())
return
if(inclusive)
if(inclusive.get_value())
if(findtextEx(hearing_args[HEARING_RAW_MESSAGE], sentence))
send_code()
else
if(hearing_args[HEARING_RAW_MESSAGE] == sentence)
send_code()
send_code()
@@ -1,15 +1,14 @@
//Programs that are generally useful for population control and non-harmful suppression.
/datum/nanite_program/triggered/sleepy
/datum/nanite_program/sleepy
name = "Sleep Induction"
desc = "The nanites cause rapid narcolepsy when triggered."
can_trigger = TRUE
trigger_cost = 15
trigger_cooldown = 1200
rogue_types = list(/datum/nanite_program/brain_misfire, /datum/nanite_program/brain_decay)
/datum/nanite_program/triggered/sleepy/trigger()
if(!..())
return
/datum/nanite_program/sleepy/on_trigger(comm_message)
to_chat(host_mob, "<span class='warning'>You start to feel very sleepy...</span>")
host_mob.drowsyness += 20
addtimer(CALLBACK(host_mob, /mob/living.proc/Sleeping, 200), rand(60,200))
@@ -31,31 +30,31 @@
. = ..()
to_chat(host_mob, "<span class='notice'>Your muscles relax, and you can move again.</span>")
/datum/nanite_program/triggered/shocking
/datum/nanite_program/shocking
name = "Electric Shock"
desc = "The nanites shock the host when triggered. Destroys a large amount of nanites!"
can_trigger = TRUE
trigger_cost = 10
trigger_cooldown = 300
program_flags = NANITE_SHOCK_IMMUNE
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/triggered/shocking/trigger()
if(!..())
return
/datum/nanite_program/shocking/on_trigger(comm_message)
host_mob.electrocute_act(rand(5,10), "shock nanites", TRUE, TRUE)
/datum/nanite_program/triggered/stun
/datum/nanite_program/stun
name = "Neural Shock"
desc = "The nanites pulse the host's nerves when triggered, inapacitating them for a short period."
can_trigger = TRUE
trigger_cost = 4
trigger_cooldown = 300
rogue_types = list(/datum/nanite_program/triggered/shocking, /datum/nanite_program/nerve_decay)
rogue_types = list(/datum/nanite_program/shocking, /datum/nanite_program/nerve_decay)
/datum/nanite_program/triggered/stun/trigger()
if(!..())
return
playsound(host_mob, "sparks", 75, 1, -1)
host_mob.DefaultCombatKnockdown(80)
playsound(host_mob, "sparks", 75, TRUE, -1)
/datum/nanite_program/pacifying
name = "Pacification"
@@ -115,64 +114,50 @@
host_mob.cure_fakedeath("nanites")
//Can receive transmissions from a nanite communication remote for customized messages
/datum/nanite_program/triggered/comm
/datum/nanite_program/comm
can_trigger = TRUE
var/comm_code = 0
var/comm_message = ""
/datum/nanite_program/triggered/comm/proc/receive_comm_signal(signal_comm_code, comm_message, comm_source)
/datum/nanite_program/comm/register_extra_settings()
extra_settings[NES_COMM_CODE] = new /datum/nanite_extra_setting/number(0, 0, 9999)
/datum/nanite_program/comm/proc/receive_comm_signal(signal_comm_code, comm_message, comm_source)
if(!activated || !comm_code)
return
if(signal_comm_code == comm_code)
host_mob.investigate_log("'s [name] nanite program was messaged by [comm_source] with comm code [signal_comm_code] and message '[comm_message]'.", INVESTIGATE_NANITES)
trigger(comm_message)
/datum/nanite_program/triggered/comm/speech
/datum/nanite_program/comm/speech
name = "Forced Speech"
desc = "The nanites force the host to say a pre-programmed sentence when triggered."
unique = FALSE
trigger_cost = 3
trigger_cooldown = 20
rogue_types = list(/datum/nanite_program/brain_misfire, /datum/nanite_program/brain_decay)
var/static/list/blacklist = list(
"*surrender",
"*collapse"
)
extra_settings = list("Sentence","Comm Code")
var/sentence = ""
/datum/nanite_program/comm/speech/register_extra_settings()
. = ..()
extra_settings[NES_SENTENCE] = new /datum/nanite_extra_setting/text("")
/datum/nanite_program/triggered/comm/speech/set_extra_setting(user, setting)
if(setting == "Sentence")
var/new_sentence = stripped_input(user, "Choose the sentence that the host will be forced to say.", "Sentence", sentence, MAX_MESSAGE_LEN)
if(!new_sentence)
return
if(new_sentence[1] == "*") //emotes are abusable, like surrender
return
sentence = new_sentence
if(setting == "Comm Code")
var/new_code = input(user, "Set the communication code (1-9999) or set to 0 to disable external signals.", name, null) as null|num
if(isnull(new_code))
return
comm_code = CLAMP(round(new_code, 1), 0, 9999)
/datum/nanite_program/triggered/comm/speech/get_extra_setting(setting)
if(setting == "Sentence")
return sentence
if(setting == "Comm Code")
return comm_code
/datum/nanite_program/triggered/comm/speech/copy_extra_settings_to(datum/nanite_program/triggered/comm/speech/target)
target.sentence = sentence
target.comm_code = comm_code
/datum/nanite_program/triggered/comm/speech/trigger(comm_message)
if(!..())
return
/datum/nanite_program/comm/speech/on_trigger(comm_message)
var/sent_message = comm_message
if(!comm_message)
sent_message = sentence
var/datum/nanite_extra_setting/sentence = extra_settings[NES_SENTENCE]
sent_message = sentence.get_value()
if(sent_message in blacklist)
return
if(host_mob.stat == DEAD)
return
to_chat(host_mob, "<span class='warning'>You feel compelled to speak...</span>")
host_mob.say(sent_message, forced = "nanite speech")
/datum/nanite_program/triggered/comm/voice
/datum/nanite_program/comm/voice
name = "Skull Echo"
desc = "The nanites echo a synthesized message inside the host's skull."
unique = FALSE
@@ -180,56 +165,50 @@
trigger_cooldown = 20
rogue_types = list(/datum/nanite_program/brain_misfire, /datum/nanite_program/brain_decay)
extra_settings = list("Message","Comm Code")
var/message = ""
/datum/nanite_program/comm/voice/register_extra_settings()
. = ..()
extra_settings[NES_MESSAGE] = new /datum/nanite_extra_setting/text("")
/datum/nanite_program/triggered/comm/voice/set_extra_setting(user, setting)
if(setting == "Message")
var/new_message = stripped_input(user, "Choose the message sent to the host.", "Message", message, MAX_MESSAGE_LEN)
if(!new_message)
return
message = new_message
if(setting == "Comm Code")
var/new_code = input(user, "Set the communication code (1-9999) or set to 0 to disable external signals.", name, null) as null|num
if(isnull(new_code))
return
comm_code = CLAMP(round(new_code, 1), 0, 9999)
/datum/nanite_program/triggered/comm/voice/get_extra_setting(setting)
if(setting == "Message")
return message
if(setting == "Comm Code")
return comm_code
/datum/nanite_program/triggered/comm/voice/copy_extra_settings_to(datum/nanite_program/triggered/comm/voice/target)
target.message = message
target.comm_code = comm_code
/datum/nanite_program/triggered/comm/voice/trigger(comm_message)
if(!..())
return
/datum/nanite_program/comm/voice/on_trigger(comm_message)
var/sent_message = comm_message
if(!comm_message)
sent_message = message
var/datum/nanite_extra_setting/message_setting = extra_settings[NES_MESSAGE]
sent_message = message_setting.get_value()
if(host_mob.stat == DEAD)
return
to_chat(host_mob, "<i>You hear a strange, robotic voice in your head...</i> \"<span class='robot'>[sent_message]</span>\"")
/datum/nanite_program/triggered/comm/hallucination
/datum/nanite_program/comm/hallucination
name = "Hallucination"
desc = "The nanites make the host hallucinate something when triggered."
trigger_cost = 4
trigger_cooldown = 80
unique = FALSE
rogue_types = list(/datum/nanite_program/brain_misfire)
extra_settings = list("Hallucination Type", "Comm Code")
var/hal_type
var/hal_details
/datum/nanite_program/triggered/comm/hallucination/trigger(comm_message)
if(!..())
return
/datum/nanite_program/comm/hallucination/register_extra_settings()
. = ..()
var/list/options = list(
"Message",
"Battle",
"Sound",
"Weird Sound",
"Station Message",
"Health",
"Alert",
"Fire",
"Shock",
"Plasma Flood",
"Random"
)
extra_settings[NES_HALLUCINATION_TYPE] = new /datum/nanite_extra_setting/type("Message", options)
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/text("")
/datum/nanite_program/comm/hallucination/on_trigger(comm_message)
var/datum/nanite_extra_setting/hal_setting = extra_settings[NES_HALLUCINATION_TYPE]
var/hal_type = hal_setting.get_value()
var/datum/nanite_extra_setting/hal_detail_setting = extra_settings[NES_HALLUCINATION_DETAIL]
var/hal_details = hal_detail_setting.get_value()
if(comm_message && (hal_type != "Message")) //Triggered via comm remote, but not set to a message hallucination
return
var/sent_message = comm_message //Comm remotes can send custom hallucination messages for the chat hallucination
@@ -239,7 +218,9 @@
if(!iscarbon(host_mob))
return
var/mob/living/carbon/C = host_mob
if(!hal_type)
if(hal_details == "random")
hal_details = null
if(hal_type == "Random")
C.hallucination += 15
else
switch(hal_type)
@@ -254,6 +235,13 @@
if("Station Message")
new /datum/hallucination/stationmessage(C, TRUE, hal_details)
if("Health")
switch(hal_details)
if("critical")
hal_details = SCREWYHUD_CRIT
if("dead")
hal_details = SCREWYHUD_DEAD
if("healthy")
hal_details = SCREWYHUD_HEALTHY
new /datum/hallucination/hudscrew(C, TRUE, hal_details)
if("Alert")
new /datum/hallucination/fake_alert(C, TRUE, hal_details)
@@ -264,127 +252,40 @@
if("Plasma Flood")
new /datum/hallucination/fake_flood(C, TRUE)
/datum/nanite_program/triggered/comm/hallucination/set_extra_setting(user, setting)
if(setting == "Comm Code")
var/new_code = input(user, "(Only for Message) Set the communication code (1-9999) or set to 0 to disable external signals.", name, null) as null|num
if(isnull(new_code))
return
comm_code = CLAMP(round(new_code, 1), 0, 9999)
if(setting == "Hallucination Type")
var/list/possible_hallucinations = list("Random","Message","Battle","Sound","Weird Sound","Station Message","Health","Alert","Fire","Shock","Plasma Flood")
var/hal_type_choice = input("Choose the hallucination type", name) as null|anything in possible_hallucinations
if(!hal_type_choice)
return
switch(hal_type_choice)
if("Random")
hal_type = null
hal_details = null
/datum/nanite_program/comm/hallucination/set_extra_setting(setting, value)
. = ..()
if(setting == NES_HALLUCINATION_TYPE)
switch(value)
if("Message")
hal_type = "Message"
var/hal_chat = stripped_input(user, "Choose the message the host will hear, or leave empty for random messages.", "Message", hal_details, MAX_MESSAGE_LEN)
if(hal_chat)
hal_details = hal_chat
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/text("")
if("Battle")
hal_type = "Battle"
var/sound_list = list("random","laser","disabler","esword","gun","stunprod","harmbaton","bomb")
var/hal_choice = input("Choose the hallucination battle type", name) as null|anything in sound_list
if(!hal_choice || hal_choice == "random")
hal_details = null
else
hal_details = hal_choice
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/type("random", list("random","laser","disabler","esword","gun","stunprod","harmbaton","bomb"))
if("Sound")
hal_type = "Sound"
var/sound_list = list("random","airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
var/hal_choice = input("Choose the hallucination sound", name) as null|anything in sound_list
if(!hal_choice || hal_choice == "random")
hal_details = null
else
hal_details = hal_choice
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/type("random", list("random","airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack"))
if("Weird Sound")
hal_type = "Weird Sound"
var/sound_list = list("random","phone","hallelujah","highlander","laughter","hyperspace","game over","creepy","tesla")
var/hal_choice = input("Choose the hallucination sound", name) as null|anything in sound_list
if(!hal_choice || hal_choice == "random")
hal_details = null
else
hal_details = hal_choice
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/type("random", list("random","phone","hallelujah","highlander","laughter","hyperspace","game over","creepy","tesla"))
if("Station Message")
hal_type = "Station Message"
var/msg_list = list("random","ratvar","shuttle dock","blob alert","malf ai","meteors","supermatter")
var/hal_choice = input("Choose the hallucination station message", name) as null|anything in msg_list
if(!hal_choice || hal_choice == "random")
hal_details = null
else
hal_details = hal_choice
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/type("random", list("random","ratvar","shuttle dock","blob alert","malf ai","meteors","supermatter"))
if("Health")
hal_type = "Health"
var/health_list = list("random","critical","dead","healthy")
var/hal_choice = input("Choose the health status", name) as null|anything in health_list
if(!hal_choice || hal_choice == "random")
hal_details = null
else
switch(hal_choice)
if("critical")
hal_details = SCREWYHUD_CRIT
if("dead")
hal_details = SCREWYHUD_DEAD
if("healthy")
hal_details = SCREWYHUD_HEALTHY
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/type("random", list("random","critical","dead","healthy"))
if("Alert")
hal_type = "Alert"
var/alert_list = list("random","not_enough_oxy","not_enough_tox","not_enough_co2","too_much_oxy","too_much_co2","too_much_tox","newlaw","nutrition","charge","gravity","fire","locked","hacked","temphot","tempcold","pressure")
var/hal_choice = input("Choose the alert", name) as null|anything in alert_list
if(!hal_choice || hal_choice == "random")
hal_details = null
else
hal_details = hal_choice
if("Fire")
hal_type = "Fire"
if("Shock")
hal_type = "Shock"
if("Plasma Flood")
hal_type = "Plasma Flood"
/datum/nanite_program/triggered/comm/hallucination/get_extra_setting(setting)
if(setting == "Hallucination Type")
if(!hal_type)
return "Random"
else
return hal_type
if(setting == "Comm Code")
return comm_code
/datum/nanite_program/triggered/comm/hallucination/copy_extra_settings_to(datum/nanite_program/triggered/comm/hallucination/target)
target.hal_type = hal_type
target.hal_details = hal_details
target.comm_code = comm_code
extra_settings[NES_HALLUCINATION_DETAIL] = new /datum/nanite_extra_setting/type("random", list("random","not_enough_oxy","not_enough_tox","not_enough_co2","too_much_oxy","too_much_co2","too_much_tox","newlaw","nutrition","charge","gravity","fire","locked","hacked","temphot","tempcold","pressure"))
else
extra_settings.Remove(NES_HALLUCINATION_DETAIL)
/datum/nanite_program/good_mood
name = "Happiness Enhancer"
desc = "The nanites synthesize serotonin inside the host's brain, creating an artificial sense of happiness."
use_rate = 0.1
rogue_types = list(/datum/nanite_program/brain_decay)
extra_settings = list("Mood Message")
var/message = "HAPPINESS ENHANCEMENT"
/datum/nanite_program/good_mood/set_extra_setting(user, setting)
if(setting == "Mood Message")
var/new_message = stripped_input(user, "Choose the message visible on the mood effect.", "Message", message, MAX_NAME_LEN)
if(!new_message)
return
message = new_message
/datum/nanite_program/good_mood/get_extra_setting(setting)
if(setting == "Mood Message")
return message
/datum/nanite_program/good_mood/copy_extra_settings_to(datum/nanite_program/good_mood/target)
target.message = message
/datum/nanite_program/good_mood/register_extra_settings()
. = ..()
extra_settings[NES_MOOD_MESSAGE] = new /datum/nanite_extra_setting/text("HAPPINESS ENHANCEMENT")
/datum/nanite_program/good_mood/enable_passive_effect()
. = ..()
SEND_SIGNAL(host_mob, COMSIG_ADD_MOOD_EVENT, "nanite_happy", /datum/mood_event/nanite_happiness, message)
SEND_SIGNAL(host_mob, COMSIG_ADD_MOOD_EVENT, "nanite_happy", /datum/mood_event/nanite_happiness, get_extra_setting_value(NES_MOOD_MESSAGE))
/datum/nanite_program/good_mood/disable_passive_effect()
. = ..()
@@ -395,26 +296,14 @@
desc = "The nanites suppress the production of serotonin inside the host's brain, creating an artificial state of depression."
use_rate = 0.1
rogue_types = list(/datum/nanite_program/brain_decay)
extra_settings = list("Mood Message")
var/message = "HAPPINESS SUPPRESSION"
/datum/nanite_program/bad_mood/set_extra_setting(user, setting)
if(setting == "Mood Message")
var/new_message = stripped_input(user, "Choose the message visible on the mood effect.", "Message", message, MAX_NAME_LEN)
if(!new_message)
return
message = new_message
/datum/nanite_program/bad_mood/get_extra_setting(setting)
if(setting == "Mood Message")
return message
/datum/nanite_program/bad_mood/copy_extra_settings_to(datum/nanite_program/bad_mood/target)
target.message = message
/datum/nanite_program/bad_mood/register_extra_settings()
. = ..()
extra_settings[NES_MOOD_MESSAGE] = new /datum/nanite_extra_setting/text("HAPPINESS SUPPRESSION")
/datum/nanite_program/bad_mood/enable_passive_effect()
. = ..()
SEND_SIGNAL(host_mob, COMSIG_ADD_MOOD_EVENT, "nanite_sadness", /datum/mood_event/nanite_sadness, message)
SEND_SIGNAL(host_mob, COMSIG_ADD_MOOD_EVENT, "nanite_sadness", /datum/mood_event/nanite_sadness, get_extra_setting_value(NES_MOOD_MESSAGE))
/datum/nanite_program/bad_mood/disable_passive_effect()
. = ..()
@@ -1,82 +1,29 @@
//Programs that interact with other programs or nanites directly, or have other special purposes.
/datum/nanite_program/viral
name = "Viral Replica"
desc = "The nanites constantly send encrypted signals attempting to forcefully copy their own programming into other nanite clusters."
desc = "The nanites constantly send encrypted signals attempting to forcefully copy their own programming into other nanite clusters, also overriding or disabling their cloud sync."
use_rate = 0.5
rogue_types = list(/datum/nanite_program/toxic)
extra_settings = list("Program Overwrite","Cloud Overwrite")
var/pulse_cooldown = 0
var/sync_programs = TRUE
var/sync_overwrite = FALSE
var/overwrite_cloud = FALSE
var/set_cloud = 0
/datum/nanite_program/viral/set_extra_setting(user, setting)
if(setting == "Program Overwrite")
var/overwrite_type = input("Choose what to do with the target's programs", name) as null|anything in list("Overwrite","Add To","Ignore")
if(!overwrite_type)
return
switch(overwrite_type)
if("Ignore") //Do not affect programs (if you only want to set the cloud ID)
sync_programs = FALSE
sync_overwrite = FALSE
if("Add To") //Add to existing programs (so the target does not notice theirs are missing)
sync_programs = TRUE
sync_overwrite = FALSE
if("Overwrite") //Replace target's programs with the source
sync_programs = TRUE
sync_overwrite = TRUE
if(setting == "Cloud Overwrite")
var/overwrite_type = input("Choose what to do with the target's Cloud ID", name) as null|anything in list("Overwrite","Disable","Keep")
if(!overwrite_type)
return
switch(overwrite_type)
if("Keep") //Don't change the cloud ID
overwrite_cloud = FALSE
set_cloud = 0
if("Disable") //Set the cloud ID to disabled
overwrite_cloud = TRUE
set_cloud = 0
if("Overwrite") //Set the cloud ID to what we choose
var/new_cloud = input(user, "Choose the Cloud ID to set on infected nanites (1-100)", name, null) as null|num
if(isnull(new_cloud))
return
overwrite_cloud = TRUE
set_cloud = CLAMP(round(new_cloud, 1), 1, 100)
/datum/nanite_program/viral/get_extra_setting(setting)
if(setting == "Program Overwrite")
if(!sync_programs)
return "Ignore"
else if(sync_overwrite)
return "Overwrite"
else
return "Add To"
if(setting == "Cloud Overwrite")
if(!overwrite_cloud)
return "None"
else if(set_cloud == 0)
return "Disable"
else
return set_cloud
/datum/nanite_program/viral/copy_extra_settings_to(datum/nanite_program/viral/target)
target.overwrite_cloud = overwrite_cloud
target.set_cloud = set_cloud
target.sync_programs = sync_programs
target.sync_overwrite = sync_overwrite
/datum/nanite_program/viral/register_extra_settings()
extra_settings[NES_PROGRAM_OVERWRITE] = new /datum/nanite_extra_setting/type("Add To", list("Overwrite", "Add To", "Ignore"))
extra_settings[NES_CLOUD_OVERWRITE] = new /datum/nanite_extra_setting/number(0, 0, 100)
/datum/nanite_program/viral/active_effect()
if(world.time < pulse_cooldown)
return
var/datum/nanite_extra_setting/program = extra_settings[NES_PROGRAM_OVERWRITE]
var/datum/nanite_extra_setting/cloud = extra_settings[NES_CLOUD_OVERWRITE]
for(var/mob/M in orange(host_mob, 5))
if(SEND_SIGNAL(M, COMSIG_NANITE_IS_STEALTHY))
continue
if(sync_programs)
SEND_SIGNAL(M, COMSIG_NANITE_SYNC, nanites, sync_overwrite)
if(overwrite_cloud)
SEND_SIGNAL(M, COMSIG_NANITE_SET_CLOUD, set_cloud)
switch(program.get_value())
if("Overwrite")
SEND_SIGNAL(M, COMSIG_NANITE_SYNC, nanites, TRUE)
if("Add To")
SEND_SIGNAL(M, COMSIG_NANITE_SYNC, nanites, FALSE)
SEND_SIGNAL(M, COMSIG_NANITE_SET_CLOUD, cloud.get_value())
pulse_cooldown = world.time + 75
/datum/nanite_program/monitoring
@@ -94,38 +41,23 @@
SSnanites.nanite_monitored_mobs -= host_mob
host_mob.hud_set_nanite_indicator()
/datum/nanite_program/triggered/self_scan
/datum/nanite_program/self_scan
name = "Host Scan"
desc = "The nanites display a detailed readout of a body scan to the host."
unique = FALSE
can_trigger = TRUE
trigger_cost = 3
trigger_cooldown = 50
rogue_types = list(/datum/nanite_program/toxic)
extra_settings = list("Scan Type")
var/scan_type = "Medical"
/datum/nanite_program/self_scan/register_extra_settings()
extra_settings[NES_SCAN_TYPE] = new /datum/nanite_extra_setting/type("Medical", list("Medical", "Chemical", "Nanite"))
/datum/nanite_program/triggered/self_scan/set_extra_setting(user, setting)
if(setting == "Scan Type")
var/list/scan_types = list("Medical","Chemical","Nanite")
var/new_scan_type = input("Choose the scan type", name) as null|anything in scan_types
if(!new_scan_type)
return
scan_type = new_scan_type
/datum/nanite_program/triggered/self_scan/get_extra_setting(setting)
if(setting == "Scan Type")
return scan_type
/datum/nanite_program/triggered/self_scan/copy_extra_settings_to(datum/nanite_program/triggered/self_scan/target)
target.scan_type = scan_type
/datum/nanite_program/triggered/self_scan/trigger()
if(!..())
return
/datum/nanite_program/self_scan/on_trigger(comm_message)
if(host_mob.stat == DEAD)
return
switch(scan_type)
var/datum/nanite_extra_setting/NS = extra_settings[NES_SCAN_TYPE]
switch(NS.get_value())
if("Medical")
healthscan(host_mob, host_mob)
if("Chemical")
@@ -162,28 +94,13 @@
. = ..()
nanites.diagnostics = TRUE
/datum/nanite_program/relay
name = "Relay"
desc = "The nanites receive and relay long-range nanite signals."
rogue_types = list(/datum/nanite_program/toxic)
extra_settings = list("Relay Channel")
var/relay_channel = 1
/datum/nanite_program/relay/set_extra_setting(user, setting)
if(setting == "Relay Channel")
var/new_channel = input(user, "Set the relay channel (1-9999):", name, null) as null|num
if(isnull(new_channel))
return
relay_channel = CLAMP(round(new_channel, 1), 1, 9999)
/datum/nanite_program/relay/get_extra_setting(setting)
if(setting == "Relay Channel")
return relay_channel
/datum/nanite_program/relay/copy_extra_settings_to(datum/nanite_program/relay/target)
target.relay_channel = relay_channel
/datum/nanite_program/relay/register_extra_settings()
extra_settings[NES_RELAY_CHANNEL] = new /datum/nanite_extra_setting/number(1, 1, 9999)
/datum/nanite_program/relay/enable_passive_effect()
. = ..()
@@ -198,7 +115,8 @@
return
if(!host_mob)
return
if(relay_code != relay_channel)
var/datum/nanite_extra_setting/NS = extra_settings[NES_RELAY_CHANNEL]
if(relay_code != NS.get_value())
return
SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, code, source)
@@ -207,7 +125,8 @@
return
if(!host_mob)
return
if(relay_code != relay_channel)
var/datum/nanite_extra_setting/NS = extra_settings[NES_RELAY_CHANNEL]
if(relay_code != NS.get_value())
return
SEND_SIGNAL(host_mob, COMSIG_NANITE_COMM_SIGNAL, comm_code, comm_message)
@@ -228,14 +147,64 @@
host_mob.nutrition -= 0.5
nanites.adjust_nanites(src, 0.5)
/datum/nanite_program/triggered/access
/datum/nanite_program/research
name = "Distributed Computing"
desc = "The nanites aid the research servers by performing a portion of its calculations, increasing research point generation."
use_rate = 0.2
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/research/active_effect()
if(!iscarbon(host_mob))
return
var/points = 1
if(!host_mob.client) //less brainpower
points *= 0.25
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points))
/datum/nanite_program/researchplus
name = "Neural Network"
desc = "The nanites link the host's brains together forming a neural research network, that becomes more efficient with the amount of total hosts."
use_rate = 0.3
rogue_types = list(/datum/nanite_program/brain_decay)
/datum/nanite_program/researchplus/enable_passive_effect()
. = ..()
if(!iscarbon(host_mob))
return
if(host_mob.client)
SSnanites.neural_network_count++
else
SSnanites.neural_network_count += 0.25
/datum/nanite_program/researchplus/disable_passive_effect()
. = ..()
if(!iscarbon(host_mob))
return
if(host_mob.client)
SSnanites.neural_network_count--
else
SSnanites.neural_network_count -= 0.25
/datum/nanite_program/researchplus/active_effect()
if(!iscarbon(host_mob))
return
var/mob/living/carbon/C = host_mob
var/points = round(SSnanites.neural_network_count / 12, 0.1)
if(!C.client) //less brainpower
points *= 0.25
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points))
/datum/nanite_program/access
name = "Subdermal ID"
desc = "The nanites store the host's ID access rights in a subdermal magnetic strip. Updates when triggered, copying the host's current access."
can_trigger = TRUE
trigger_cost = 3
trigger_cooldown = 30
rogue_types = list(/datum/nanite_program/skin_decay)
var/access = list()
//Syncs the nanites with the cumulative current mob's access level. Can potentially wipe existing access.
/datum/nanite_program/triggered/access/trigger()
/datum/nanite_program/access/on_trigger(comm_message)
var/list/new_access = list()
var/obj/item/current_item
current_item = host_mob.get_active_held_item()
@@ -284,19 +253,42 @@
SEND_SIGNAL(infectee, COMSIG_NANITE_SYNC, nanites)
infectee.investigate_log("was infected by spreading nanites by [key_name(host_mob)] at [AREACOORD(infectee)].", INVESTIGATE_NANITES)
/datum/nanite_program/nanite_sting
name = "Nanite Sting"
desc = "When triggered, projects a nearly invisible spike of nanites that attempts to infect a nearby non-host with a copy of the host's nanites cluster."
can_trigger = TRUE
trigger_cost = 5
trigger_cooldown = 100
rogue_types = list(/datum/nanite_program/glitch, /datum/nanite_program/toxic)
/datum/nanite_program/nanite_sting/on_trigger(comm_message)
var/list/mob/living/target_hosts = list()
for(var/mob/living/L in oview(1, host_mob))
if(!(L.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)) || SEND_SIGNAL(L, COMSIG_HAS_NANITES) || !L.Adjacent(host_mob))
continue
target_hosts += L
if(!target_hosts.len)
consume_nanites(-5)
return
var/mob/living/infectee = pick(target_hosts)
if(prob(100 - (infectee.get_permeability_protection() * 100)))
//unlike with Infective Exo-Locomotion, this can't take over existing nanites, because Nanite Sting only targets non-hosts.
infectee.AddComponent(/datum/component/nanites, 5)
SEND_SIGNAL(infectee, COMSIG_NANITE_SYNC, nanites)
infectee.investigate_log("was infected by a nanite cluster by [key_name(host_mob)] at [AREACOORD(infectee)].", INVESTIGATE_NANITES)
to_chat(infectee, "<span class='warning'>You feel a tiny prick.</span>")
/datum/nanite_program/mitosis
name = "Mitosis"
desc = "The nanites gain the ability to self-replicate, using bluespace to power the process, instead of drawing from a template. This rapidly speeds up the replication rate,\
but it causes occasional software errors due to faulty copies. Not compatible with cloud sync."
desc = "The nanites gain the ability to self-replicate, using bluespace to power the process. Becomes more effective the more nanites are already in the host.\
The replication has also a chance to corrupt the nanite programming due to copy faults - cloud sync is highly recommended."
use_rate = 0
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/mitosis/active_effect()
if(nanites.cloud_id)
return
var/rep_rate = round(nanites.nanite_volume / 50, 1) //0.5 per 50 nanite volume
rep_rate *= 0.5
nanites.adjust_nanites(rep_rate)
nanites.adjust_nanites(null, rep_rate)
if(prob(rep_rate))
var/datum/nanite_program/fault = pick(nanites.programs)
if(fault == src)
@@ -306,56 +298,22 @@
/datum/nanite_program/dermal_button
name = "Dermal Button"
desc = "Displays a button on the host's skin, which can be used to send a signal to the nanites."
extra_settings = list("Sent Code","Button Name","Icon","Color")
unique = FALSE
var/datum/action/innate/nanite_button/button
var/button_name = "Button"
var/icon = "power"
var/color = "green"
var/sent_code = 0
/datum/nanite_program/dermal_button/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Button Name")
var/new_button_name = stripped_input(user, "Choose the name for the button.", "Button Name", button_name, MAX_NAME_LEN)
if(!new_button_name)
return
button_name = new_button_name
if(setting == "Icon")
var/new_icon = input("Select the icon to display on the button:", name) as null|anything in list("one","two","three","four","five","plus","minus","power")
if(!new_icon)
return
icon = new_icon
if(setting == "Color")
var/new_color = input("Select the color of the button's icon:", name) as null|anything in list("green","red","yellow","blue")
if(!new_color)
return
color = new_color
/datum/nanite_program/dermal_button/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Button Name")
return button_name
if(setting == "Icon")
return capitalize(icon)
if(setting == "Color")
return capitalize(color)
/datum/nanite_program/dermal_button/copy_extra_settings_to(datum/nanite_program/dermal_button/target)
target.sent_code = sent_code
target.button_name = button_name
target.icon = icon
target.color = color
/datum/nanite_program/dermal_button/register_extra_settings()
extra_settings[NES_SENT_CODE] = new /datum/nanite_extra_setting/number(1, 1, 9999)
extra_settings[NES_BUTTON_NAME] = new /datum/nanite_extra_setting/text("Button")
extra_settings[NES_ICON] = new /datum/nanite_extra_setting/type("power", list("one","two","three","four","five","plus","minus","power"))
extra_settings[NES_COLOR] = new /datum/nanite_extra_setting/type("green", list("green","red","yellow","blue"))
/datum/nanite_program/dermal_button/enable_passive_effect()
. = ..()
var/datum/nanite_extra_setting/bn_name = extra_settings[NES_BUTTON_NAME]
var/datum/nanite_extra_setting/bn_icon = extra_settings[NES_ICON]
var/datum/nanite_extra_setting/bn_color = extra_settings[NES_COLOR]
if(!button)
button = new(src, button_name, icon, color)
button = new(src, bn_name.get_value(), bn_icon.get_value(), bn_color.get_value())
button.target = host_mob
button.Grant(host_mob)
@@ -372,7 +330,8 @@
if(activated)
host_mob.visible_message("<span class='notice'>[host_mob] presses a button on [host_mob.p_their()] forearm.</span>",
"<span class='notice'>You press the nanite button on your forearm.</span>", null, 2)
SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, sent_code, "a [name] program")
var/datum/nanite_extra_setting/sent_code = extra_settings[NES_SENT_CODE]
SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, sent_code.get_value(), "a [name] program")
/datum/action/innate/nanite_button
name = "Button"
@@ -389,51 +348,3 @@
/datum/action/innate/nanite_button/Activate()
program.press()
/datum/nanite_program/research
name = "Distributed Computing"
desc = "The nanites aid the research servers by performing a portion of its calculations, increasing research point generation."
use_rate = 0.2
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/research/active_effect()
if(!iscarbon(host_mob))
return
var/points = 1
if(!host_mob.client) //less brainpower
points *= 0.25
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points))
/datum/nanite_program/researchplus
name = "Neural Network"
desc = "The nanites link the host's brains together forming a neural research network, that becomes more efficient with the amount of total hosts."
use_rate = 0.3
rogue_types = list(/datum/nanite_program/brain_decay)
/datum/nanite_program/researchplus/enable_passive_effect()
. = ..()
if(!iscarbon(host_mob))
return
if(host_mob.client)
SSnanites.neural_network_count++
else
SSnanites.neural_network_count += 0.25
/datum/nanite_program/researchplus/disable_passive_effect()
. = ..()
if(!iscarbon(host_mob))
return
if(host_mob.client)
SSnanites.neural_network_count--
else
SSnanites.neural_network_count -= 0.25
/datum/nanite_program/researchplus/active_effect()
if(!iscarbon(host_mob))
return
var/mob/living/carbon/C = host_mob
var/points = round(SSnanites.neural_network_count / 12, 0.1)
if(!C.client) //less brainpower
points *= 0.25
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points))
@@ -73,21 +73,20 @@
. = ..()
to_chat(host_mob, "<span class='warning'>Your blood cools down, and the pain gradually fades.</span>")
/datum/nanite_program/triggered/explosive
/datum/nanite_program/explosive
name = "Chain Detonation"
desc = "Detonates all the nanites inside the host in a chain reaction when triggered."
can_trigger = TRUE
trigger_cost = 25 //plus every idle nanite left afterwards
trigger_cooldown = 100 //Just to avoid double-triggering
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/triggered/explosive/trigger()
if(!..())
return
/datum/nanite_program/explosive/on_trigger(comm_message)
host_mob.visible_message("<span class='warning'>[host_mob] starts emitting a high-pitched buzzing, and [host_mob.p_their()] skin begins to glow...</span>",\
"<span class='userdanger'>You start emitting a high-pitched buzzing, and your skin begins to glow...</span>")
addtimer(CALLBACK(src, .proc/boom), CLAMP((nanites.nanite_volume * 0.35), 25, 150))
/datum/nanite_program/triggered/explosive/proc/boom()
/datum/nanite_program/explosive/proc/boom()
var/nanite_amount = nanites.nanite_volume
var/heavy_range = FLOOR(nanite_amount/100, 1) - 1
var/light_range = FLOOR(nanite_amount/50, 1) - 1
@@ -96,16 +95,15 @@
//TODO make it defuse if triggered again
/datum/nanite_program/triggered/heart_stop
/datum/nanite_program/heart_stop
name = "Heart-Stopper"
desc = "Stops the host's heart when triggered; restarts it if triggered again."
can_trigger = TRUE
trigger_cost = 12
trigger_cooldown = 10
rogue_types = list(/datum/nanite_program/nerve_decay)
/datum/nanite_program/triggered/heart_stop/trigger()
if(!..())
return
/datum/nanite_program/heart_stop/on_trigger(comm_message)
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
var/obj/item/organ/heart/heart = C.getorganslot(ORGAN_SLOT_HEART)
@@ -115,16 +113,16 @@
else
heart.Restart()
/datum/nanite_program/triggered/emp
/datum/nanite_program/emp
name = "Electromagnetic Resonance"
desc = "The nanites cause an elctromagnetic pulse around the host when triggered. Will corrupt other nanite programs!"
desc = "The nanites cause an electromagnetic pulse around the host when triggered. Will corrupt other nanite programs!"
can_trigger = TRUE
trigger_cost = 10
trigger_cooldown = 50
program_flags = NANITE_EMP_IMMUNE
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/triggered/emp/trigger()
if(!..())
return
/datum/nanite_program/emp/on_trigger(comm_message)
empulse(host_mob, 1, 2)
/datum/nanite_program/pyro/active_effect()
@@ -148,7 +146,7 @@
/datum/nanite_program/cryo
name = "Cryogenic Treatment"
desc = "The nanites rapidly skin heat through the host's skin, lowering their temperature."
desc = "The nanites rapidly sink heat through the host's skin, lowering their temperature."
use_rate = 1
rogue_types = list(/datum/nanite_program/skin_decay, /datum/nanite_program/pyro)
@@ -160,55 +158,33 @@
/datum/nanite_program/cryo/active_effect()
host_mob.adjust_bodytemperature(-rand(15,25), 50)
/datum/nanite_program/triggered/comm/mind_control
/datum/nanite_program/comm/mind_control
name = "Mind Control"
desc = "The nanites imprint an absolute directive onto the host's brain for one minute when triggered."
trigger_cost = 30
trigger_cooldown = 1800
rogue_types = list(/datum/nanite_program/brain_decay, /datum/nanite_program/brain_misfire)
extra_settings = list("Directive","Comm Code")
var/directive = "..."
/datum/nanite_program/comm/mind_control/register_extra_settings()
. = ..()
extra_settings[NES_DIRECTIVE] = new /datum/nanite_extra_setting/text("...")
/datum/nanite_program/triggered/comm/mind_control/set_extra_setting(user, setting)
if(setting == "Directive")
var/new_directive = stripped_input(user, "Choose the directive to imprint with mind control.", "Directive", directive, MAX_MESSAGE_LEN)
if(!new_directive)
return
directive = new_directive
if(setting == "Comm Code")
var/new_code = input(user, "Set the communication code (1-9999) or set to 0 to disable external signals.", name, null) as null|num
if(isnull(new_code))
return
comm_code = CLAMP(round(new_code, 1), 0, 9999)
/datum/nanite_program/triggered/comm/mind_control/get_extra_setting(setting)
if(setting == "Directive")
return directive
if(setting == "Comm Code")
return comm_code
/datum/nanite_program/triggered/comm/mind_control/copy_extra_settings_to(datum/nanite_program/triggered/comm/mind_control/target)
target.directive = directive
target.comm_code = comm_code
/datum/nanite_program/triggered/comm/mind_control/trigger(comm_message)
if(!..())
return
/datum/nanite_program/comm/mind_control/on_trigger(comm_message)
if(host_mob.stat == DEAD)
return
var/sent_directive = comm_message
if(!comm_message)
sent_directive = directive
var/datum/nanite_extra_setting/ES = extra_settings[NES_DIRECTIVE]
sent_directive = ES.get_value()
brainwash(host_mob, sent_directive)
log_game("A mind control nanite program brainwashed [key_name(host_mob)] with the objective '[directive]'.")
log_game("A mind control nanite program brainwashed [key_name(host_mob)] with the objective '[sent_directive]'.")
addtimer(CALLBACK(src, .proc/end_brainwashing), 600)
/datum/nanite_program/triggered/comm/mind_control/proc/end_brainwashing()
/datum/nanite_program/comm/mind_control/proc/end_brainwashing()
if(host_mob.mind && host_mob.mind.has_antag_datum(/datum/antagonist/brainwashed))
host_mob.mind.remove_antag_datum(/datum/antagonist/brainwashed)
log_game("[key_name(host_mob)] is no longer brainwashed by nanites.")
/datum/nanite_program/triggered/comm/mind_control/disable_passive_effect()
/datum/nanite_program/comm/mind_control/disable_passive_effect()
. = ..()
end_brainwashing()