//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, also overriding or disabling their cloud sync." use_rate = 0.5 rogue_types = list(/datum/nanite_program/toxic) var/pulse_cooldown = 0 /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 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 name = "Monitoring" desc = "The nanites monitor the host's vitals and location, sending them to the suit sensor network." rogue_types = list(/datum/nanite_program/toxic) /datum/nanite_program/monitoring/enable_passive_effect() . = ..() SSnanites.nanite_monitored_mobs |= host_mob host_mob.hud_set_nanite_indicator() /datum/nanite_program/monitoring/disable_passive_effect() . = ..() SSnanites.nanite_monitored_mobs -= host_mob host_mob.hud_set_nanite_indicator() /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) /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/self_scan/on_trigger(comm_message) if(host_mob.stat == DEAD) return var/datum/nanite_extra_setting/NS = extra_settings[NES_SCAN_TYPE] switch(NS.get_value()) if("Medical") healthscan(host_mob, host_mob) if("Chemical") chemscan(host_mob, host_mob) if("Nanite") SEND_SIGNAL(host_mob, COMSIG_NANITE_SCAN, host_mob, TRUE) /datum/nanite_program/stealth name = "Stealth" desc = "The nanites mask their activity from superficial scans, becoming undetectable by HUDs and non-specialized scanners." rogue_types = list(/datum/nanite_program/toxic) use_rate = 0.2 /datum/nanite_program/stealth/enable_passive_effect() . = ..() nanites.stealth = TRUE /datum/nanite_program/stealth/disable_passive_effect() . = ..() nanites.stealth = FALSE /datum/nanite_program/reduced_diagnostics name = "Reduced Diagnostics" desc = "Disables some high-cost diagnostics in the nanites, making them unable to communicate their program list to portable scanners. \ Doing so saves some power, slightly increasing their replication speed." rogue_types = list(/datum/nanite_program/toxic) use_rate = -0.1 /datum/nanite_program/reduced_diagnostics/enable_passive_effect() . = ..() nanites.diagnostics = FALSE /datum/nanite_program/reduced_diagnostics/disable_passive_effect() . = ..() 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) /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() . = ..() SSnanites.nanite_relays |= src /datum/nanite_program/relay/disable_passive_effect() . = ..() SSnanites.nanite_relays -= src /datum/nanite_program/relay/proc/relay_signal(code, relay_code, source) if(!activated) return if(!host_mob) return 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) /datum/nanite_program/relay/proc/relay_comm_signal(comm_code, relay_code, comm_message) if(!activated) return if(!host_mob) return 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) /datum/nanite_program/metabolic_synthesis name = "Metabolic Synthesis" desc = "The nanites use the metabolic cycle of the host to speed up their replication rate, using their extra nutrition as fuel." rogue_types = list(/datum/nanite_program/toxic) /datum/nanite_program/metabolic_synthesis/check_conditions() if(!iscarbon(host_mob)) return FALSE var/mob/living/carbon/C = host_mob if(C.nutrition <= NUTRITION_LEVEL_FED) return FALSE return ..() /datum/nanite_program/metabolic_synthesis/active_effect() host_mob.nutrition -= 0.5 nanites.adjust_nanites(src, 0.5) /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/access/on_trigger(comm_message) var/list/new_access = list() var/obj/item/current_item current_item = host_mob.get_active_held_item() if(current_item) new_access += current_item.GetAccess() current_item = host_mob.get_inactive_held_item() if(current_item) new_access += current_item.GetAccess() if(ishuman(host_mob)) var/mob/living/carbon/human/H = host_mob current_item = H.wear_id if(current_item) new_access += current_item.GetAccess() else if(isanimal(host_mob)) var/mob/living/simple_animal/A = host_mob current_item = A.access_card if(current_item) new_access += current_item.GetAccess() access = new_access /datum/nanite_program/spreading name = "Infective Exo-Locomotion" desc = "The nanites gain the ability to survive for brief periods outside of the human body, as well as the ability to start new colonies without an integration process; \ resulting in an extremely infective strain of nanites." use_rate = 1.50 rogue_types = list(/datum/nanite_program/aggressive_replication, /datum/nanite_program/necrotic) var/spread_cooldown = 0 /datum/nanite_program/spreading/active_effect() if(spread_cooldown < world.time) return spread_cooldown = world.time + 50 var/list/mob/living/target_hosts = list() for(var/mob/living/L in oview(5, host_mob)) if(!prob(25)) continue if(!(L.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) continue target_hosts += L if(!target_hosts.len) return var/mob/living/infectee = pick(target_hosts) if(prob(100 - (infectee.get_permeability_protection() * 100))) //this will potentially take over existing nanites! infectee.AddComponent(/datum/component/nanites, 10) 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, "You feel a tiny prick.") /datum/nanite_program/mitosis name = "Mitosis" 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() var/rep_rate = round(nanites.nanite_volume / 50, 1) //0.5 per 50 nanite volume rep_rate *= 0.5 nanites.adjust_nanites(null, rep_rate) if(prob(rep_rate)) var/datum/nanite_program/fault = pick(nanites.programs) if(fault == src) return fault.software_error() /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." unique = FALSE var/datum/action/innate/nanite_button/button /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, bn_name.get_value(), bn_icon.get_value(), bn_color.get_value()) button.target = host_mob button.Grant(host_mob) /datum/nanite_program/dermal_button/disable_passive_effect() . = ..() if(button) button.Remove(host_mob) /datum/nanite_program/dermal_button/on_mob_remove() . = ..() qdel(button) /datum/nanite_program/dermal_button/proc/press() if(activated) host_mob.visible_message("[host_mob] presses a button on [host_mob.p_their()] forearm.", "You press the nanite button on your forearm.", null, 2) 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" icon_icon = 'icons/mob/actions/actions_items.dmi' check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS button_icon_state = "power_green" var/datum/nanite_program/dermal_button/program /datum/action/innate/nanite_button/New(datum/nanite_program/dermal_button/_program, _name, _icon, _color) ..() program = _program name = _name button_icon_state = "[_icon]_[_color]" /datum/action/innate/nanite_button/Activate() program.press()