Replaces some borer progression with an upgrade tree (#16704)

* borer wormening

* time to go

* synthetic boring

* lc-chest

* cleans unneeded logic

* warn against only 1 T3+

* _
This commit is contained in:
Zonespace
2022-10-08 19:56:21 -04:00
committed by GitHub
parent c251d24526
commit c4a2db206c
17 changed files with 970 additions and 149 deletions
@@ -18,3 +18,25 @@
/// Population requirement for bomb objectives (ninja c4, locate weakpoint, etc.) objectives to appear
#define BOMB_POP_REQUIREMENT 80
// Borer evolution defines
// The three primary paths that eventually diverge
#define BORER_EVOLUTION_SYMBIOTE "Symbiote"
#define BORER_EVOLUTION_HIVELORD "Hivelord"
#define BORER_EVOLUTION_DIVEWORM "Diveworm"
// Just general upgrades that don't take you in a specific direction
#define BORER_EVOLUTION_GENERAL "General"
#define BORER_EVOLUTION_START "Start"
// Borer effect flags
/// If the borer is in stealth mode, giving less feedback to hosts at the cost of no health/resource/point gain
#define BORER_STEALTH_MODE (1<<0)
/// If the borer is sugar-immune, taking no ill effects from sugar
#define BORER_SUGAR_IMMUNE (1<<1)
/// If the borer is able to enter hosts in half the time, if not hiding
#define BORER_FAST_BORING (1<<2)
/// If the borer is currently hiding under tables/couches/stairs or appearing on top of them
#define BORER_HIDING (1<<3)
/// If the borer can produce eggs without a host
#define BORER_ALONE_PRODUCTION (1<<4)
+7 -2
View File
@@ -1,4 +1,4 @@
//This logs subtler emotes in game.txt, if the conflig flag in config\skyrat\skyrat_config.txt is true.
/// This logs subtler emotes in game.txt, if the conflig flag in config\skyrat\skyrat_config.txt is true.
/proc/log_subtler(text)
if (CONFIG_GET(flag/log_subtler))
WRITE_LOG(GLOB.world_game_log, "SUBTLER EMOTE: [text]")
@@ -6,6 +6,11 @@
GLOBAL_VAR(character_creation_log)
GLOBAL_PROTECT(character_creation_log)
//This logs subtler emotes in game.txt, if the conflig flag in config\skyrat\skyrat_config.txt is true.
/// This logs subtler emotes in game.txt, if the conflig flag in config\skyrat\skyrat_config.txt is true.
/proc/log_creator(text)
WRITE_LOG(GLOB.character_creation_log, "CREATOR LOG: [text]")
/// Logging for borer evolutions
/proc/log_borer_evolution(text)
if (CONFIG_GET(flag/log_uplink))
WRITE_LOG(GLOB.world_uplink_log, "BORER EVOLUTION: [text]")
@@ -11,9 +11,12 @@
/datum/action/changeling/panacea/sting_action(mob/user)
to_chat(user, span_notice("We cleanse impurities from our form."))
..()
// SKYRAT EDIT ADDITION: BORER EGG
var/list/bad_organs = list(
user.getorgan(/obj/item/organ/internal/body_egg),
user.getorgan(/obj/item/organ/internal/zombie_infection))
user.getorgan(/obj/item/organ/internal/zombie_infection),
user.getorgan(/obj/item/organ/internal/empowered_borer_egg))
// SKYRAT EDIT END
try_to_mutant_cure(user) //SKYRAT EDIT ADDITION
@@ -11,10 +11,13 @@ GLOBAL_VAR_INIT(successful_blood_chem, 0)
GLOBAL_LIST_EMPTY(cortical_borers)
//we need a way of buffing leg speed
/datum/movespeed_modifier/borer_speed
/datum/movespeed_modifier/focus_speed
multiplicative_slowdown = -0.4
/datum/actionspeed_modifier/borer_speed
/datum/movespeed_modifier/borer_speed
multiplicative_slowdown = -0.5
/datum/actionspeed_modifier/focus_speed
multiplicative_slowdown = -0.3
id = ACTIONSPEED_ID_BORER
@@ -122,24 +125,28 @@ GLOBAL_LIST_EMPTY(cortical_borers)
var/chemical_storage = 50
///how fast chemicals are gained. Goes up only when inside a host
var/chemical_regen = 1
/// How much health you gain per level
var/health_per_level = 2.5
/// How much health regen you gain per level
var/health_regen_per_level = 0.02
/// How much more chemical storage you gain per level
var/chem_storage_per_level = 20
/// Chemical regen you gain per level
var/chem_regen_per_level = 1
/// How many times you've levelled up over all
var/level = 0
///the list of actions that the borer has
var/list/known_abilities = list(/datum/action/cooldown/borer/toggle_hiding,
/datum/action/cooldown/borer/choosing_host,
/datum/action/cooldown/borer/evolution_tree,
/datum/action/cooldown/borer/inject_chemical,
/datum/action/cooldown/borer/upgrade_chemical,
/datum/action/cooldown/borer/learn_focus,
/datum/action/cooldown/borer/upgrade_stat,
/datum/action/cooldown/borer/learn_ability,
/datum/action/cooldown/borer/force_speak,
/datum/action/cooldown/borer/fear_human,
/datum/action/cooldown/borer/check_blood,
)
///the list of actions that the borer could learn
var/possible_abilities = list(/datum/action/cooldown/borer/produce_offspring,
/datum/action/cooldown/borer/learn_bloodchemical,
/datum/action/cooldown/borer/revive_host,
/datum/action/cooldown/borer/willing_host,
)
///the host
var/mob/living/carbon/human/human_host
//what the host gains or loses with the borer
@@ -183,6 +190,14 @@ GLOBAL_LIST_EMPTY(cortical_borers)
var/injection_rate_current = 5
/// Cooldown between injecting chemicals
COOLDOWN_DECLARE(injection_cooldown)
/// Evolutions we've already learned
var/list/past_evolutions = list()
/// Bitflag of upgrades and effects the borer has
var/upgrade_flags = 0
/// If the borer has evolved with a genome that locks out others of the same & higher tier
var/genome_locked = FALSE
/// Multiplier for a borer's negative effects to their host
var/host_harm_multiplier = 1
/mob/living/simple_animal/cortical_borer/Initialize(mapload)
. = ..()
@@ -205,6 +220,7 @@ GLOBAL_LIST_EMPTY(cortical_borers)
mind.add_antag_datum(/datum/antagonist/cortical_borer)
for(var/focus_path in subtypesof(/datum/borer_focus))
possible_focuses += new focus_path
do_evolution(/datum/borer_evolution/base)
/mob/living/simple_animal/cortical_borer/Destroy()
human_host = null
@@ -251,8 +267,8 @@ GLOBAL_LIST_EMPTY(cortical_borers)
return
//there needs to be a negative to having a borer
if(prob(5) && human_host.getToxLoss() <= 80)
human_host.adjustToxLoss(5, TRUE, TRUE)
if(prob(5 * host_harm_multiplier * ((upgrade_flags & BORER_STEALTH_MODE) ? 0.1 : 1)) && human_host.getToxLoss() <= (80 * host_harm_multiplier))
human_host.adjustToxLoss(5 * host_harm_multiplier, TRUE, TRUE)
human_host.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
@@ -266,43 +282,17 @@ GLOBAL_LIST_EMPTY(cortical_borers)
//this is regenerating chemical_storage
if(chemical_storage < max_chemical_storage)
chemical_storage = min(chemical_storage + chemical_regen, max_chemical_storage)
if(chemical_storage > max_chemical_storage)
chemical_storage = max_chemical_storage
if(!(upgrade_flags & BORER_STEALTH_MODE))
chemical_storage = min(chemical_storage + chemical_regen, max_chemical_storage)
//this is regenerating health
if(health < maxHealth)
health = min(health * health_regen, maxHealth)
if(health > maxHealth)
health = maxHealth
if(!(upgrade_flags & BORER_STEALTH_MODE))
health = min(health * health_regen, maxHealth)
//this is so they can evolve
if(timed_maturity < world.time)
timed_maturity = world.time + 1 SECONDS
maturity_age++
//20:40, 15:30, 10:20, 5:10
var/maturity_threshold = 20
if(GLOB.successful_egg_number >= GLOB.objective_egg_borer_number)
maturity_threshold -= 2
if(length(GLOB.willing_hosts) >= GLOB.objective_willing_hosts)
maturity_threshold -= 10
if(GLOB.successful_blood_chem >= GLOB.objective_blood_borer)
maturity_threshold -= 3
if(maturity_age == maturity_threshold)
if(chemical_evolution < limited_borer) //you can only have a default of 10 at a time
chemical_evolution++
to_chat(src, span_notice("You gain a chemical evolution point. Spend it to learn a new chemical!"))
else
to_chat(src, span_warning("You were unable to gain a chemical evolution point due to having the max!"))
if(maturity_age >= (maturity_threshold * 2))
if(stat_evolution < limited_borer)
stat_evolution++
to_chat(src, span_notice("You gain a stat evolution point. Spend it to become stronger!"))
else
to_chat(src, span_warning("You were unable to gain a stat evolution point due to having the max!"))
maturity_age = 0
mature()
//if it doesnt have a ckey, let ghosts have it
/mob/living/simple_animal/cortical_borer/attack_ghost(mob/dead/observer/user)
@@ -330,6 +320,8 @@ GLOBAL_LIST_EMPTY(cortical_borers)
//check if the host has sugar
/mob/living/simple_animal/cortical_borer/proc/host_sugar()
if(upgrade_flags & BORER_SUGAR_IMMUNE)
return FALSE
if(human_host?.reagents?.has_reagent(/datum/reagent/consumable/sugar))
return TRUE
return FALSE
@@ -387,3 +379,56 @@ GLOBAL_LIST_EMPTY(cortical_borers)
/mob/living/simple_animal/cortical_borer/start_pulling(atom/movable/AM, state, force, supress_message)
to_chat(src, span_warning("You cannot pull things!"))
return
/// Called on Life() for the borer to age a bit
/mob/living/simple_animal/cortical_borer/proc/mature()
. = TRUE
if(upgrade_flags & BORER_STEALTH_MODE)
return FALSE
timed_maturity = world.time + 1 SECONDS
maturity_age++
//20:40, 15:30, 10:20, 5:10
var/maturity_threshold = 20
if(GLOB.successful_egg_number >= GLOB.objective_egg_borer_number)
maturity_threshold -= 2
if(length(GLOB.willing_hosts) >= GLOB.objective_willing_hosts)
maturity_threshold -= 10
if(GLOB.successful_blood_chem >= GLOB.objective_blood_borer)
maturity_threshold -= 3
if(maturity_age == maturity_threshold)
if(chemical_evolution < limited_borer) //you can only have a default of 10 at a time
chemical_evolution++
to_chat(src, span_notice("You gain a chemical evolution point. Spend it to learn a new chemical!"))
else
to_chat(src, span_warning("You were unable to gain a chemical evolution point due to having the max!"))
if(maturity_age >= (maturity_threshold * 2))
if(stat_evolution < limited_borer)
stat_evolution++
to_chat(src, span_notice("You gain a stat evolution point. Spend it to become stronger!"))
else
to_chat(src, span_warning("You were unable to gain a stat evolution point due to having the max!"))
maturity_age = 0
/// Use to recalculate a borer's health and chemical stats when something retroactively affects them
/mob/living/simple_animal/cortical_borer/proc/recalculate_stats()
var/old_health = health
maxHealth = initial(maxHealth) * (level + 1) * health_per_level
health_regen = initial(health_regen) * (level + 1) * health_regen_per_level
max_chemical_storage = initial(max_chemical_storage) * (level + 1) * chem_storage_per_level
chemical_regen = initial(chemical_regen) * (level + 1) * chem_regen_per_level
health = clamp(old_health, 0, maxHealth)
// Only able to spawn from an egg burst from a corpse, starts off stronger
/mob/living/simple_animal/cortical_borer/empowered
maxHealth = 150
health = 150
health_per_level = 15
health_regen_per_level = 0.04
stat_evolution = 8
chemical_evolution = 8
max_chemical_storage = 250
chemical_storage = 250
chem_regen_per_level = 1.5
chem_storage_per_level = 25
@@ -1,10 +1,11 @@
#define CHEMICALS_PER_UNIT 2
#define CHEMICAL_SECOND_DIVISOR 5 SECONDS
#define OUT_OF_HOST_EGG_COST 50
// Parent of all borer actions
/datum/action/cooldown/borer
icon_icon = 'modular_skyrat/modules/cortical_borer/icons/actions.dmi'
cooldown_time = 1 SECONDS
cooldown_time = 0
/datum/action/cooldown/borer/Trigger(trigger_flags, atom/target)
. = ..()
@@ -41,7 +42,7 @@
ui.open()
/datum/action/cooldown/borer/inject_chemical/ui_data(mob/user)
var/data = list()
var/list/data = list()
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
data["amount"] = cortical_owner.injection_rate_current
data["energy"] = cortical_owner.chemical_storage / CHEMICALS_PER_UNIT
@@ -81,11 +82,14 @@
var/reagent = GLOB.name2reagent[reagent_name]
if(!(reagent in cortical_owner.known_chemicals))
return
cortical_owner.reagent_holder.reagents.add_reagent(reagent, cortical_owner.injection_rate_current, added_purity = 1)
cortical_owner.reagent_holder.reagents.trans_to(cortical_owner.human_host, cortical_owner.injection_rate_current, methods = INGEST)
to_chat(cortical_owner.human_host, span_warning("You feel something cool inside of you and a dull ache in your head!"))
cortical_owner.chemical_storage -= cortical_owner.injection_rate_current * CHEMICALS_PER_UNIT
COOLDOWN_START(cortical_owner, injection_cooldown, (cortical_owner.injection_rate_current / CHEMICAL_SECOND_DIVISOR))
var/turf/human_turf = get_turf(cortical_owner.human_host)
var/logging_text = "[key_name(cortical_owner)] injected [key_name(cortical_owner.human_host)] with [reagent_name] at [loc_name(human_turf)]"
cortical_owner.log_message(logging_text, LOG_GAME)
@@ -98,11 +102,103 @@
/datum/action/cooldown/borer/inject_chemical/ui_status(mob/user, datum/ui_state/state)
if(!iscorticalborer(user))
return UI_CLOSE
var/mob/living/simple_animal/cortical_borer/borer = user
if(!borer.human_host)
return UI_CLOSE
return ..()
/datum/action/cooldown/borer/evolution_tree
name = "Open Evolution Tree"
button_icon_state = "newability"
/datum/action/cooldown/borer/evolution_tree/Trigger(trigger_flags)
. = ..()
if(!.)
return FALSE
ui_interact(owner)
/datum/action/cooldown/borer/evolution_tree/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "BorerEvolution", name)
ui.open()
/datum/action/cooldown/borer/evolution_tree/ui_data(mob/user)
var/list/data = list()
var/static/list/path_to_color = list(
BORER_EVOLUTION_DIVEWORM = "red",
BORER_EVOLUTION_HIVELORD = "purple",
BORER_EVOLUTION_SYMBIOTE = "green",
BORER_EVOLUTION_GENERAL = "label",
)
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
data["evolution_points"] = cortical_owner.stat_evolution
for(var/datum/borer_evolution/evolution as anything in cortical_owner.get_possible_evolutions())
if(evolution in cortical_owner.past_evolutions)
continue
var/list/evo_data = list()
evo_data["path"] = evolution
evo_data["name"] = initial(evolution.name)
evo_data["desc"] = initial(evolution.desc)
evo_data["gainFlavor"] = initial(evolution.gain_text)
evo_data["cost"] = initial(evolution.evo_cost)
evo_data["disabled"] = ((initial(evolution.evo_cost) > cortical_owner.stat_evolution) || (initial(evolution.mutually_exclusive) && cortical_owner.genome_locked))
evo_data["evoPath"] = initial(evolution.evo_type)
evo_data["color"] = path_to_color[initial(evolution.evo_type)] || "grey"
evo_data["tier"] = initial(evolution.tier)
evo_data["exclusive"] = initial(evolution.mutually_exclusive)
data["learnableEvolution"] += list(evo_data)
for(var/path in cortical_owner.past_evolutions)
var/list/evo_data = list()
var/datum/borer_evolution/found_evolution = cortical_owner.past_evolutions[path]
evo_data["name"] = found_evolution.name
evo_data["desc"] = found_evolution.desc
evo_data["gainFlavor"] = found_evolution.gain_text
evo_data["cost"] = found_evolution.evo_cost
evo_data["evoPath"] = found_evolution.evo_type
evo_data["color"] = path_to_color[found_evolution.evo_type] || "grey"
evo_data["tier"] = found_evolution.tier
data["learnedEvolution"] += list(evo_data)
return data
/datum/action/cooldown/borer/evolution_tree/ui_act(action, params)
. = ..()
if(.)
return
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
switch(action)
if("evolve")
var/datum/borer_evolution/to_evolve_path = text2path(params["path"])
if(!ispath(to_evolve_path))
CRASH("Cortical borer attempted to evolve with a non-evolution path! (Got: [to_evolve_path])")
if(initial(to_evolve_path.evo_cost) > cortical_owner.stat_evolution)
return
if(initial(to_evolve_path.mutually_exclusive) && cortical_owner.genome_locked)
return
if(!cortical_owner.do_evolution(to_evolve_path))
return
log_borer_evolution("[key_name(owner)] gained knowledge: [initial(to_evolve_path.name)]")
cortical_owner.stat_evolution -= initial(to_evolve_path.evo_cost)
return TRUE
/datum/action/cooldown/borer/evolution_tree/ui_state(mob/user)
return GLOB.always_state
/datum/action/cooldown/borer/learn_focus
name = "Learn Focus"
button_icon_state = "getfocus"
@@ -183,7 +279,7 @@
cortical_owner.blood_chems_learned++
var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.getorganslot(ORGAN_SLOT_BRAIN)
if(victim_brain)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier)
if(cortical_owner.blood_chems_learned == 5)
GLOB.successful_blood_chem += 1
owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned")
@@ -223,7 +319,7 @@
cortical_owner.potential_chemicals -= reagent_choice
var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.getorganslot(ORGAN_SLOT_BRAIN)
if(victim_brain)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier)
owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned")
to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!"))
StartCooldown()
@@ -248,14 +344,14 @@
owner.balloon_alert(owner, "1 stat evolution point required")
return
cortical_owner.stat_evolution--
cortical_owner.maxHealth += 5
cortical_owner.health_regen += 0.02
cortical_owner.max_chemical_storage += 20
cortical_owner.chemical_regen++
cortical_owner.maxHealth += cortical_owner.health_per_level
cortical_owner.health_regen += cortical_owner.health_regen_per_level
cortical_owner.max_chemical_storage += cortical_owner.chem_storage_per_level
cortical_owner.chemical_regen += cortical_owner.chem_regen_per_level
var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.getorganslot(ORGAN_SLOT_BRAIN)
if(victim_brain)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
cortical_owner.human_host.adjust_blurriness(3) //about 12 seconds' worth
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10 * cortical_owner.host_harm_multiplier)
cortical_owner.human_host.adjust_blurriness(3 * cortical_owner.host_harm_multiplier) //about 12 seconds' worth by default
to_chat(cortical_owner, span_notice("You have grown!"))
to_chat(cortical_owner.human_host, span_warning("You feel a sharp pressure in your head!"))
StartCooldown()
@@ -269,11 +365,14 @@
. = ..()
if(!.)
return FALSE
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
if(owner.layer == PROJECTILE_HIT_THRESHHOLD_LAYER)
cortical_owner.upgrade_flags &= ~BORER_HIDING
owner.balloon_alert(owner, "stopped hiding")
owner.layer = BELOW_MOB_LAYER
StartCooldown()
return
cortical_owner.upgrade_flags |= BORER_HIDING
owner.balloon_alert(owner, "started hiding")
owner.layer = PROJECTILE_HIT_THRESHHOLD_LAYER
StartCooldown()
@@ -377,7 +476,8 @@
owner.balloon_alert(owner, "cannot function with sugar in host")
return
owner.balloon_alert(owner, "detached from host")
to_chat(cortical_owner.human_host, span_notice("Something carefully tickles your inner ear..."))
if(!(cortical_owner.upgrade_flags & BORER_STEALTH_MODE))
to_chat(cortical_owner.human_host, span_notice("Something carefully tickles your inner ear..."))
var/obj/item/organ/internal/borer_body/borer_organ = locate() in cortical_owner.human_host.internal_organs
//log the interaction
var/turf/human_turfone = get_turf(cortical_owner.human_host)
@@ -419,7 +519,7 @@
if(singular_host.has_borer())
owner.balloon_alert(owner, "target already occupied")
return
if(!do_after(cortical_owner, 6 SECONDS, target = singular_host))
if(!do_after(cortical_owner, ((cortical_owner.upgrade_flags & BORER_FAST_BORING) && (cortical_owner.upgrade_flags & BORER_HIDING) ? 3 SECONDS : 6 SECONDS), target = singular_host))
owner.balloon_alert(owner, "you and target must be still")
return
if(get_dist(singular_host, cortical_owner) > 1)
@@ -427,7 +527,8 @@
return
cortical_owner.human_host = singular_host
cortical_owner.forceMove(cortical_owner.human_host)
to_chat(cortical_owner.human_host, span_notice("A chilling sensation goes down your spine..."))
if(!(cortical_owner.upgrade_flags & BORER_STEALTH_MODE))
to_chat(cortical_owner.human_host, span_notice("A chilling sensation goes down your spine..."))
cortical_owner.copy_languages(cortical_owner.human_host)
var/obj/item/organ/internal/borer_body/borer_organ = new(cortical_owner.human_host)
borer_organ.borer = owner
@@ -448,7 +549,7 @@
if(choosen_human.has_borer())
owner.balloon_alert(owner, "target already occupied")
return
if(!do_after(cortical_owner, 6 SECONDS, target = choose_host))
if(!do_after(cortical_owner, ((cortical_owner.upgrade_flags & BORER_FAST_BORING) && (cortical_owner.upgrade_flags & BORER_HIDING) ? 3 SECONDS : 6 SECONDS), target = choose_host))
owner.balloon_alert(owner, "you and target must be still")
return
if(get_dist(choose_host, cortical_owner) > 1)
@@ -494,7 +595,7 @@
to_chat(cortical_host, span_boldwarning("Your voice moves without your permission!"))
var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.getorganslot(ORGAN_SLOT_BRAIN)
if(victim_brain)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * cortical_owner.host_harm_multiplier)
cortical_host.say(message = borer_message, forced = TRUE)
var/turf/human_turf = get_turf(cortical_owner.human_host)
var/logging_text = "[key_name(cortical_owner)] forced [key_name(cortical_owner.human_host)] to say [borer_message] at [loc_name(human_turf)]"
@@ -513,22 +614,21 @@
if(!.)
return FALSE
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
if(!cortical_owner.inside_human())
if(!(cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human())
owner.balloon_alert(owner, "host required")
return
if(cortical_owner.chemical_storage < 100)
owner.balloon_alert(owner, "100 chemical points required")
return
cortical_owner.chemical_storage -= 100
var/turf/borer_turf = get_turf(cortical_owner)
var/obj/effect/mob_spawn/ghost_role/borer_egg/spawned_egg = new /obj/effect/mob_spawn/ghost_role/borer_egg(borer_turf)
spawned_egg.generation = (cortical_owner.generation + 1)
cortical_owner.children_produced++
if(cortical_owner.children_produced == GLOB.objective_egg_egg_number)
GLOB.successful_egg_number += 1
if((cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human())
no_host_egg()
StartCooldown()
return
produce_egg()
var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.getorganslot(ORGAN_SLOT_BRAIN)
if(victim_brain)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25)
cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25 * cortical_owner.host_harm_multiplier)
var/eggroll = rand(1,100)
if(eggroll <= 75)
switch(eggroll)
@@ -541,6 +641,7 @@
if(72 to 75)
cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
to_chat(cortical_owner.human_host, span_warning("Your brain begins to hurt..."))
var/turf/borer_turf = get_turf(cortical_owner)
new /obj/effect/decal/cleanable/vomit(borer_turf)
playsound(borer_turf, 'sound/effects/splat.ogg', 50, TRUE)
var/logging_text = "[key_name(cortical_owner)] gave birth at [loc_name(borer_turf)]"
@@ -548,6 +649,26 @@
owner.balloon_alert(owner, "egg laid")
StartCooldown()
/datum/action/cooldown/borer/produce_offspring/proc/no_host_egg()
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
cortical_owner.health = max(cortical_owner.health, 1, cortical_owner.health -= OUT_OF_HOST_EGG_COST)
produce_egg()
var/turf/borer_turf = get_turf(cortical_owner)
new/obj/effect/decal/cleanable/blood/splatter(borer_turf)
playsound(borer_turf, 'sound/effects/splat.ogg', 50, TRUE)
var/logging_text = "[key_name(cortical_owner)] gave birth alone at [loc_name(borer_turf)]"
cortical_owner.log_message(logging_text, LOG_GAME)
owner.balloon_alert(owner, "egg laid")
/datum/action/cooldown/borer/produce_offspring/proc/produce_egg()
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
var/turf/borer_turf = get_turf(cortical_owner)
var/obj/effect/mob_spawn/ghost_role/borer_egg/spawned_egg = new /obj/effect/mob_spawn/ghost_role/borer_egg(borer_turf)
spawned_egg.generation = (cortical_owner.generation + 1)
cortical_owner.children_produced++
if(cortical_owner.children_produced == GLOB.objective_egg_egg_number)
GLOB.successful_egg_number += 1
//revive your host
/datum/action/cooldown/borer/revive_host
name = "Revive Host (200 chemicals)"
@@ -590,82 +711,6 @@
cortical_owner.human_host.log_message(logging_text, LOG_GAME)
StartCooldown()
//certain abilities are now locked, you have to learn them
/datum/action/cooldown/borer/learn_ability
name = "Learn Ability (2 stat points)"
button_icon_state = "newability"
/datum/action/cooldown/borer/learn_ability/Trigger(trigger_flags)
. = ..()
if(!.)
return FALSE
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
if(!cortical_owner.inside_human())
owner.balloon_alert(owner, "host required")
return
if(cortical_owner.host_sugar())
owner.balloon_alert(owner, "cannot function with sugar in host")
return
if(cortical_owner.stat_evolution < 2)
owner.balloon_alert(owner, "2 stat points required")
return
cortical_owner.stat_evolution -= 2
var/list/abil_list = list("Produce Offspring", "Learn Chemical from Blood", "Revive Host", "Willing Host", "Upgrade Injection")
for(var/ability in abil_list)
switch(ability)
if("Produce Offspring")
if(locate(/datum/action/cooldown/borer/produce_offspring) in cortical_owner.known_abilities)
abil_list.Remove("Produce Offspring")
if("Learn Chemical from Blood")
if(locate(/datum/action/cooldown/borer/learn_bloodchemical) in cortical_owner.known_abilities)
abil_list.Remove("Learn Chemical from Blood")
if("Revive Host")
if(locate(/datum/action/cooldown/borer/revive_host) in cortical_owner.known_abilities)
abil_list.Remove("Revive Host")
if("Willing Host")
if(locate(/datum/action/cooldown/borer/willing_host) in cortical_owner.known_abilities)
abil_list.Remove("Willing Host")
if("Upgrade Injection")
if(length(cortical_owner.injection_rates_unlocked) >= length(cortical_owner.injection_rates))
abil_list.Remove("Upgrade Injection")
if(!length(abil_list))
owner.balloon_alert(owner, "all abilites learned")
cortical_owner.stat_evolution += 2
return
var/ability_choice = tgui_input_list(cortical_owner, "Choose your ability!", "Ability Choice", abil_list)
if(!ability_choice)
owner.balloon_alert(owner, "ability not selected")
cortical_owner.stat_evolution += 2
return
owner.balloon_alert(owner, "ability learned")
switch(ability_choice)
if("Produce Offspring")
var/datum/action/attack_action = new /datum/action/cooldown/borer/produce_offspring()
attack_action.Grant(cortical_owner)
cortical_owner.known_abilities += /datum/action/cooldown/borer/produce_offspring
return
if("Learn Chemical from Blood")
var/datum/action/attack_action = new /datum/action/cooldown/borer/learn_bloodchemical()
attack_action.Grant(cortical_owner)
cortical_owner.known_abilities += /datum/action/cooldown/borer/learn_bloodchemical
return
if("Revive Host")
var/datum/action/attack_action = new /datum/action/cooldown/borer/revive_host()
attack_action.Grant(cortical_owner)
cortical_owner.known_abilities += /datum/action/cooldown/borer/revive_host
return
if("Willing Host")
var/datum/action/attack_action = new /datum/action/cooldown/borer/willing_host()
attack_action.Grant(cortical_owner)
cortical_owner.known_abilities += /datum/action/cooldown/borer/willing_host
return
if("Upgrade Injection")
if(length(cortical_owner.injection_rates_unlocked) >= length(cortical_owner.injection_rates)) // Extra insurance
owner.balloon_alert(owner, "injection already maximized")
return
cortical_owner.injection_rates_unlocked += cortical_owner.injection_rates[length(cortical_owner.injection_rates_unlocked) + 1]
StartCooldown()
//to ask if a host is willing
/datum/action/cooldown/borer/willing_host
name = "Willing Host (150 chemicals)"
@@ -702,5 +747,67 @@
GLOB.willing_hosts += cortical_owner.human_host.ckey
StartCooldown()
/datum/action/cooldown/borer/stealth_mode
name = "Stealth Mode (100 chemicals)"
cooldown_time = 2 MINUTES
button_icon_state = "willing"
/datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags)
. = ..()
if(!.)
return FALSE
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
if(cortical_owner.host_sugar())
owner.balloon_alert(owner, "cannot function with sugar in host")
return
if(cortical_owner.chemical_storage < 100)
owner.balloon_alert(owner, "100 chemical points required")
return
var/in_stealth = (cortical_owner.upgrade_flags & BORER_STEALTH_MODE)
owner.balloon_alert(owner, "stealth mode [in_stealth ? "disabled" : "enabled"]")
if(in_stealth)
cortical_owner.upgrade_flags &= ~BORER_STEALTH_MODE
else
cortical_owner.upgrade_flags |= BORER_STEALTH_MODE
StartCooldown()
/datum/action/cooldown/borer/empowered_offspring
name = "Produce Empowered Offspring (150 chemicals)"
cooldown_time = 1 MINUTES
button_icon_state = "reproduce"
/datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags)
. = ..()
if(!.)
return FALSE
var/mob/living/simple_animal/cortical_borer/cortical_owner = owner
if(!cortical_owner.inside_human())
owner.balloon_alert(owner, "host required")
return
if(cortical_owner.stat != DEAD)
owner.balloon_alert(owner, "host not dead")
return
if(cortical_owner.chemical_storage < 150)
owner.balloon_alert(owner, "150 chemical points required")
return
cortical_owner.chemical_storage -= 150
var/turf/borer_turf = get_turf(cortical_owner)
var/obj/item/bodypart/chest/chest = cortical_owner.get_bodypart(BODY_ZONE_CHEST)
if((!chest || IS_ORGANIC_LIMB(chest)) && !cortical_owner.getorgan(/obj/item/organ/internal/empowered_borer_egg))
var/obj/item/organ/internal/empowered_borer_egg/spawned_egg = new(cortical_owner)
spawned_egg.generation = (cortical_owner.generation + 1)
cortical_owner.children_produced++
if(cortical_owner.children_produced == GLOB.objective_egg_egg_number)
GLOB.successful_egg_number += 1
playsound(borer_turf, 'sound/effects/splat.ogg', 50, TRUE)
var/logging_text = "[key_name(cortical_owner)] gave birth to an empowered borer at [loc_name(borer_turf)]"
cortical_owner.log_message(logging_text, LOG_GAME)
owner.balloon_alert(owner, "egg laid")
StartCooldown()
#undef CHEMICALS_PER_UNIT
#undef CHEMICAL_SECOND_DIVISOR
#undef OUT_OF_HOST_EGG_COST
@@ -22,7 +22,7 @@
///what the generation of the borer egg is
var/generation = 1
///the egg that is attached to this mob spawn
var/obj/item/borer_egg/host_egg
var/obj/item/borer_egg/host_egg = /obj/item/borer_egg
/obj/effect/mob_spawn/ghost_role/borer_egg/Destroy()
host_egg = null
@@ -36,7 +36,7 @@
/obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team)
. = ..()
host_egg = new /obj/item/borer_egg(get_turf(src))
host_egg = new host_egg(get_turf(src))
host_egg.host_spawner = src
forceMove(host_egg)
var/area/src_area = get_area(src)
@@ -73,6 +73,10 @@
QDEL_NULL(host_spawner)
qdel(src)
/obj/item/borer_egg/empowered
name = "empowered borer egg"
icon_state = "empowered_brainegg"
/datum/uplink_item/dangerous/cortical_borer
name = "Cortical Borer Egg"
desc = "The egg of a cortical borer. The cortical borer is a parasite that can produce chemicals upon command, as well as \
@@ -88,3 +92,9 @@
/obj/effect/mob_spawn/ghost_role/borer_egg/opfor
prompt_name = "cortical borer (OPFOR spawned)"
/obj/effect/mob_spawn/ghost_role/borer_egg/empowered
name = "empowered borer egg"
desc = "An egg of a creature that came crawling out of someone instead of into them."
mob_type = /mob/living/simple_animal/cortical_borer/empowered
host_egg = /obj/item/borer_egg/empowered
@@ -0,0 +1,18 @@
/mob/living/simple_animal/cortical_borer/proc/get_possible_evolutions()
var/list/possible_evolutions = list()
for(var/evolution_index in past_evolutions)
var/datum/borer_evolution/evolution = past_evolutions[evolution_index]
possible_evolutions |= evolution.unlocked_evolutions
return possible_evolutions
/mob/living/simple_animal/cortical_borer/proc/do_evolution(datum/borer_evolution/evolution_type)
if(!ispath(evolution_type))
stack_trace("[type] do_evolution was given an invalid path! (Got: [evolution_type])")
return FALSE
if(past_evolutions[evolution_type])
return FALSE
var/datum/borer_evolution/initialized_evolution = new evolution_type()
past_evolutions[evolution_type] = initialized_evolution
initialized_evolution.on_evolve(src)
return TRUE
@@ -0,0 +1,39 @@
/datum/borer_evolution
/// Name of the evolution
var/name = ""
/// Description of the evolution
var/desc = ""
/// Cost to get the evolution
var/evo_cost = 2 // T5 cost 3 points instead of 2
/// Text to show the borer when they evolve
var/gain_text = ""
/// What evolution genome this is
var/evo_type = BORER_EVOLUTION_GENERAL
/// If TRUE, this is an evolution that locks out other evolutions of the same tier & above but in different genomes
var/mutually_exclusive = FALSE
/// What evolutions this one unlocks
var/list/unlocked_evolutions = list()
/// What numerical tier is this? (Doesn't affect anything mechanically)
var/tier = 0
/// What happens when a borer gets this evolution
/datum/borer_evolution/proc/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
SHOULD_CALL_PARENT(TRUE)
if(gain_text)
to_chat(cortical_owner, span_notice(span_italics(gain_text)))
if(mutually_exclusive)
cortical_owner.genome_locked = TRUE
/datum/borer_evolution/base
name = "The Beginning"
desc = "The start of a great age."
gain_text = "The worms, which we came to call \"Cortical Borers\", are fascinating creatures."
evo_cost = 0
evo_type = BORER_EVOLUTION_START
tier = 0
unlocked_evolutions = list(
/datum/borer_evolution/upgrade_injection,
/datum/borer_evolution/symbiote/willing_host,
/datum/borer_evolution/hivelord/produce_offspring,
/datum/borer_evolution/diveworm/health_per_level,
)
@@ -0,0 +1,108 @@
/datum/borer_evolution/diveworm
evo_type = BORER_EVOLUTION_DIVEWORM
// T1
/datum/borer_evolution/diveworm/health_per_level
name = "Health Increase"
desc = "Increase the amount of health per level-up you gain."
gain_text = "Over time, some of the more aggressive worms became harder to dissect post-mortem. Their skin membrane has become up to thrice as thick."
tier = 1
unlocked_evolutions = list(/datum/borer_evolution/diveworm/host_speed)
/datum/borer_evolution/diveworm/health_per_level/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.health_per_level += 2.5
cortical_owner.recalculate_stats()
// T2
/datum/borer_evolution/diveworm/host_speed
name = "Boring Speed"
desc = "Decrease the time it takes to enter a host when you are not hiding."
gain_text = "Once or twice, I would blink, and see the non-host monkeys be grappling with a worm that was cross the room just moments before."
tier = 2
unlocked_evolutions = list(/datum/borer_evolution/diveworm/expanded_chemicals)
/datum/borer_evolution/diveworm/host_speed/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.upgrade_flags |= BORER_FAST_BORING
// T3 + T1 path
/datum/borer_evolution/diveworm/expanded_chemicals
name = "Expanded Chemical List"
desc = "Gain access to a new list of devious chemicals to the unlockable list."
gain_text = "Sometimes, I would just see a known host monkey... collapse, then get up, then collapse again. It was as if the worm was playing with it..."
mutually_exclusive = TRUE
tier = 3
unlocked_evolutions = list(
/datum/borer_evolution/diveworm/harm_increase,
/datum/borer_evolution/diveworm/health_per_level/t2,
)
var/static/list/added_chemicals = list(
/datum/reagent/toxin/fentanyl,
/datum/reagent/toxin/staminatoxin,
/datum/reagent/toxin/mutetoxin,
/datum/reagent/toxin/mutagen,
/datum/reagent/toxin/cyanide,
/datum/reagent/drug/opium,
/datum/reagent/drug/mushroomhallucinogen,
/datum/reagent/inverse/oculine,
)
/datum/borer_evolution/diveworm/expanded_chemicals/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.potential_chemicals |= added_chemicals
/datum/borer_evolution/diveworm/health_per_level/t2
name = "Health Increase II"
tier = -1
unlocked_evolutions = list(/datum/borer_evolution/diveworm/health_per_level/t3)
/datum/borer_evolution/diveworm/health_per_level/t3
name = "Health Increase III"
tier = -1
unlocked_evolutions = list()
// T4 + its path
/datum/borer_evolution/diveworm/harm_increase
name = "Toxins Increase"
desc = "Increase the passive and active damage you do to your host, and how often it occurs."
gain_text = "In captivity, some of the worms became more... brutish, larger. Most notably, hosts succumbed much quicker to them."
tier = 4
unlocked_evolutions = list(
/datum/borer_evolution/diveworm/harm_increase/t2,
/datum/borer_evolution/diveworm/empowered_offspring,
)
/datum/borer_evolution/diveworm/harm_increase/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.host_harm_multiplier += 0.25
/datum/borer_evolution/diveworm/harm_increase/t2
name = "Toxins Increase II"
desc = "Further increase the passive and active damage you do to your host, and how often it occurs."
tier = -1
unlocked_evolutions = list(/datum/borer_evolution/diveworm/harm_increase/t3)
/datum/borer_evolution/diveworm/harm_increase/t3
name = "Toxins Increase III"
desc = "Further increase the passive and active damage you do to your host, and how often it occurs."
tier = -1
unlocked_evolutions = list()
// T5
/datum/borer_evolution/diveworm/empowered_offspring
name = "Empowered Offspring"
desc = "Lay an egg in a deceased host, and after a delay an empowered borer will burst out."
gain_text = "Most eggs would be regurgitated through the throat from their hosts... but one did not. They exploded out the chest like a horror movie. What a worrying discovery."
evo_cost = 3
tier = 5
unlocked_evolutions = list(
/datum/borer_evolution/sugar_immunity,
/datum/borer_evolution/synthetic_borer,
/datum/borer_evolution/synthetic_chems_negative,
)
/datum/borer_evolution/diveworm/empowered_offspring/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
var/datum/action/cooldown/borer/learn_bloodchemical/attack_action = new()
attack_action.Grant(cortical_owner)
@@ -0,0 +1,82 @@
/datum/borer_evolution/upgrade_injection
name = "Upgrade Injection"
desc = "Upgrade your possible injection amount to 10 units."
gain_text = "Their growth is astounding, their organs and glands can expand several times their size in mere days."
unlocked_evolutions = list(/datum/borer_evolution/upgrade_injection/t2)
tier = 1
/datum/borer_evolution/upgrade_injection/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.injection_rates_unlocked += cortical_owner.injection_rates[length(cortical_owner.injection_rates_unlocked) + 1]
/datum/borer_evolution/upgrade_injection/t2
name = "Upgrade Injection II"
desc = "Upgrade your possible injection amount to 25 units."
unlocked_evolutions = list(/datum/borer_evolution/upgrade_injection/t3)
tier = 2
/datum/borer_evolution/upgrade_injection/t3
name = "Upgrade Injection III"
desc = "Upgrade your possible injection amount to 50 units."
unlocked_evolutions = list()
tier = 3
/datum/borer_evolution/sugar_immunity
name = "Sugar Immunity"
desc = "Become immune to the ill effects of sugar in you or a host."
gain_text = "Of the biggest ones, a few have managed to resist the effects of sugar. Truly concerning if we wish to keep them contained."
evo_cost = 5
tier = 6
/datum/borer_evolution/sugar_immunity/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.upgrade_flags |= BORER_SUGAR_IMMUNE
/datum/borer_evolution/synthetic_borer
name = "Synthetic Boring"
desc = "Gain the ability to take synthetic humans as a host as well."
gain_text = "Now, we used robots to take care of the worms when they're alive, but one day... they all went haywire. Security took them down, closer inspection showed that the worms managed their way into the processing units."
evo_cost = 6
tier = 6
/datum/borer_evolution/synthetic_borer/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.organic_restricted = FALSE
/datum/borer_evolution/synthetic_chems_positive
name = "Synthetic Chemicals (+)"
desc = "Gain access to a list of helpful, synthetic-compatible chemicals."
gain_text = "Once we had established that robots weren't safe either, we began to experiment with them. Interestingly enough, some of them never needed to be oiled again."
tier = 6
evo_cost = 6
var/static/list/added_chemicals = list(
/datum/reagent/consumable/ethanol/synthanol,
/datum/reagent/medicine/system_cleaner,
/datum/reagent/medicine/nanite_slurry,
/datum/reagent/medicine/liquid_solder,
/datum/reagent/oil,
/datum/reagent/fuel,
)
/datum/borer_evolution/synthetic_chems_positive/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.potential_chemicals |= added_chemicals
/datum/borer_evolution/synthetic_chems_negative
name = "Synthetic Chemicals (-)"
desc = "Gain access to a list of synthetic-damaging chemicals."
gain_text = "Good thing is, some of the worms were hostile to the robots, too. Corroded from the inside, some of them were basically husks."
tier = 6
evo_cost = 6
var/static/list/added_chemicals = list(
/datum/reagent/toxin/acid/fluacid, // More like anti everything but :shrug:
/datum/reagent/toxin/plasma,
/datum/reagent/teslium,
/datum/reagent/thermite,
/datum/reagent/pyrosium,
/datum/reagent/oxygen,
)
/datum/borer_evolution/synthetic_chems_negative/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.potential_chemicals |= added_chemicals
@@ -0,0 +1,72 @@
/datum/borer_evolution/hivelord
evo_type = BORER_EVOLUTION_HIVELORD
// T1
/datum/borer_evolution/hivelord/produce_offspring
name = "Produce Offspring"
desc = "Produce an egg, which your host will vomit up."
gain_text = "The way that a Cortical Borer produces an egg is a strange one. So far, we have not seen how it produces one, or it doing so outside a host."
tier = 1
unlocked_evolutions = list(/datum/borer_evolution/hivelord/blood_chemical)
/datum/borer_evolution/hivelord/produce_offspring/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
var/datum/action/cooldown/borer/produce_offspring/attack_action = new()
attack_action.Grant(cortical_owner)
// T2
/datum/borer_evolution/hivelord/blood_chemical
name = "Learn Blood Chemical"
desc = "Learn a synthesizable chemical from the blood of your host."
gain_text = "As we were dissecting a former host monkey's fecal matter, I noticed a high concentration of banana matter, despite us not feeding them any for the past week."
tier = 2
unlocked_evolutions = list(/datum/borer_evolution/hivelord/movespeed)
/datum/borer_evolution/hivelord/blood_chemical/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
var/datum/action/cooldown/borer/learn_bloodchemical/attack_action = new()
attack_action.Grant(cortical_owner)
// T3
/datum/borer_evolution/hivelord/movespeed
name = "Increased Energy"
desc = "Boost your speed by a large amount."
gain_text = "And as I watched, the Cortical Borer was able to complete the course in just over half the time it had last week."
mutually_exclusive = TRUE
tier = 3
unlocked_evolutions = list(/datum/borer_evolution/hivelord/stealth_mode)
/datum/borer_evolution/hivelord/movespeed/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.add_movespeed_modifier(/datum/movespeed_modifier/borer_speed)
// T4
/datum/borer_evolution/hivelord/stealth_mode
name = "Stealth Mode"
desc = "While in stealth mode, your presence is much less noticable in hosts, but you do not gain passive benefits."
gain_text = "As I was writing my report one day, I noticed that one of the worms had slipped out of its cage and into a monkey without so much as a sound. Fascinating how they seem to know the importance of sound."
tier = 4
unlocked_evolutions = list(/datum/borer_evolution/hivelord/produce_offspring_alone)
/datum/borer_evolution/hivelord/stealth_mode/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
var/datum/action/cooldown/borer/stealth_mode/attack_action = new()
attack_action.Grant(cortical_owner)
// T5
/datum/borer_evolution/hivelord/produce_offspring_alone
name = "Produce Offspring II"
desc = "Allows you to produce eggs outside a host, in exchange for health and chemicals."
gain_text = "One of the worms seems to have taken an... Alpha position in the hive, producing more eggs than the others. Most worryingly, eggs have shown up without them having a host, but I haven't *seen* them lay any..."
evo_cost = 3
tier = 5
unlocked_evolutions = list(
/datum/borer_evolution/sugar_immunity,
/datum/borer_evolution/synthetic_borer,
/datum/borer_evolution/synthetic_chems_positive,
/datum/borer_evolution/synthetic_chems_negative,
)
/datum/borer_evolution/hivelord/produce_offspring_alone/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.upgrade_flags |= BORER_ALONE_PRODUCTION
@@ -0,0 +1,111 @@
/datum/borer_evolution/symbiote
evo_type = BORER_EVOLUTION_SYMBIOTE
// T1
/datum/borer_evolution/symbiote/willing_host
name = "Willing Host"
desc = "Ask a host if they are willing, furthering your objectives."
gain_text = "Some of the monkeys we gave the worms seemed far more... willing than others to be a host. I could've sworn one let them climb up their arm."
tier = 1
unlocked_evolutions = list(/datum/borer_evolution/symbiote/chem_per_level)
/datum/borer_evolution/symbiote/willing_host/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
var/datum/action/cooldown/borer/willing_host/attack_action = new()
attack_action.Grant(cortical_owner)
// T2
/datum/borer_evolution/symbiote/chem_per_level
name = "Chemical Increase"
desc = "Increase the amount of chemicals per level-up you gain."
gain_text = "The rate of which we've had to clean the borer pens is increasing. Perhaps their secretions are excess chemicals they cannot use?"
tier = 2
unlocked_evolutions = list(/datum/borer_evolution/symbiote/expanded_chemicals)
/datum/borer_evolution/symbiote/chem_per_level/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.chem_storage_per_level += 10
cortical_owner.chem_regen_per_level += 0.5
cortical_owner.recalculate_stats()
// T3 + T2 Path
/datum/borer_evolution/symbiote/expanded_chemicals
name = "Expanded Chemical List"
desc = "Gain access to a new list of helpful chemicals to the unlockable list."
gain_text = "The chemicals the worms seem capable of synthesizing are truly remarkable, their hosts are able to get up from amazing amounts of harm."
mutually_exclusive = TRUE
tier = 3
unlocked_evolutions = list(
/datum/borer_evolution/symbiote/harm_decrease,
/datum/borer_evolution/symbiote/chem_per_level/t2,
)
var/static/list/added_chemicals = list(
/datum/reagent/medicine/sal_acid,
/datum/reagent/medicine/oxandrolone,
/datum/reagent/medicine/atropine,
/datum/reagent/medicine/neurine,
/datum/reagent/medicine/leporazine,
/datum/reagent/medicine/omnizine,
)
/datum/borer_evolution/symbiote/expanded_chemicals/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.potential_chemicals |= added_chemicals
/datum/borer_evolution/symbiote/chem_per_level/t2
name = "Chemical Increase II"
desc = "Increase the amount of chemicals per level-up you gain even further."
tier = -1
unlocked_evolutions = list(/datum/borer_evolution/symbiote/chem_per_level/t3)
/datum/borer_evolution/symbiote/chem_per_level/t3
name = "Chemical Increase III"
desc = "Increase the amount of chemicals per level-up you gain even further."
tier = -1
unlocked_evolutions = list()
// T4 and path
/datum/borer_evolution/symbiote/harm_decrease
name = "Toxins Decrease"
desc = "Decrease the passive and active damage you do to your host, and how often it occurs."
gain_text = "However, some of the others became... if not smaller, certainly longer, more lithe."
tier = 4
unlocked_evolutions = list(
/datum/borer_evolution/symbiote/harm_decrease/t2,
/datum/borer_evolution/symbiote/revive_host,
)
/datum/borer_evolution/symbiote/harm_decrease/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
cortical_owner.host_harm_multiplier -= 0.25
/datum/borer_evolution/symbiote/harm_decrease/t2
name = "Toxins Decrease II"
desc = "Further decrease the passive and active damage you do to your host, and how often it occurs."
tier = -1
unlocked_evolutions = list(/datum/borer_evolution/symbiote/harm_decrease/t3)
/datum/borer_evolution/symbiote/harm_decrease/t3
name = "Toxins Decrease III"
desc = "Further decrease the passive and active damage you do to your host, and how often it occurs."
tier = -1
unlocked_evolutions = list()
// T5
/datum/borer_evolution/symbiote/revive_host
name = "Revive Host"
desc = "Revive your host and heal what ails them."
gain_text = "As I was in the lab, the most curious occurance so far happened. A Cortical Borer went into one of the cadaver's heads, and moments later they were standing again."
evo_cost = 3
tier = 5
unlocked_evolutions = list(
/datum/borer_evolution/sugar_immunity,
/datum/borer_evolution/synthetic_borer,
/datum/borer_evolution/synthetic_chems_positive,
)
/datum/borer_evolution/symbiote/revive_host/on_evolve(mob/living/simple_animal/cortical_borer/cortical_owner)
. = ..()
var/datum/action/cooldown/borer/revive_host/attack_action = new()
attack_action.Grant(cortical_owner)
@@ -0,0 +1,52 @@
/obj/item/organ/internal/empowered_borer_egg
name = "strange egg"
desc = "All slimy and yuck."
icon_state = "innards" // not like you'll be seeing this anyway
visual = TRUE
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_PARASITE_EGG
/// How long it takes to burst from a corpse
var/burst_time = 3 MINUTES
/// What generation the egg will be
var/generation = 1
/obj/item/organ/internal/empowered_borer_egg/on_find(mob/living/finder)
..()
to_chat(finder, span_warning("You found an unknown egg in [owner]'s [zone]!"))
/obj/item/organ/internal/empowered_borer_egg/Initialize(mapload)
. = ..()
if(iscarbon(loc))
Insert(loc)
/obj/item/organ/internal/empowered_borer_egg/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
..()
addtimer(CALLBACK(src, .proc/try_burst), burst_time)
/obj/item/organ/internal/empowered_borer_egg/Remove(mob/living/carbon/M, special = FALSE)
. = ..()
visible_message(span_warning(span_italics("As [src] is cut out of [M], it quickly vibrates and shatters, leaving nothing but some goop!")))
new/obj/effect/decal/cleanable/food/egg_smudge(get_turf(src))
qdel(src)
/obj/item/organ/internal/empowered_borer_egg/proc/try_burst()
if(!owner)
qdel(src)
return
if(owner.stat != DEAD)
qdel(src)
return
var/list/candidates = poll_ghost_candidates("Do you want to spawn as an empowered Cortical Borer bursting from [owner]?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER)
if(!length(candidates))
var/obj/effect/mob_spawn/ghost_role/borer_egg/empowered/borer_egg = new(get_turf(owner))
borer_egg.generation = generation
var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST)
chest.dismember()
return
var/mob/dead/observer/new_borer = pick(candidates)
var/mob/living/simple_animal/cortical_borer/empowered/spawned_cb = new(get_turf(owner))
var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST)
chest.dismember()
spawned_cb.generation = generation
spawned_cb.ckey = new_borer.ckey
spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer)
@@ -54,7 +54,7 @@
/datum/borer_focus/arms/on_add(mob/living/carbon/human/host, mob/living/simple_animal/cortical_borer/borer)
to_chat(host, span_notice("Your arms start to feel funny..."))
borer.human_host.add_actionspeed_modifier(/datum/actionspeed_modifier/borer_speed)
borer.human_host.add_actionspeed_modifier(/datum/actionspeed_modifier/focus_speed)
return ..()
/datum/borer_focus/arms/on_remove(mob/living/carbon/human/host, mob/living/simple_animal/cortical_borer/borer)
@@ -68,10 +68,10 @@
/datum/borer_focus/legs/on_add(mob/living/carbon/human/host, mob/living/simple_animal/cortical_borer/borer)
to_chat(host, span_notice("You feel faster..."))
host.add_movespeed_modifier(/datum/movespeed_modifier/borer_speed)
host.add_movespeed_modifier(/datum/movespeed_modifier/focus_speed)
return ..()
/datum/borer_focus/legs/on_remove(mob/living/carbon/human/host, mob/living/simple_animal/cortical_borer/borer)
to_chat(host, span_notice("You feel slower..."))
host.remove_movespeed_modifier(/datum/movespeed_modifier/borer_speed)
host.remove_movespeed_modifier(/datum/movespeed_modifier/focus_speed)
return ..()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

+7
View File
@@ -5333,6 +5333,13 @@
#include "modular_skyrat\modules\cortical_borer\code\cortical_borer_items.dm"
#include "modular_skyrat\modules\cortical_borer\code\focus_datum.dm"
#include "modular_skyrat\modules\cortical_borer\code\status_effects.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\borer_evolution.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\evolution_datum.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\evolution_diveworm.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\evolution_general.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\evolution_hivelord.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\evolution_symbiote.dm"
#include "modular_skyrat\modules\cortical_borer\code\evolution\evolution_things\empowered_egg.dm"
#include "modular_skyrat\modules\crafting\crafting_skyrat.dm"
#include "modular_skyrat\modules\cryosleep\code\admin.dm"
#include "modular_skyrat\modules\cryosleep\code\ai.dm"
@@ -0,0 +1,140 @@
import { useBackend } from '../backend';
import { Section, Stack, Button, BlockQuote } from '../components';
import { Window } from '../layouts';
const borerColor = {
fontWeight: 'bold',
color: '#b2c96b',
};
type Evolution = {
path: string;
name: string;
desc: string;
gainFlavor: string;
cost: number;
disabled: boolean;
evoPath: string;
color: string;
tier: number;
exclusive: boolean;
};
type EvolutionInfo = {
learnableEvolution: Evolution[];
learnedEvolution: Evolution[];
};
type Info = {
evolution_points: number;
};
export const BorerEvolution = (props, context) => {
return (
<Window width={675} height={600} theme="wizard" title="Evolution Tree">
<Window.Content>
<Stack vertical fill>
<Stack.Item grow>
<EvoInfo />
</Stack.Item>
</Stack>
</Window.Content>
</Window>
);
};
const PastEvolutions = (props, context) => {
const { data } = useBackend<EvolutionInfo>(context);
const { learnedEvolution } = data;
return (
<Stack.Item grow>
<Section title="Past Evolutions" fill scrollable>
<Stack vertical>
{(!learnedEvolution.length && 'None!') ||
learnedEvolution.map((learned) => (
<Stack.Item key={learned.name}>
<Button
width="100%"
color={learned.color}
content={`${learned.evoPath} - ${
learned.tier !== -1 ? `T${learned.tier} -` : ``
} ${learned.name}`}
tooltip={learned.desc}
/>
</Stack.Item>
))}
</Stack>
</Section>
</Stack.Item>
);
};
const EvolutionList = (props, context) => {
const { data, act } = useBackend<EvolutionInfo>(context);
const { learnableEvolution } = data;
return (
<Stack.Item grow>
<Section title="Possible Evolutions" fill scrollable>
{(!learnableEvolution.length && 'None!') ||
learnableEvolution.map((toLearn) => (
<Stack.Item key={toLearn.name} mb={1}>
<Button
width="100%"
color={toLearn.color}
disabled={toLearn.disabled}
content={`${toLearn.evoPath} - ${
toLearn.tier !== -1 ? `T${toLearn.tier} -` : ``
} ${
toLearn.cost > 0
? `${toLearn.name}: ${toLearn.cost}
point${toLearn.cost !== 1 ? 's' : ''}`
: toLearn.name
}`}
tooltip={
toLearn.exclusive
? toLearn.desc +
` By taking this, you cannot take other T3+ gneomes.`
: toLearn.desc
}
onClick={() => act('evolve', { path: toLearn.path })}
/>
{!!toLearn.gainFlavor && (
<BlockQuote>
<i>{toLearn.gainFlavor}</i>
</BlockQuote>
)}
</Stack.Item>
))}
</Section>
</Stack.Item>
);
};
const EvoInfo = (props, context) => {
const { data } = useBackend<Info>(context);
const { evolution_points } = data;
return (
<Stack justify="space-evenly" height="100%" width="100%">
<Stack.Item grow>
<Stack vertical height="100%">
<Stack.Item fontSize="20px" textAlign="center">
You have <b>{evolution_points || 0}</b>&nbsp;
<span style={borerColor}>
evolution point{evolution_points !== 1 ? 's' : ''}
</span>{' '}
to spend.
</Stack.Item>
<Stack.Item grow>
<Stack height="100%">
<PastEvolutions />
<EvolutionList />
</Stack>
</Stack.Item>
</Stack>
</Stack.Item>
</Stack>
);
};