From 730f9d9d26476481cf87b768e0fab6c0a4aa1853 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:01:31 +0100 Subject: [PATCH 01/67] broken initial commit --- code/__DEFINES/role_preferences.dm | 1 + .../~monkestation/actionspeed_modification.dm | 1 + code/__DEFINES/~monkestation/antagonists.dm | 22 + code/__DEFINES/~monkestation/is_helpers.dm | 1 + .../~monkestation/role_preferences.dm | 1 + .../~monkestation-helpers/logging.dm | 4 + code/_globalvars/lists/poll_ignore.dm | 2 + code/datums/mutations/_mutations.dm | 5 + code/modules/admin/sql_ban_system.dm | 1 + .../antagonists/changeling/powers/panacea.dm | 6 + .../antagonists/borers/code/cortical_borer.dm | 474 ++++++++++ .../borers/code/cortical_borer_abilities.dm | 829 ++++++++++++++++++ .../borers/code/cortical_borer_antagonist.dm | 188 ++++ .../borers/code/cortical_borer_chems.dm | 19 + .../borers/code/cortical_borer_egg.dm | 96 ++ .../borers/code/cortical_borer_items.dm | 103 +++ .../borers/code/evolution/borer_evolution.dm | 17 + .../borers/code/evolution/evolution_datum.dm | 39 + .../code/evolution/evolution_diveworm.dm | 111 +++ .../code/evolution/evolution_general.dm | 80 ++ .../code/evolution/evolution_hivelord.dm | 73 ++ .../code/evolution/evolution_symbiote.dm | 111 +++ .../evolution_things/empowered_egg.dm | 54 ++ .../antagonists/borers/code/focus_datum.dm | 77 ++ .../antagonists/borers/code/status_effects.dm | 11 + .../antagonists/borers/icons/actions.dmi | Bin 0 -> 6184 bytes .../antagonists/borers/icons/animal.dmi | Bin 0 -> 2000 bytes .../modules/antagonists/borers/icons/hud.dmi | Bin 0 -> 277 bytes .../antagonists/borers/icons/items.dmi | Bin 0 -> 1007 bytes .../code/modules/antagonists/borers/readme.md | 24 + tgstation.dme | 19 + tgui/packages/tgui/interfaces/BorerChem.jsx | 59 ++ .../tgui/interfaces/BorerEvolution.tsx | 142 +++ 33 files changed, 2570 insertions(+) create mode 100644 code/__DEFINES/~monkestation/actionspeed_modification.dm create mode 100644 code/__DEFINES/~monkestation/is_helpers.dm create mode 100644 code/__DEFINES/~monkestation/role_preferences.dm create mode 100644 code/__HELPERS/~monkestation-helpers/logging.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/borer_evolution.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/focus_datum.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/status_effects.dm create mode 100644 monkestation/code/modules/antagonists/borers/icons/actions.dmi create mode 100644 monkestation/code/modules/antagonists/borers/icons/animal.dmi create mode 100644 monkestation/code/modules/antagonists/borers/icons/hud.dmi create mode 100644 monkestation/code/modules/antagonists/borers/icons/items.dmi create mode 100644 monkestation/code/modules/antagonists/borers/readme.md create mode 100644 tgui/packages/tgui/interfaces/BorerChem.jsx create mode 100644 tgui/packages/tgui/interfaces/BorerEvolution.tsx diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 64a4ccdc0772..d286b170bf05 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -153,6 +153,7 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_DRIFTING_CONTRACTOR = 0, ROLE_VAMPIRICACCIDENT = 0, ROLE_MONSTERHUNTER = 0, + ROLE_BORER = 0, // Module ID: CORTICAL_BORERS //monkestation edit end // Latejoin diff --git a/code/__DEFINES/~monkestation/actionspeed_modification.dm b/code/__DEFINES/~monkestation/actionspeed_modification.dm new file mode 100644 index 000000000000..1d7c683c7e6d --- /dev/null +++ b/code/__DEFINES/~monkestation/actionspeed_modification.dm @@ -0,0 +1 @@ +#define ACTIONSPEED_ID_BORER "borer" diff --git a/code/__DEFINES/~monkestation/antagonists.dm b/code/__DEFINES/~monkestation/antagonists.dm index 8ec0def3b22b..6228d16e5bd1 100644 --- a/code/__DEFINES/~monkestation/antagonists.dm +++ b/code/__DEFINES/~monkestation/antagonists.dm @@ -17,3 +17,25 @@ #define iscogscarab(checked) (istype(checked, /mob/living/basic/drone/cogscarab)) /// is something an eminence #define iseminence(checked) (istype(checked, /mob/living/eminence)) + +// 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) diff --git a/code/__DEFINES/~monkestation/is_helpers.dm b/code/__DEFINES/~monkestation/is_helpers.dm new file mode 100644 index 000000000000..b4157e80d274 --- /dev/null +++ b/code/__DEFINES/~monkestation/is_helpers.dm @@ -0,0 +1 @@ +#define iscorticalborer(A) (istype(A, /mob/living/basic/cortical_borer)) diff --git a/code/__DEFINES/~monkestation/role_preferences.dm b/code/__DEFINES/~monkestation/role_preferences.dm new file mode 100644 index 000000000000..d2a7dd7dec21 --- /dev/null +++ b/code/__DEFINES/~monkestation/role_preferences.dm @@ -0,0 +1 @@ +#define ROLE_BORER "Borer" diff --git a/code/__HELPERS/~monkestation-helpers/logging.dm b/code/__HELPERS/~monkestation-helpers/logging.dm new file mode 100644 index 000000000000..405d31d65f71 --- /dev/null +++ b/code/__HELPERS/~monkestation-helpers/logging.dm @@ -0,0 +1,4 @@ +/// Logging for borer evolutions +/proc/log_borer_evolution(text) + if (CONFIG_GET(flag/log_uplink)) + WRITE_LOG(GLOB.world_uplink_log, "BORER EVOLUTION: [text]") diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index c3fbb720650f..c9b10eb43d60 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -1,5 +1,6 @@ //Each lists stores ckeys for "Never for this round" option category +#define POLL_IGNORE_CORTICAL_BORER "cortical_borer" // MONKESTATION ADDITION -- CORTICAL_BORERS #define POLL_IGNORE_ACADEMY_WIZARD "academy_wizard" #define POLL_IGNORE_ALIEN_LARVA "alien_larva" #define POLL_IGNORE_ASH_SPIRIT "ash_spirit" @@ -38,6 +39,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( + POLL_IGNORE_CORTICAL_BORER = "Cortical Borer", // MONKESTATION ADDITION -- CORTICAL_BORERS POLL_IGNORE_ACADEMY_WIZARD = "Academy Wizard Defender", POLL_IGNORE_ALIEN_LARVA = "Xenomorph larva", POLL_IGNORE_ASH_SPIRIT = "Ash Spirit", diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 0226326165c8..16fd60905c41 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -90,6 +90,11 @@ /datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/acquirer) if(!acquirer || !istype(acquirer) || acquirer.stat == DEAD || (src in acquirer.dna.mutations)) return TRUE + // MONKESTATION ADDITION START -- CORTICAL_BORERS + if(acquirer.has_borer()) + to_chat(acquirer, span_warning("Something inside holds dearly to your humanity!")) + return TRUE + // MONKESTATION ADDITION END if(species_allowed && !species_allowed.Find(acquirer.dna.species.id)) return TRUE if(health_req && acquirer.health < health_req) diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 06943b4a5c57..d2ad68674bae 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -369,6 +369,7 @@ ROLE_TRAITOR, ROLE_VAMPIRICACCIDENT, ROLE_WIZARD, + ROLE_BORER, // MONKESTATION ADDITION -- CORTICAL_BORERS ), ) for(var/department in long_job_lists) diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm index dff8cd7f7365..fec074885459 100644 --- a/code/modules/antagonists/changeling/powers/panacea.dm +++ b/code/modules/antagonists/changeling/powers/panacea.dm @@ -15,6 +15,7 @@ user.get_organ_by_type(/obj/item/organ/internal/body_egg), user.get_organ_by_type(/obj/item/organ/internal/legion_tumour), user.get_organ_by_type(/obj/item/organ/internal/zombie_infection), + user.get_organ_by_type(/obj/item/organ/internal/empowered_borer_egg), // MONKESTATION ADDITION -- CORTICAL_BORERS ) for(var/o in bad_organs) @@ -28,6 +29,11 @@ C.vomit(0) O.forceMove(get_turf(user)) + // MONKESTATION ADDITION START -- CORTICAL_BORERS + var/mob/living/basic/cortical_borer/brain_pest = user.has_borer() + if(brain_pest) + brain_pest.leave_host() + // MONKESTATION ADDITION END user.reagents.add_reagent(/datum/reagent/medicine/mutadone, 10) user.reagents.add_reagent(/datum/reagent/medicine/pen_acid, 20) user.reagents.add_reagent(/datum/reagent/medicine/antihol, 10) diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm new file mode 100644 index 000000000000..709f49df15dc --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm @@ -0,0 +1,474 @@ +GLOBAL_VAR_INIT(objective_egg_borer_number, 2) +GLOBAL_VAR_INIT(objective_egg_egg_number, 5) +GLOBAL_VAR_INIT(objective_willing_hosts, 2) +GLOBAL_VAR_INIT(objective_blood_chem, 3) +GLOBAL_VAR_INIT(objective_blood_borer, 3) + +GLOBAL_VAR_INIT(successful_egg_number, 0) +GLOBAL_LIST_EMPTY(willing_hosts) +GLOBAL_VAR_INIT(successful_blood_chem, 0) + +GLOBAL_LIST_EMPTY(cortical_borers) + +/// This divisor controls how fast body temperature changes to match the environment +#define BODYTEMP_DIVISOR 16 + +//we need a way of buffing leg speed +/datum/movespeed_modifier/focus_speed + multiplicative_slowdown = -0.4 + +/datum/movespeed_modifier/borer_speed + multiplicative_slowdown = -0.5 + +/datum/actionspeed_modifier/focus_speed + multiplicative_slowdown = -0.3 + id = ACTIONSPEED_ID_BORER + +//so that we know if a mob has a borer (only humans should have one, but in case) +/mob/proc/has_borer() + for(var/check_content in contents) + if(iscorticalborer(check_content)) + return check_content + return FALSE + +//this allows borers to slide under/through a door +/obj/machinery/door/Bumped(atom/movable/movable_atom) + if(iscorticalborer(movable_atom) && density) + if(!do_after(movable_atom, 5 SECONDS, src)) + return ..() + movable_atom.forceMove(get_turf(src)) + to_chat(movable_atom, span_notice("You squeeze through [src].")) + return + return ..() + +//so if a person is debrained, the borer is removed +/obj/item/organ/internal/brain/Remove(mob/living/carbon/target, special = 0, no_id_transfer = FALSE) + . = ..() + var/mob/living/basic/cortical_borer/cb_inside = target.has_borer() + if(cb_inside) + cb_inside.leave_host() + +//borers also create an organ, so you dont need to debrain someone +/obj/item/organ/internal/borer_body + name = "engorged cortical borer" + desc = "the body of a cortical borer, full of human viscera, blood, and more." + zone = BODY_ZONE_HEAD + /// Ref to the borer who this organ belongs to + var/mob/living/basic/cortical_borer/borer + +/obj/item/organ/internal/borer_body/Destroy() + borer = null + return ..() + +/obj/item/organ/internal/borer_body/Insert(mob/living/carbon/carbon_target, special, drop_if_replaced) + . = ..() + for(var/datum/borer_focus/body_focus as anything in borer.body_focuses) + body_focus.on_add() + carbon_target.hal_screwyhud = SCREWYHUD_HEALTHY + +//on removal, force the borer out +/obj/item/organ/internal/borer_body/Remove(mob/living/carbon/carbon_target, special) + . = ..() + var/mob/living/basic/cortical_borer/cb_inside = carbon_target.has_borer() + for(var/datum/borer_focus/body_focus as anything in cb_inside.body_focuses) + body_focus.on_remove() + if(cb_inside) + cb_inside.leave_host() + carbon_target.hal_screwyhud = SCREWYHUD_NONE + qdel(src) + +/obj/item/reagent_containers/borer + volume = 100 + +/mob/living/basic/cortical_borer + name = "cortical borer" + desc = "A slimy creature that is known to go into the ear canal of unsuspecting victims." + icon = 'monkestation/code/modules/antagonists/borers/icons/animal.dmi' + icon_state = "brainslug" + icon_living = "brainslug" + icon_dead = "brainslug_dead" + maxHealth = 25 + health = 25 + //they need to be able to pass tables and mobs + pass_flags = PASSTABLE | PASSMOB + density = FALSE + //they are below mobs, or below tables + layer = BELOW_MOB_LAYER + //corticals are tiny + mob_size = MOB_SIZE_TINY + mob_biotypes = MOB_ORGANIC|MOB_BUG + //because they are small, why can't they be held? + can_be_held = TRUE + ///what chemicals borers know, starting with none + var/list/known_chemicals = list() + ///what chemicals the borer can learn + var/list/potential_chemicals = list(/datum/reagent/medicine/spaceacillin, + /datum/reagent/medicine/potass_iodide, + /datum/reagent/medicine/diphenhydramine, + /datum/reagent/medicine/epinephrine, + /datum/reagent/medicine/haloperidol, + /datum/reagent/toxin/formaldehyde, + /datum/reagent/impurity/libitoil, + /datum/reagent/impurity/mannitol, + /datum/reagent/medicine/c2/libital, + /datum/reagent/medicine/c2/lenturi, + /datum/reagent/medicine/c2/convermol, + /datum/reagent/medicine/c2/seiver, + /datum/reagent/medicine/c2/multiver, + /datum/reagent/lithium, + /datum/reagent/medicine/salglu_solution, + /datum/reagent/medicine/mutadone, + /datum/reagent/toxin/heparin, + /datum/reagent/drug/methamphetamine/borer_version, + /datum/reagent/medicine/morphine, + /datum/reagent/medicine/inacusiate, + /datum/reagent/medicine/oculine, + /datum/reagent/toxin/mindbreaker, + /datum/reagent/medicine/mannitol, + ) + //blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these + var/list/blacklisted_chemicals = list() //currently may be empty, but leaving the mechanism just in case + ///how old the borer is, starting from zero. Goes up only when inside a host + var/maturity_age = 0 + ///the amount of "evolution" points a borer has for chemicals. Start with one + var/chemical_evolution = 1 + ///the amount of "evolution" points a borer has for stats + var/stat_evolution = 0 + ///how many chemical points the borer can have. Can be upgraded + var/max_chemical_storage = 50 + ///how many chemical points the borer has + 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/force_speak, + /datum/action/cooldown/borer/fear_human, + /datum/action/cooldown/borer/check_blood, + ) + ///the host + var/mob/living/carbon/human/human_host + //what the host gains or loses with the borer + var/list/hosts_abilities = list() + //just a little "timer" to compare to world.time + var/timed_maturity = 0 + ///multiplies the current health up to the max health + var/health_regen = 1.02 + //holds the chems right before injection + var/obj/item/reagent_containers/reagent_holder + //just a flavor kind of thing + var/generation = 1 + /// List of focus datums + var/list/possible_focuses = list() + /// What focuses the borer has unlocked + var/list/body_focuses = list() + ///how many children the borer has produced + var/children_produced = 0 + ///how many blood chems have been learned through the blood + var/blood_chems_learned = 0 + ///we dont want to spam the chat + var/deathgasp_once = FALSE + //the limit to the chemical and stat evolution + var/limited_borer = 10 + ///borers can only enter biologicals if true + var/organic_restricted = TRUE + ///borers are unable to enter changelings if true + var/changeling_restricted = TRUE + /// Assoc list of chemical injection rates that the borer can have + var/static/list/injection_rates = list( + 5, + 10, + 25, + 50, + ) + /// Which injection rates the borer has unlocked + var/list/injection_rates_unlocked = list( + 5, + ) + /// What is the current injection rate of the borer + 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/basic/cortical_borer/Initialize(mapload) + . = ..() + AddComponent( \ + /datum/component/squashable, \ + squash_chance = 25, \ + squash_damage = 25, \ + squash_flags = SQUASHED_DONT_SQUASH_IN_CONTENTS, \ + ) + ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) //they need to be able to move around + + var/matrix/borer_matrix = matrix(transform) + borer_matrix.Scale(0.5, 0.5) + transform = borer_matrix + + name = "[initial(name)] ([generation]-[rand(100,999)])" //so their gen and a random. ex 1-288 is first gen named 288, 4-483 if fourth gen named 483 + + GLOB.cortical_borers += src + reagent_holder = new /obj/item/reagent_containers/borer(src) + for(var/action_type in known_abilities) + var/datum/action/attack_action = new action_type() + attack_action.Grant(src) + + if(mind) + if(!mind.has_antag_datum(/datum/antagonist/cortical_borer)) + 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/basic/cortical_borer/Destroy() + human_host = null + GLOB.cortical_borers -= src + QDEL_NULL(reagent_holder) + return ..() + +/mob/living/basic/cortical_borer/death(gibbed) + if(inside_human()) + var/turf/human_turf = get_turf(human_host) + forceMove(human_turf) + human_host = null + GLOB.cortical_borers -= src + if(!deathgasp_once) + deathgasp_once = TRUE + for(var/borers in GLOB.cortical_borers) + to_chat(borers, span_boldwarning("[src] has left the hivemind forcibly!")) + QDEL_NULL(reagent_holder) + return ..() + +//so we can add some stuff to status, making it easier to read... maybe some hud some day +/mob/living/basic/cortical_borer/get_status_tab_items() + . = ..() + . += "Chemical Storage: [chemical_storage]/[max_chemical_storage]" + . += "Chemical Evolution Points: [chemical_evolution]" + . += "Stat Evolution Points: [stat_evolution]" + . += "" + if(host_sugar()) + . += "Sugar detected! Unable to generate resources!" + . += "" + . += "OBJECTIVES:" + . += "1) [GLOB.objective_egg_borer_number] borers producing [GLOB.objective_egg_egg_number] eggs: [GLOB.successful_egg_number]/[GLOB.objective_egg_borer_number]" + . += "2) [GLOB.objective_willing_hosts] willing hosts: [length(GLOB.willing_hosts)]/[GLOB.objective_willing_hosts]" + . += "3) [GLOB.objective_blood_borer] borers learning [GLOB.objective_blood_chem] chemicals from the blood: [GLOB.successful_blood_chem]/[GLOB.objective_blood_borer]" + +/mob/living/basic/cortical_borer/Life(delta_time, times_fired) + . = ..() + //can only do stuff when we are inside a LIVING human + if(!inside_human() || human_host?.stat == DEAD) + return + + //there needs to be a negative to having a borer + 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) + + if(human_host.hal_screwyhud != SCREWYHUD_HEALTHY) + human_host.hal_screwyhud = SCREWYHUD_HEALTHY + + //cant do anything if the host has sugar + if(host_sugar()) + if(!has_status_effect(/datum/status_effect/borer_sugar)) + apply_status_effect(/datum/status_effect/borer_sugar) + else + if(has_status_effect(/datum/status_effect/borer_sugar)) + remove_status_effect(/datum/status_effect/borer_sugar) + + //this is regenerating chemical_storage + if(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) + if(!(upgrade_flags & BORER_STEALTH_MODE)) + health = min(health * health_regen, maxHealth) + + //this is so they can evolve + if(timed_maturity < world.time) + mature() + +//if it doesnt have a ckey, let ghosts have it +/mob/living/basic/cortical_borer/attack_ghost(mob/dead/observer/user) + . = ..() + if(ckey || key) + return + if(stat == DEAD) + return + var/choice = tgui_input_list(usr, "Do you want to control [src]?", "Confirmation", list("Yes", "No")) + if(choice != "Yes") + return + if(ckey || key) + return + to_chat(user, span_warning("As a borer, you have the option to be friendly or not. Note that how you act will determine how a host responds!")) + to_chat(user, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) + ckey = user.ckey + if(mind) + mind.add_antag_datum(/datum/antagonist/cortical_borer) + +//check if we are inside a human +/mob/living/basic/cortical_borer/proc/inside_human() + if(!ishuman(loc)) + return FALSE + return TRUE + +//check if the host has sugar +/mob/living/basic/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 + +// Base mob environment handler for body temperature, overriden to take into consideration being inside a host +/mob/living/basic/cortical_borer/handle_environment(datum/gas_mixture/environment, delta_time, times_fired) + var/loc_temp + if(human_host) + loc_temp = human_host.coretemperature // set the local temp to that of the host's core temp + else + loc_temp = get_temperature(environment) + var/temp_delta = loc_temp - bodytemperature + + if(!human_host && ismovable(loc)) + var/atom/movable/occupied_space = loc + temp_delta *= (1 - occupied_space.contents_thermal_insulation) + + if(temp_delta < 0) // it is cold here + if(!on_fire) // do not reduce body temp when on fire + adjust_bodytemperature(max(max(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_COOLING_MAX) * delta_time, temp_delta)) + else // this is a hot place + adjust_bodytemperature(min(min(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_HEATING_MAX) * delta_time, temp_delta)) + +//leave the host, forced or not +/mob/living/basic/cortical_borer/proc/leave_host() + if(!human_host) + return + var/obj/item/organ/internal/borer_body/borer_organ = locate() in human_host.organs + if(borer_organ) + borer_organ.Remove(human_host) + var/turf/human_turf = get_turf(human_host) + forceMove(human_turf) + human_host = null + +//borers shouldnt be able to whisper... +/mob/living/basic/cortical_borer/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language, ignore_spam = FALSE, forced, filterproof) + to_chat(src, span_warning("You are not able to whisper!")) + return FALSE + +//previously had borers unable to emote... but that means less RP, and we want that + +//borers should not be talking without a host at least +/mob/living/basic/cortical_borer/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null) + if(!inside_human()) + to_chat(src, span_warning("You are not able to speak without a host!")) + return + if(host_sugar()) + message = scramble_message_replace_chars(message, 10) + message = sanitize(message) + var/list/split_message = splittext(message, "") + if(split_message[1] == ";") + message = copytext(message, 2) + for(var/borer in GLOB.cortical_borers) + to_chat(borer, span_purple("Cortical Hivemind: [src] sings, \"[message]\"")) + for(var/mob/dead_mob in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(dead_mob, src) + to_chat(dead_mob, span_purple("[link] Cortical Hivemind: [src] sings, \"[message]\"")) + var/logging_textone = "[key_name(src)] spoke into the hivemind: [message]" + log_say(logging_textone) + return + + //this is when they speak normally + to_chat(human_host, span_purple("Cortical Link: [src] sings, \"[message]\"")) + var/logging_texttwo = "[key_name(src)] spoke to [key_name(human_host)]: [message]" + log_say(logging_texttwo) + to_chat(src, span_purple("Cortical Link: [src] sings, \"[message]\"")) + for(var/mob/dead_mob in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(dead_mob, src) + to_chat(dead_mob, span_purple("[link] Cortical Hivemind: [src] sings to [human_host], \"[message]\"")) + +//borers should not be able to pull anything +/mob/living/basic/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/basic/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/basic/cortical_borer/proc/recalculate_stats() + var/old_health = health + maxHealth = initial(maxHealth) + (level * health_per_level) + health_regen = initial(health_regen) + (level * health_regen_per_level) + max_chemical_storage = initial(max_chemical_storage) + (level * chem_storage_per_level) + chemical_regen = initial(chemical_regen) + (level * chem_regen_per_level) + health = clamp(old_health, 1, maxHealth) + +// Only able to spawn from an egg burst from a corpse, starts off stronger +/mob/living/basic/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 + +#undef BODYTEMP_DIVISOR diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm new file mode 100644 index 000000000000..cdde8d8bdbfd --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm @@ -0,0 +1,829 @@ +#define CHEMICALS_PER_UNIT 2 +#define CHEMICAL_SECOND_DIVISOR (5 SECONDS) +#define OUT_OF_HOST_EGG_COST 50 +#define BLOOD_CHEM_OBJECTIVE 3 + +// Parent of all borer actions +/datum/action/cooldown/borer + button_icon = 'monkestation/code/modules/antagonists/borers/icons/actions.dmi' + cooldown_time = 0 + /// How many chemicals this costs + var/chemical_cost = 0 + /// How many chem evo points are needed to use this ability + var/chemical_evo_points = 0 + /// How many stat evo points are needed to use this ability + var/stat_evo_points = 0 + +/datum/action/cooldown/borer/New(Target, original) + . = ..() + var/compiled_string = "" + if(chemical_cost) + compiled_string += "([chemical_cost] chemical[chemical_cost == 1 ? "" : "s"])" + if(chemical_evo_points) + compiled_string += " ([chemical_evo_points] chemical point[chemical_evo_points == 1 ? "" : "s"])" + if(stat_evo_points) + compiled_string += " ([stat_evo_points] stat point[stat_evo_points == 1 ? "" : "s"])" + name = "[initial(name)][compiled_string]" + +/datum/action/cooldown/borer/Trigger(trigger_flags, atom/target) + . = ..() + if(!iscorticalborer(owner)) + to_chat(owner, span_warning("You must be a cortical borer to use this action!")) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(owner.stat == DEAD) + return FALSE + if(cortical_owner.chemical_storage < chemical_cost) + cortical_owner.balloon_alert(cortical_owner, "need [chemical_cost] chemicals") + return FALSE + if(cortical_owner.chemical_evolution < chemical_evo_points) + cortical_owner.balloon_alert(cortical_owner, "need [chemical_evo_points] chemical points") + return FALSE + if(cortical_owner.stat_evolution < stat_evo_points) + cortical_owner.balloon_alert(cortical_owner, "need [stat_evo_points] stat points") + return FALSE + + return . == FALSE ? FALSE : TRUE //. can be null, true, or false. There's a difference between null and false here + +//inject chemicals into your host +/datum/action/cooldown/borer/inject_chemical + name = "Open Chemical Injector" + button_icon_state = "chemical" + +/datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!cortical_owner.human_host) + owner.balloon_alert(owner, "host required") + return + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + ui_interact(owner) + +/datum/action/cooldown/borer/inject_chemical/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BorerChem", name) + ui.open() + +/datum/action/cooldown/borer/inject_chemical/ui_data(mob/user) + var/list/data = list() + var/mob/living/basic/cortical_borer/cortical_owner = owner + data["amount"] = cortical_owner.injection_rate_current + data["energy"] = cortical_owner.chemical_storage / CHEMICALS_PER_UNIT + data["maxEnergy"] = cortical_owner.max_chemical_storage / CHEMICALS_PER_UNIT + data["borerTransferAmounts"] = cortical_owner.injection_rates_unlocked + data["onCooldown"] = !COOLDOWN_FINISHED(cortical_owner, injection_cooldown) + data["notEnoughChemicals"] = ((cortical_owner.injection_rate_current * CHEMICALS_PER_UNIT) > cortical_owner.chemical_storage) ? TRUE : FALSE + + var/chemicals[0] + for(var/reagent in cortical_owner.known_chemicals) + var/datum/reagent/temp = GLOB.chemical_reagents_list[reagent] + if(temp) + var/chemname = temp.name + chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name)))) + data["chemicals"] = chemicals + + return data + +/datum/action/cooldown/borer/inject_chemical/ui_act(action, params) + . = ..() + if(.) + return + var/mob/living/basic/cortical_borer/cortical_owner = owner + switch(action) + if("amount") + var/target = text2num(params["target"]) + if(target in cortical_owner.injection_rates) + cortical_owner.injection_rate_current = target + . = TRUE + if("inject") + if(!iscorticalborer(usr) || !COOLDOWN_FINISHED(cortical_owner, injection_cooldown)) + return + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + var/reagent_name = params["reagent"] + 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) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + . = TRUE + +/datum/action/cooldown/borer/inject_chemical/ui_state(mob/user) + return GLOB.always_state + +/datum/action/cooldown/borer/inject_chemical/ui_status(mob/user, datum/ui_state/state) + if(!iscorticalborer(user)) + return UI_CLOSE + + var/mob/living/basic/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, atom/target) + . = ..() + 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/basic/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/basic/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" + +/datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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(!length(cortical_owner.possible_focuses)) + owner.balloon_alert(owner, "all focuses already learned") + return + var/list/fancy_list = list() + for(var/datum/borer_focus/foci as anything in cortical_owner.possible_focuses) + if(foci in cortical_owner.body_focuses) + continue + fancy_list["[foci.name] ([foci.cost] points)"] = foci + var/focus_choice = tgui_input_list(cortical_owner, "Learn a focus!", "Focus Choice", fancy_list) + if(!focus_choice) + owner.balloon_alert(owner, "focus not chosen") + return + var/datum/borer_focus/picked_focus = fancy_list[focus_choice] + if(cortical_owner.stat_evolution < picked_focus.cost) + owner.balloon_alert(owner, "[picked_focus.cost] points required") + return + cortical_owner.stat_evolution -= picked_focus.cost + cortical_owner.body_focuses += picked_focus + picked_focus.on_add(cortical_owner.human_host, owner) + owner.balloon_alert(owner, "focus learned successfully") + StartCooldown() + +/datum/action/cooldown/borer/learn_bloodchemical + name = "Learn Chemical from Blood" + button_icon_state = "bloodchem" + chemical_evo_points = 5 + +/datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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(length(cortical_owner.human_host.reagents.reagent_list) <= 0) + owner.balloon_alert(owner, "no reagents in host") + return + var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.human_host.reagents.reagent_list) + if(!reagent_choice) + owner.balloon_alert(owner, "chemical not chosen") + return + if(locate(reagent_choice) in cortical_owner.known_chemicals) + owner.balloon_alert(owner, "chemical already known") + return + if(locate(reagent_choice) in cortical_owner.blacklisted_chemicals) + owner.balloon_alert(owner, "chemical blacklisted") + return + if(!(reagent_choice.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) + owner.balloon_alert(owner, "cannot learn [initial(reagent_choice.name)]") + return + cortical_owner.chemical_evolution -= chemical_evo_points + cortical_owner.known_chemicals += reagent_choice.type + cortical_owner.blood_chems_learned++ + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) + if(cortical_owner.blood_chems_learned == BLOOD_CHEM_OBJECTIVE) + GLOB.successful_blood_chem += 1 + owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") + if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) + to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) + StartCooldown() + +//become stronger by learning new chemicals +/datum/action/cooldown/borer/upgrade_chemical + name = "Learn New Chemical" + button_icon_state = "bloodlevel" + chemical_evo_points = 1 + +/datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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(!length(cortical_owner.potential_chemicals)) + owner.balloon_alert(owner, "all chemicals learned") + return + var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.potential_chemicals) + if(!reagent_choice) + owner.balloon_alert(owner, "no chemical chosen") + return + cortical_owner.chemical_evolution -= chemical_evo_points + cortical_owner.known_chemicals += reagent_choice + cortical_owner.potential_chemicals -= reagent_choice + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) + owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") + if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) + to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) + StartCooldown() + +//become stronger by affecting the stats +/datum/action/cooldown/borer/upgrade_stat + name = "Become Stronger" + button_icon_state = "level" + stat_evo_points = 1 + +/datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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 + cortical_owner.stat_evolution -= stat_evo_points + 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 + cortical_owner.level += 1 + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10 * cortical_owner.host_harm_multiplier) + cortical_owner.human_host.adjust_eye_blur(6 SECONDS * 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() + +//go between either hiding behind tables or behind mobs +/datum/action/cooldown/borer/toggle_hiding + name = "Toggle Hiding" + button_icon_state = "hide" + +/datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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() + +//to paralyze people +/datum/action/cooldown/borer/fear_human + name = "Incite Fear" + cooldown_time = 12 SECONDS + button_icon_state = "fear" + +/datum/action/cooldown/borer/fear_human/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(cortical_owner.human_host) + incite_internal_fear() + StartCooldown() + return + var/list/potential_freezers = list() + for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) + if(!ishuman(listed_human)) //no nonhuman hosts + continue + if(listed_human.stat == DEAD) //no dead hosts + continue + if(considered_afk(listed_human.mind)) //no afk hosts + continue + potential_freezers += listed_human + if(length(potential_freezers) == 1) + incite_fear(potential_freezers[1]) + return + var/mob/living/carbon/human/choose_fear = tgui_input_list(cortical_owner, "Choose who you will fear!", "Fear Choice", potential_freezers) + if(!choose_fear) + owner.balloon_alert(owner, "no target chosen") + return + if(get_dist(choose_fear, cortical_owner) > 1) + owner.balloon_alert(owner, "chosen target too far") + return + incite_fear(choose_fear) + StartCooldown() + +/datum/action/cooldown/borer/fear_human/proc/incite_fear(mob/living/carbon/human/singular_fear) + var/mob/living/basic/cortical_borer/cortical_owner = owner + to_chat(singular_fear, span_warning("Something glares menacingly at you!")) + singular_fear.Paralyze(7 SECONDS) + singular_fear.adjustStaminaLoss(50) + singular_fear.set_confusion_if_lower(9 SECONDS) + var/turf/human_turf = get_turf(singular_fear) + var/logging_text = "[key_name(cortical_owner)] feared/paralyzed [key_name(singular_fear)] at [loc_name(human_turf)]" + cortical_owner.log_message(logging_text, LOG_GAME) + singular_fear.log_message(logging_text, LOG_GAME) + +/datum/action/cooldown/borer/fear_human/proc/incite_internal_fear() + var/mob/living/basic/cortical_borer/cortical_owner = owner + owner.balloon_alert(owner, "fear incited into host") + cortical_owner.human_host.Paralyze(10 SECONDS) + cortical_owner.human_host.adjustStaminaLoss(100) + cortical_owner.human_host.set_confusion_if_lower(15 SECONDS) + to_chat(cortical_owner.human_host, span_warning("Something moves inside of you violently!")) + var/turf/human_turf = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] feared/paralyzed [key_name(cortical_owner.human_host)] (internal) at [loc_name(human_turf)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + +//to check the health of the human +/datum/action/cooldown/borer/check_blood + name = "Check Blood" + cooldown_time = 5 SECONDS + button_icon_state = "blood" + +/datum/action/cooldown/borer/check_blood/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(!cortical_owner.human_host) + owner.balloon_alert(owner, "host required") + return + healthscan(owner, cortical_owner.human_host, advanced = TRUE) // :thinking: + chemscan(owner, cortical_owner.human_host) + StartCooldown() + +//to either get inside, or out, of a host +/datum/action/cooldown/borer/choosing_host + name = "Inhabit/Uninhabit Host" + cooldown_time = 10 SECONDS + button_icon_state = "host" + +/datum/action/cooldown/borer/choosing_host/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + + //having a host means we need to leave them then + if(cortical_owner.human_host) + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + owner.balloon_alert(owner, "detached from host") + 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.organs + //log the interaction + var/turf/human_turfone = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] left [key_name(cortical_owner.human_host)] at [loc_name(human_turfone)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + if(borer_organ) + borer_organ.Remove(cortical_owner.human_host) + cortical_owner.forceMove(human_turfone) + cortical_owner.human_host = null + StartCooldown() + return + + //we dont have a host so lets inhabit one + var/list/usable_hosts = list() + for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) + // no non-human hosts + if(!ishuman(listed_human) || ismonkey(listed_human)) + continue + // cannot have multiple borers (for now) + if(listed_human.has_borer()) + continue + // hosts need to be organic + if(!(listed_human.dna.species.inherent_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) + continue + // hosts need to be organic + if(!(listed_human.mob_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) + continue + //hosts cannot be changelings + if(listed_human.mind) + var/datum/antagonist/changeling/changeling = listed_human.mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling && cortical_owner.changeling_restricted) + continue + usable_hosts += listed_human + + //if the list of possible hosts is one, just go straight in, no choosing + if(length(usable_hosts) == 1) + enter_host(usable_hosts[1]) + return + + //if the list of possible host is more than one, allow choosing a host + var/choose_host = tgui_input_list(cortical_owner, "Choose your host!", "Host Choice", usable_hosts) + if(!choose_host) + owner.balloon_alert(owner, "no target selected") + return + enter_host(choose_host) + +/datum/action/cooldown/borer/choosing_host/proc/enter_host(mob/living/carbon/human/singular_host) + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(check_for_bio_protection(singular_host)) + owner.balloon_alert(owner, "target head too protected!") + return + if(singular_host.has_borer()) + owner.balloon_alert(owner, "target already occupied") + return + 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) + owner.balloon_alert(owner, "target too far away") + return + cortical_owner.human_host = singular_host + cortical_owner.forceMove(cortical_owner.human_host) + 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 + borer_organ.Insert(cortical_owner.human_host) + var/turf/human_turftwo = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] went into [key_name(cortical_owner.human_host)] at [loc_name(human_turftwo)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + StartCooldown() + +/// Checks if the target's head is bio protected, returns true if this is the case +/datum/action/cooldown/borer/choosing_host/proc/check_for_bio_protection(mob/living/carbon/human/target) + if(isobj(target.head)) + if(target.head.get_armor_rating(BIO) >= 100) + return TRUE + if(isobj(target.wear_mask)) + if(target.wear_mask.get_armor_rating(BIO) >= 100) + return TRUE + if(isobj(target.wear_neck)) + if(target.wear_neck.get_armor_rating(BIO) >= 100) + return TRUE + return FALSE + +//you can force your host to speak... dont abuse this +/datum/action/cooldown/borer/force_speak + name = "Force Host Speak" + cooldown_time = 30 SECONDS + button_icon_state = "speak" + +/datum/action/cooldown/borer/force_speak/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(!cortical_owner.inside_human()) + owner.balloon_alert(owner, "must be in a host") + return + var/borer_message = input(cortical_owner, "What would you like to force your host to say?", "Force Speak") as message|null + if(!borer_message) + owner.balloon_alert(owner, "no message given") + return + borer_message = sanitize(borer_message) + var/mob/living/carbon/human/cortical_host = cortical_owner.human_host + to_chat(cortical_host, span_boldwarning("Your voice moves without your permission!")) + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + 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)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + StartCooldown() + +//we need a way to produce offspring +/datum/action/cooldown/borer/produce_offspring + name = "Produce Offspring" + cooldown_time = 1 MINUTES + button_icon_state = "reproduce" + chemical_cost = 100 + +/datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!(cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + cortical_owner.chemical_storage -= chemical_cost + 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.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25 * cortical_owner.host_harm_multiplier) + var/eggroll = rand(1,100) + if(eggroll <= 75) + switch(eggroll) + if(1 to 34) + cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_BASIC) + if(35 to 60) + cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY) + if(61 to 71) + cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_SURGERY) + 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)]" + cortical_owner.log_message(logging_text, LOG_GAME) + owner.balloon_alert(owner, "egg laid") + StartCooldown() + +/datum/action/cooldown/borer/produce_offspring/proc/no_host_egg() + var/mob/living/basic/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/basic/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" + cooldown_time = 2 MINUTES + button_icon_state = "revive" + chemical_cost = 200 + +/datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(!cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + cortical_owner.chemical_storage -= chemical_cost + if(cortical_owner.human_host.getBruteLoss()) + cortical_owner.human_host.adjustBruteLoss(-(cortical_owner.human_host.getBruteLoss()*0.5)) + if(cortical_owner.human_host.getToxLoss()) + cortical_owner.human_host.adjustToxLoss(-(cortical_owner.human_host.getToxLoss()*0.5)) + if(cortical_owner.human_host.getFireLoss()) + cortical_owner.human_host.adjustFireLoss(-(cortical_owner.human_host.getFireLoss()*0.5)) + if(cortical_owner.human_host.getOxyLoss()) + cortical_owner.human_host.adjustOxyLoss(-(cortical_owner.human_host.getOxyLoss()*0.5)) + if(cortical_owner.human_host.blood_volume < BLOOD_VOLUME_BAD) + cortical_owner.human_host.blood_volume = BLOOD_VOLUME_BAD + for(var/obj/item/organ/internal/internal_target in cortical_owner.human_host.organs) + internal_target.applyOrganDamage(-internal_target.damage * 0.5) + cortical_owner.human_host.revive() + to_chat(cortical_owner.human_host, span_boldwarning("Your heart jumpstarts!")) + owner.balloon_alert(owner, "host revived") + var/turf/human_turf = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] revived [key_name(cortical_owner.human_host)] at [loc_name(human_turf)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + StartCooldown() + +//to ask if a host is willing +/datum/action/cooldown/borer/willing_host + name = "Willing Host" + cooldown_time = 2 MINUTES + button_icon_state = "willing" + chemical_cost = 150 + +/datum/action/cooldown/borer/willing_host/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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 + for(var/ckey_check in GLOB.willing_hosts) + if(ckey_check == cortical_owner.human_host.ckey) + owner.balloon_alert(owner, "host already willing") + return + owner.balloon_alert(owner, "asking host...") + cortical_owner.chemical_storage -= chemical_cost + var/host_choice = tgui_input_list(cortical_owner.human_host,"Do you accept to be a willing host?", "Willing Host Request", list("Yes", "No")) + if(host_choice != "Yes") + owner.balloon_alert(owner, "host not willing!") + StartCooldown() + return + owner.balloon_alert(owner, "host willing!") + to_chat(cortical_owner.human_host, span_notice("You have accepted being a willing host!")) + GLOB.willing_hosts += cortical_owner.human_host.ckey + StartCooldown() + +/datum/action/cooldown/borer/stealth_mode + name = "Stealth Mode" + cooldown_time = 2 MINUTES + button_icon_state = "hiding" + chemical_cost = 100 + +/datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags, atom/target) + var/mob/living/basic/cortical_borer/cortical_owner = owner + var/in_stealth = (cortical_owner.upgrade_flags & BORER_STEALTH_MODE) + if(in_stealth) + chemical_cost = 0 + else + chemical_cost = initial(chemical_cost) + . = ..() + if(!.) + return FALSE + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + owner.balloon_alert(owner, "stealth mode [in_stealth ? "disabled" : "enabled"]") + cortical_owner.chemical_storage -= chemical_cost + 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" + cooldown_time = 1 MINUTES + button_icon_state = "reproduce" + chemical_cost = 150 + +/datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + if(cortical_owner.human_host.stat != DEAD) + owner.balloon_alert(owner, "host not dead") + return + + cortical_owner.chemical_storage -= chemical_cost + var/turf/borer_turf = get_turf(cortical_owner) + var/obj/item/bodypart/chest/chest = cortical_owner.human_host.get_bodypart(BODY_ZONE_CHEST) + if((!chest || IS_ORGANIC_LIMB(chest)) && !cortical_owner.human_host.getorgan(/obj/item/organ/internal/empowered_borer_egg)) + var/obj/item/organ/internal/empowered_borer_egg/spawned_egg = new(cortical_owner.human_host) + spawned_egg.generation = (cortical_owner.generation + 1) + + cortical_owner.children_produced += 1 + 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) + cortical_owner.balloon_alert(owner, "egg laid") + StartCooldown() + +#undef CHEMICALS_PER_UNIT +#undef CHEMICAL_SECOND_DIVISOR +#undef OUT_OF_HOST_EGG_COST +#undef BLOOD_CHEM_OBJECTIVE diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm new file mode 100644 index 000000000000..ef793957e59a --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm @@ -0,0 +1,188 @@ +#define POP_PER_BORER 30 + +/proc/printborer(datum/mind/borer) + var/list/text = list() + var/mob/living/basic/cortical_borer/player_borer = borer.current + if(!player_borer) + text += span_redtext("[span_bold(borer.name)] had their body destroyed.") + return text.Join("
") + if(borer.current.stat != DEAD) + text += "[span_bold(player_borer.name)] [span_greentext("survived")]" + else + text += "[span_bold(player_borer.name)] [span_redtext("died")]" + text += span_bold("[span_bold(player_borer.name)] produced [player_borer.children_produced] borers.") + var/list/string_of_genomes = list() + + for(var/evo_index in player_borer.past_evolutions) + var/datum/borer_evolution/evolution = player_borer.past_evolutions[evo_index] + string_of_genomes += evolution.name + + text += "[span_bold(player_borer.name)] had the following evolutions: [english_list(string_of_genomes)]" + return text.Join("
") + +/proc/printborerlist(list/players,fleecheck) + var/list/parts = list() + + parts += "" + return parts.Join("
") + +/datum/antagonist/cortical_borer + name = "Cortical Borer" + job_rank = ROLE_BORER + show_in_antagpanel = TRUE + roundend_category = "cortical borers" + antagpanel_category = "Cortical Borers" + prevent_roundtype_conversion = FALSE + show_to_ghosts = TRUE + /// The team of borers + var/datum/team/cortical_borers/borers + +/datum/antagonist/cortical_borer/get_preview_icon() + return finish_preview_icon(icon('monkestation/code/modules/antagonists/borers/icons/animal.dmi', "brainslug")) + +/datum/antagonist/cortical_borer/get_team() + return borers + +/datum/antagonist/cortical_borer/create_team(datum/team/cortical_borers/new_team) + if(!new_team) + for(var/datum/antagonist/cortical_borer/borer in GLOB.antagonists) + if(!borer.owner) + stack_trace("Antagonist datum without owner in GLOB.antagonists: [borer]") + continue + if(borer.borers) + borers = borer.borers + return + borers = new /datum/team/cortical_borers + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + borers = new_team + +/datum/team/cortical_borers + name = "Cortical Borers" + +/datum/team/cortical_borers/roundend_report() + var/list/parts = list() + parts += span_header("The [name] were:") + parts += printborerlist(members) + var/survival = FALSE + for(var/mob/living/basic/cortical_borer/check_borer in GLOB.cortical_borers) + if(check_borer.stat == DEAD) + continue + survival = TRUE + if(survival) + parts += span_greentext("Borers were able to survive the shift!") + else + parts += span_redtext("Borers were unable to survive the shift!") + if(GLOB.successful_egg_number >= GLOB.objective_egg_borer_number) + parts += span_greentext("Borers were able to produce enough eggs!") + else + parts += span_redtext("Borers were unable to produce enough eggs!") + if(length(GLOB.willing_hosts) >= GLOB.objective_willing_hosts) + parts += span_greentext("Borers were able to gather enough willing hosts!") + else + parts += span_redtext("Borers were unable to gather enough willing hosts!") + if(GLOB.successful_blood_chem >= GLOB.objective_blood_borer) + parts += span_greentext("Borers were able to learn enough chemicals through the blood!") + else + parts += span_redtext("Borers were unable to learn enough chemicals through the blood!") + return "
[parts.Join("
")]
" + +/datum/round_event_control/cortical_borer + name = "Cortical Borer Infestation" + typepath = /datum/round_event/ghost_role/cortical_borer + weight = 10 + min_players = 999 + max_occurrences = 1 //should only ever happen once + dynamic_should_hijack = TRUE + +/datum/round_event/ghost_role/cortical_borer + announceWhen = 400 + +/datum/round_event/ghost_role/cortical_borer/setup() + announceWhen = rand(announceWhen, announceWhen + 50) + +/datum/round_event/ghost_role/cortical_borer/announce(fake) + priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS) + +/datum/round_event/ghost_role/cortical_borer/start() + var/list/vents = list() + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) + if(QDELETED(temp_vent)) + continue + if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] + if(!temp_vent_parent) + continue // No parent vent + // Stops Cortical Borers getting stuck in small networks. + // See: Security, Virology + if(length(temp_vent_parent.other_atmos_machines) > 20) + vents += temp_vent + if(!length(vents)) + return MAP_ERROR + var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER) + if(!length(candidates)) + return NOT_ENOUGH_PLAYERS + var/living_number = max(length(GLOB.player_list) / POP_PER_BORER, 1) + var/choosing_number = min(length(candidates), living_number) + for(var/repeating_code in 1 to choosing_number) + var/mob/dead/observer/new_borer = pick(candidates) + candidates -= new_borer + var/turf/vent_turf = get_turf(pick(vents)) + var/mob/living/basic/cortical_borer/spawned_cb = new /mob/living/basic/cortical_borer(vent_turf) + spawned_cb.ckey = new_borer.ckey + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) + to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) + for(var/mob/dead_mob in GLOB.dead_mob_list) + to_chat(dead_mob, span_notice("The cortical borers have been selected, you are able to orbit them! Remember, they can reproduce!")) + +/* +/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer + name = "Cortical Borer Infestation" + antag_datum = /datum/antagonist/cortical_borer + antag_flag = ROLE_BORER + enemy_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + ) + required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_candidates = 1 + weight = 3 + cost = 15 + requirements = list(101,101,101,70,50,40,20,15,10,10) + repeatable = TRUE + /// List of on-station vents + var/list/vents = list() + +/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/execute() + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) + if(QDELETED(temp_vent)) + continue + if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] + if(!temp_vent_parent) + continue // No parent vent + // Stops Borers getting stuck in small networks. + // See: Security, Virology + if(length(temp_vent_parent.other_atmos_machines) > 20) + vents += temp_vent + if(!length(vents)) + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/generate_ruleset_body(mob/applicant) + var/obj/vent = pick_n_take(vents) + var/mob/living/basic/cortical_borer/new_borer = new(vent.loc) + new_borer.key = applicant.key + new_borer.move_into_vent(vent) + message_admins("[ADMIN_LOOKUPFLW(new_borer)] has been made into a borer by the midround ruleset.") + log_game("DYNAMIC: [key_name(new_borer)] was spawned as a borer by the midround ruleset.") + return new_borer +*/ + +#undef POP_PER_BORER diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm new file mode 100644 index 000000000000..7d4ef3f28f4e --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm @@ -0,0 +1,19 @@ +/datum/reagent/drug/methamphetamine/borer_version + overdose_threshold = 40 + +/datum/reagent/drug/methamphetamine/borer_version/on_mob_life(mob/living/carbon/M, delta_time, times_fired) + var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.") + if(DT_PROB(2.5, delta_time)) + to_chat(M, span_notice("[high_message]")) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "tweaking", /datum/mood_event/stimulant_medium, name) + M.AdjustStun(-40 * REM * delta_time) + M.AdjustKnockdown(-40 * REM * delta_time) + M.AdjustUnconscious(-40 * REM * delta_time) + M.AdjustParalyzed(-40 * REM * delta_time) + M.AdjustImmobilized(-40 * REM * delta_time) + M.adjustStaminaLoss(-2 * REM * delta_time, 0) + M.Jitter(2 * REM * delta_time) + if(DT_PROB(2.5, delta_time)) + M.emote(pick("twitch", "shiver")) + ..() + . = TRUE diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm new file mode 100644 index 000000000000..d45b307d6f88 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm @@ -0,0 +1,96 @@ +/obj/effect/mob_spawn/ghost_role/borer_egg + name = "borer egg" + desc = "An egg of a creature that is known to crawl inside of you, be careful." + icon = 'monkestation/code/modules/antagonists/borers/icons/animal.dmi' + icon_state = "brainegg" + layer = BELOW_MOB_LAYER + density = FALSE + mob_name = "cortical borer" + ///Type of mob that will be spawned + mob_type = /mob/living/basic/cortical_borer + role_ban = ROLE_ALIEN + show_flavor = FALSE + prompt_name = "cortical borer" + you_are_text = "You are a Cortical Borer." + flavour_text = "You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! \ + You only grow/heal/talk when inside a host!" + important_text = "As a borer, you have the option to be friendly or not. \ + Note that how you act will determine how a host responds. \ + Do not wordlessly resort to mechanics within a host. \ + You can talk to other borers using ; and your host by just speaking normally. \ + You are unable to speak outside of a host, but are able to emote." + ///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 = /obj/item/borer_egg + +/obj/effect/mob_spawn/ghost_role/borer_egg/Destroy() + host_egg = null + return ..() + +/obj/effect/mob_spawn/ghost_role/borer_egg/special(mob/living/spawned_mob, mob/mob_possessor) + . = ..() + spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer) + spawned_mob.name = "cortical borer ([generation]-[rand(100,999)])" + QDEL_NULL(host_egg) + +/obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team) + . = ..() + host_egg = new host_egg(get_turf(src)) + host_egg.host_spawner = src + forceMove(host_egg) + var/area/src_area = get_area(src) + if(src_area) + notify_ghosts("A cortical borer egg has been laid in \the [src_area.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_DRONE, notify_suiciders = FALSE) + +/obj/item/borer_egg + name = "borer egg" + desc = "An egg of a creature that is known to crawl inside of you, be careful." + icon = 'monkestation/code/modules/antagonists/borers/icons/animal.dmi' + icon_state = "brainegg" + layer = BELOW_MOB_LAYER + ///the spawner that is attached to this item + var/obj/effect/mob_spawn/ghost_role/borer_egg/host_spawner + +/obj/item/borer_egg/attack_ghost(mob/user) + if(host_spawner) + host_spawner.attack_ghost(user) + return ..() + +/obj/item/borer_egg/attack_self(mob/user, modifiers) + to_chat(user, span_notice("You crush [src] within your grasp.")) + new /obj/effect/decal/cleanable/food/egg_smudge(get_turf(user)) + if(host_spawner) + QDEL_NULL(host_spawner) + qdel(src) + +/obj/item/borer_egg/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if (..()) // was it caught by a mob? + return + + var/turf/hit_turf = get_turf(hit_atom) + new /obj/effect/decal/cleanable/food/egg_smudge(hit_turf) + QDEL_NULL(host_spawner) + qdel(src) + +/obj/item/borer_egg/empowered + name = "empowered borer egg" + icon_state = "empowered_brainegg" + +/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/basic/cortical_borer/empowered + host_egg = /obj/item/borer_egg/empowered + +/* +/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 \ + learn new chemicals through the blood if old enough. Be careful as there is no way to get the borer to pledge allegiance \ + to yourself. The egg is extremely fragile, do not crush it in your hand nor throw it. \ + The egg is required to sit out in the open in order to hatch. (Cannot be hidden in closets, etc.)" + progression_minimum = 20 MINUTES + item = /obj/item/borer_egg + cost = 20 +*/ diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm new file mode 100644 index 000000000000..7152787b5730 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm @@ -0,0 +1,103 @@ +/obj/item/cortical_cage + name = "cortical borer cage" + desc = "A harmless cage that is intended to capture cortical borers." + icon = 'monkestation/code/modules/antagonists/borers/icons/items.dmi' + icon_state = "cage" + + ///If true, the trap is "open" and can trigger. + var/opened = FALSE + ///The radio that is inserted into the trap. + var/obj/item/radio/internal_radio + ///The borer that is inside the trap + var/mob/living/basic/cortical_borer/trapped_borer + +/obj/item/cortical_cage/Initialize(mapload) + . = ..() + update_appearance() + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/spring_trap, + ) + AddElement(/datum/element/connect_loc, loc_connections) + +/obj/item/cortical_cage/update_overlays() + . = ..() + if(trapped_borer) + . += "borer" + if(internal_radio) + . += "radio" + if(opened) + . += "doors_open" + else + . += "doors_closed" + +/obj/item/cortical_cage/attack_self(mob/user, modifiers) + opened = !opened + if(opened) + user.visible_message("[user] opens [src].", "You open [src].", "You hear a metallic thunk.") + else + user.visible_message("[user] closes [src].", "You close [src].", "You hear a metallic thunk.") + playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + update_appearance() + +/obj/item/cortical_cage/attackby(obj/item/attacking_item, mob/user, params) + if(istype(attacking_item, /obj/item/radio)) + internal_radio = attacking_item + internal_radio.forceMove(src) + visible_message("[internal_radio] attaches to [src] with a click.", "You attach [internal_radio] to the [src].", "You hear a clicking sound.") + update_appearance() + return + return ..() + +/obj/item/cortical_cage/crowbar_act(mob/living/user, obj/item/tool) + . = ..() + if(internal_radio) + internal_radio.forceMove(get_turf(src)) + user.visible_message("[internal_radio] pops off [src].", "You pop off [internal_radio] from [src].", "You hear a clicking sound then a loud metallic thunk.") + internal_radio = null + update_appearance() + return + +/obj/item/cortical_cage/proc/spring_trap(datum/source, atom/movable/AM) + SIGNAL_HANDLER + //it will only trigger on a cortical borer, and it has to be opened + if(!iscorticalborer(AM) || !opened) + return + trapped_borer = AM + trapped_borer.visible_message("[trapped_borer] gets sucked into [src]!", "You get sucked into [src]!", "You hear a vacuuming sound.") + trapped_borer.forceMove(src) + opened = FALSE + if(internal_radio) + var/area/src_area = get_area(src) + internal_radio.talk_into(src, "A cortical borer has been trapped in [src_area].", RADIO_CHANNEL_COMMON) + playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + update_appearance() + +/obj/item/cortical_cage/relaymove(mob/living/user, direction) + if(!iscorticalborer(user)) + user.forceMove(get_turf(src)) + update_appearance() + return + if(opened) + loc.visible_message(span_notice("[user] climbs out of [src]!"), \ + span_warning("[user] jumps out of [src]!")) + opened = FALSE + trapped_borer.forceMove(get_turf(src)) + trapped_borer = null + update_appearance() + return + else if(user.client) + container_resist_act(user) + +/obj/item/cortical_cage/container_resist_act(mob/living/user) + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + to_chat(user, span_notice("You begin squeezing through the bars in an attempt to escape! (This will take time.)")) + to_chat(loc, span_warning("You see [user] begin trying to squeeze through the bars!")) + if(!do_after(user, rand(30 SECONDS, 40 SECONDS), target = user) || opened || !(user in contents)) + return + loc.visible_message(span_warning("[user] squeezes through [src]'s handles!"), null, null, null, user) + to_chat(user, span_boldannounce("Bingo, you squeeze through!")) + opened = FALSE + trapped_borer.forceMove(get_turf(src)) + trapped_borer = null + update_appearance() diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/borer_evolution.dm b/monkestation/code/modules/antagonists/borers/code/evolution/borer_evolution.dm new file mode 100644 index 000000000000..ad8ce237db07 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/borer_evolution.dm @@ -0,0 +1,17 @@ +/mob/living/basic/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/basic/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 diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm new file mode 100644 index 000000000000..657cc24f632c --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm @@ -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/basic/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, + ) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm new file mode 100644 index 000000000000..5a07e43d3131 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm @@ -0,0 +1,111 @@ +/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) + evo_cost = 1 + +/datum/borer_evolution/diveworm/health_per_level/on_evolve(mob/living/basic/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/basic/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/basic/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) + evo_cost = 2 + +/datum/borer_evolution/diveworm/health_per_level/t3 + name = "Health Increase III" + tier = -1 + unlocked_evolutions = list() + evo_cost = 2 + +// 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/basic/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/basic/cortical_borer/cortical_owner) + . = ..() + var/datum/action/cooldown/borer/empowered_offspring/attack_action = new() + attack_action.Grant(cortical_owner) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm new file mode 100644 index 000000000000..9a21906dbf37 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm @@ -0,0 +1,80 @@ +/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/basic/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/basic/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/basic/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/basic/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/thermite, + /datum/reagent/pyrosium, + /datum/reagent/oxygen, + ) + +/datum/borer_evolution/synthetic_chems_negative/on_evolve(mob/living/basic/cortical_borer/cortical_owner) + . = ..() + cortical_owner.potential_chemicals |= added_chemicals diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm new file mode 100644 index 000000000000..ca5e11883524 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm @@ -0,0 +1,73 @@ +/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) + evo_cost = 1 + +/datum/borer_evolution/hivelord/produce_offspring/on_evolve(mob/living/basic/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/basic/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/basic/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/basic/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/basic/cortical_borer/cortical_owner) + . = ..() + cortical_owner.upgrade_flags |= BORER_ALONE_PRODUCTION diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm new file mode 100644 index 000000000000..5f2000158014 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm @@ -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) + evo_cost = 1 + +/datum/borer_evolution/symbiote/willing_host/on_evolve(mob/living/basic/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/basic/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/basic/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/basic/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/basic/cortical_borer/cortical_owner) + . = ..() + var/datum/action/cooldown/borer/revive_host/attack_action = new() + attack_action.Grant(cortical_owner) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm new file mode 100644 index 000000000000..a685b1d9f710 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm @@ -0,0 +1,54 @@ +/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() + owner.visible_message(span_danger("An egg explodes out of [owner]'s chest, sending gore flying everywhere!"), span_danger("An egg explodes out of your chest, giblets flying everywhere!")) + return + var/mob/dead/observer/new_borer = pick(candidates) + var/mob/living/basic/cortical_borer/empowered/spawned_cb = new(get_turf(owner)) + var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST) + chest.dismember() + owner.visible_message(span_danger("[spawned_cb] explodes out of [owner]'s chest, sending gore flying everywhere!"), span_danger("[spawned_cb] explodes out of your chest, giblets flying everywhere!")) + spawned_cb.generation = generation + spawned_cb.ckey = new_borer.ckey + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) diff --git a/monkestation/code/modules/antagonists/borers/code/focus_datum.dm b/monkestation/code/modules/antagonists/borers/code/focus_datum.dm new file mode 100644 index 000000000000..86db5e6c772e --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/focus_datum.dm @@ -0,0 +1,77 @@ +/datum/borer_focus + /// Name of the focus + var/name = "" + /// Cost of the focus + var/cost = 5 + /// Traits to add/remove + var/list/traits = list() + +/// Effects to take when the focus is added +/datum/borer_focus/proc/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + SHOULD_CALL_PARENT(TRUE) + for(var/trait in traits) + if(HAS_TRAIT(host, trait)) + continue + ADD_TRAIT(host, trait, borer) + +/// Effects to take when the focus is removed +/datum/borer_focus/proc/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + SHOULD_CALL_PARENT(TRUE) + for(var/trait in traits) + if(!HAS_TRAIT_FROM(host, trait, borer)) + continue + REMOVE_TRAIT(host, trait, borer) + +/datum/borer_focus/head + name = "head focus" + traits = list(TRAIT_NOFLASH, TRAIT_TRUE_NIGHT_VISION, TRAIT_KNOW_ENGI_WIRES) + +/datum/borer_focus/head/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("Your eyes begin to feel strange...")) + return ..() + +/datum/borer_focus/head/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("Your eyes begin to return to normal...")) + host.update_sight() + return ..() + +/datum/borer_focus/chest + name = "chest focus" + traits = list(TRAIT_NOBREATH, TRAIT_NOHUNGER, TRAIT_STABLEHEART) + +/datum/borer_focus/chest/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("Your chest begins to slow down...")) + host.nutrition = NUTRITION_LEVEL_WELL_FED + return ..() + +/datum/borer_focus/chest/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("Your chest begins to heave again...")) + return ..() + +/datum/borer_focus/arms + name = "arm focus" + traits = list(TRAIT_QUICKER_CARRY, TRAIT_QUICK_BUILD, TRAIT_SHOCKIMMUNE) + +/datum/borer_focus/arms/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("Your arms start to feel funny...")) + 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/basic/cortical_borer/borer) + to_chat(host, span_notice("Your arms start to feel normal again...")) + borer.human_host.remove_actionspeed_modifier(ACTIONSPEED_ID_BORER) + return ..() + +/datum/borer_focus/legs + name = "leg focus" + traits = list(TRAIT_LIGHT_STEP, TRAIT_FREERUNNING, TRAIT_SILENT_FOOTSTEPS) + +/datum/borer_focus/legs/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("You feel faster...")) + host.add_movespeed_modifier(/datum/movespeed_modifier/focus_speed) + return ..() + +/datum/borer_focus/legs/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) + to_chat(host, span_notice("You feel slower...")) + host.remove_movespeed_modifier(/datum/movespeed_modifier/focus_speed) + return ..() diff --git a/monkestation/code/modules/antagonists/borers/code/status_effects.dm b/monkestation/code/modules/antagonists/borers/code/status_effects.dm new file mode 100644 index 000000000000..edfca2eff0ec --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/status_effects.dm @@ -0,0 +1,11 @@ +/datum/status_effect/borer_sugar + id = "borer_sugar" + tick_interval = -1 + status_type = STATUS_EFFECT_UNIQUE + alert_type = /atom/movable/screen/alert/status_effect/borer_sugar + +/atom/movable/screen/alert/status_effect/borer_sugar + name = "Sugar Dampening" + desc = "Your powers are diminished while sugar is in you or your host!" + icon = 'monkestation/code/modules/antagonists/borers/icons/actions.dmi' + icon_state = "borer_sugar" diff --git a/monkestation/code/modules/antagonists/borers/icons/actions.dmi b/monkestation/code/modules/antagonists/borers/icons/actions.dmi new file mode 100644 index 0000000000000000000000000000000000000000..caf6dba6136c0764ae8099d8f79bf180ee007e8a GIT binary patch literal 6184 zcmaKQWmHsO^!6PZ1{^{{q(MNsyF?L?25F>}QW}&Rh5)H2t_TCY?+NxwE^dtZPkg2OZ)5qFx*auETfPF{5 zwta{->;5lIyr0>5z4ml+_jYn~1pwd7n31a34k1$bva}xwc!I=(c7m^v?H|Yzlpir` zl1Kbv)TkLlMymOD-gf(VNipC;)~e}Y?WDHAS8zTNy>@u+ecr~MCm*j;I@n`cTf_CW zRE8^$i~eQZkM#tRDe99>YhJ*D$fe&ToJu8#2Zw=Z*T!2QoC+oqwv35cVDNQ(;%q@F z(kWx^Lob}O#xb9qJGPWpN6e}^GtZr_A1wCsxp=W&PF*yZ|AxyRy0K>8*GHUdKE`la zKw&&)@a<|Pw;=k`aswSuDWB=aj}7b=cbIl^++-|70RU)j)t^0i>6?kl3h<_y%tE$_ zPV{|o?z_P6iZf{EwY8-*mrIm*6~Q@O;Nq{J*_F?+Zx4Bu(f(a4bu|z5rDnbW^+987 zEE!jQDt=8#BZF@$9HG7y3{M^vllVdJUvzY$aLb}8Du*h?R)Y?PGoLK zS|)L0aBi_h)C#lzZiDO38uEpTOfpWqh@S`#egKdAcBdjxdsVw#P5w z_tn4S^ed4*XXiS5b-}bRbt@aR=#Eq;rndg%sm?-k^goM7t`ccFDiK_|M{TGU^VE{>8G!mj`m z-MMVnoDB!JbIsN>y1y`NeYPx__Dm^NIa`x2D=%zzaHyW`<1;!#c&N-f@K~LvBq2~Y z!8O&~6hsihlst{j*t`cmXQuaF2ek(e@i%2S@0vBrKBC@?DzB{kDJCenDe(!thzB@- z89jL5@P-{X>8K>O1Xo*X;m8knb5kQ!b>;&DwJZCk?KJ}TT=%*r!W14_ceYqvTEKB0 zp~w*M0Fa6Wi%Gih*G~_o0!kj}9UDOE{ORmWPqD<*TvTPr@)Mx_&19c?)S=pJY~~NP z_bwk0{oF~9HNYfa93x4pW^eJlhX-V6`Ey2-mcNNP=ph3Ci$uei6R z3Q!#B_&0c=2Ul{-o_;KE_Wo?mIvZyW2M(_lq1SZ*w@%%(pl_x9z7wk+W%$6a76>4K z^RrpK?tTS>@NW}C9D@V*Q8o_CipokyQ&ZFB&Ew+~D_!n2{1;(=3SSoeVp%enbkaS*w?bD=v?yAjgIdcB&8ke{aVvCB=}-AZk3sAeJx5{Qg4&cQ4P z-FDobo*Lp4&ITa$ABTjwDwaPX()0Hko3M>T;sbPaLS>Bftt7zD#`T5sCP9WamtqGz zYBDVV?zTz|y*`3eZp@>$O6Q~InpE{B$2+=tlv@uyy$s)9UP_BU>W*?9ajfQD_mp_& z@9+Qi&Dx9hgH_Jz>gqXx!cL@SNi(Sa&n8%?({wBytkN3k!OX6)4Uh5>=w;7}8XR1n z*eDoZ2jWZa2Gg%)H6K3+vlKjg-NX%jjf-1QCo$`1(KHtxc|=XC@nRyT$r5g>YF0_(npnFBF>>G+ceUornVHs5nBZ#K zk&ZM{er!idk;U-SQ z1c=#pqN|%N96){Ejiea3T?s;ln50NzKEHR|E#*IQ z%WU$8n%aTbbH0kz{@bVmSSp&%#}*b=QNYnJqy6lja9<_E4@P$FLr%3b9o70S3-pbP z^~uB+)RsBM8}6D~I*oy^UE>a@*ct$2pvd}Z+wP$+;pLe)$t7i2$SeM&s%}%#*T??2 zZb(@Y?eRvU@q=gEiJ1|;&%aAXVk&c&TCNe9r zl@`tbS5Emgh2QS>p={;iIPyEmCcur>ycVA>ZqAn`@yiP8ZJCl^f6hWar}fNT`?IFl z!F;_6e^O1!1A;!OdzhXcewpv}WQ7aTZ$ zSsHyPn?un&E~Rg`Jv5S3{!F4Bt;<9Y#D+CcdgjLKgY>!4%5KOXY9!PwD*FFFP0Qnm zKKy>ExV$FpKK0j%O}#FGrsyo0@jC!6Mp!lF$U{u4h_@&pR3`1x?3m_~*d=OcpT zpUSh?(cBC(7CFXV`h5<=@9_oEUsUM|-7RvO>R%epT$PD9SQkbyvtZmNV@sKU^(_O zbhn~El{Rq(#$G{cpA_NLwHMW|vzaPx25mP{MURv_lm@mtUUofFvI$aF<0MeB`21Ci zbAvo&A!;#|y$Tb$%@Na<#lYS#Id%mXR-{JKrhXm%i(q$=jotSv_yt4Ozco`gV?%GV z5zCKeS`@FWK6-2Qc2qA&IAPq>+&+uB>ND-g5s>K1XTYt-*6{LAAr)2dRJV>XwAlnT z#I^ZlTec$oPUKz2qKmnFo2HqHuhpuZB+1Vm|QjGIM7y-EgbbUGC9ooFNpjM>y~oJ< zmU;h~e^8H)=*!--Ma+T~mWuwvr1d{4V*M5C5w3l-+S#q^Ffu4srE}%i1yi|RtC#|2<60>!K~cooTjcG|CW!TokU6mUzVIT>P;+avriX2!D4tQ2%WSC-UWl zV&+A)mEVgK(O};W$IB>xrK$^e0=$+%{t`sRJi091sJ4X+29?@P%3<`|Yr89Tb2Nb+ z3HRTdPw7E#kE)0;3F%`N&!S6^NYpCOOyYZ=L}@wuYXNM0)*+F_dVvb9@{zM*s{dTu!G2Sy4nmkU4UXW<{kHUR8%a3_T1>{ma5(foZV{ zIJ3W=_5lF`Ig3ce=S8M-yb@dL1-DqBwJqPfHFvAF3zObi8~=l!2*-q+@6UR!j2kO9 zWwe!jx4Be@+5O-jc=Hz8^d>D%PpIwoy-saeO%9p1AGdf^z~u)b+cU~CMW>M9#_Y;A z*{!HA<6D~ysaS&OND_e1^)R`YMbOryy$DcxLlH?)aslwP=OrkUcNNeTAyinjgwqbd zs&Xs1KLLY~`yufmCIzqA@P5$#Pfh$F@F~ywRrvpw$9exhwgI!rnK#pseya3YNgvp# zT};$LAziJ!`KP98l0M=Kxxmti>j$Q4yvh@#M#oh0dZ|YJD1Krt_PEwS-FPIxaQByN z0ox+EX+cI>)-hCtX$?VER@MW>{>gQs(^44+;C$={DD&INO-#~ss#*#m2tVW5M z$%KUv;fP@s-yV;HGm}WGR9({ejZK(lnxu?u=Yk~fgUNNV{&exth0y+bK^4=E>C~&{ z&k4gUU3mfN!nRzrpRIBLkmSJgH%s;%s06YfBu`um(6w+RC zIbzFXr87U#@ys?0N9|V1|=A~cU)&O@l8G~Ou|JW-Qb z?X(M#e`_UkOEMYOSw6Q-4hc?&x~!0Cf70WS;OXy zt>jC;j|oXik&$IEc6V!VRJqiUaUOuk2-qDYG>*?tlmFS)kQHxqYI~q5B`-6R0kTg^ z%=h&v1fb4{Cx(`mOp%c<=0?uQ@NjBcYn=CWMk7bffIa8z-@fO7AR@2 zyFt-tv5lBTdEtHGG5Hc^QSOcV6T3Fo`_fKL~%KnuTp+9snNI!4%MX0D?t90_D(a% z)>Q4srHoURGlwP1{e>C*_Q3m2812S3!*;=UB;pwTIOv&>9!>E@=$(R2D|oS!5gD|3 z@Ni!$WZpIB^zDIEu4Pe)NBO^TsW7Jz%e98HSkbpO^f?W9jvv0#ZGlE;pR9l)o{V)m zk%mjhEW7`?A*WnURN`CvbtpgQu{Q54A`D#)lf6geuXI#>=3O#b@oUTpwQY1Sg#E!Ysmc{!%R5f0oX(82GfB_n%Pp-(!3o%rw=eIN#ml zdyjSNlt+{Ek8>n6FmypMkyhgm_(3&YCF*<)*jZMj_7&bq{&{)yXP`W|Rwm8m-LaN=N?kma- z9W`J6uZmY$arTqeTg(0SjIW1J+;3n7c0r;iT0_UNQxKDM>k-0~8B(we=<5KOS3u?-yA-|6u-H3fCU%g$~NKiQqe;X4?4$}ExF}h zIQH)20p39sGzWYNGfh5=U#PIHcLNu-9Zvc97~J}<*kjj}0p~D9tXnlxN9|5?N{6Z% zHlL-RfoDtcg~^P8e8vVMX}qQw0v-dijz}06Irjf&A2QMBOkY|3SoOcIcq7 ztuy)Prydjy>X}@$t$McjIBd(?>*ELH4k-BBWWbwOWd|uw4|saWpQ-L!$foOHwe_7QL+)2RI=5!2Jl#+%aQpwFT~H8}zx zcn3=M4htYgA%_`&L0bnReD^;^s6wHXXuSU>BZ2O#*@PFfmavmgKHTTVnBn$E z_l*}K4T7YD>&9hHFm^<$_sh7et7tlp>`s9tjF5F>9(vcK&)oO)T4#=I59yZusy7AO z_DV_Bn_wK|SVGW8p%l3*WkH-`zo8J5d@r7WfPZ5*Cp=jOjZOygV8BvGaTUFV({_9M zE*Omn>hZT;)##5y%=e7*_2!7zO~U+=ce{9RM@IA|hf8kH#~+U0eUQRUMFCcMHB8C_1}}WZS4`COEzt zSX(yTCZ30IlMXzhDdxo{F-1fVL(|>%BuaUlf z*hrHMqs}A;e=<9j8sfkM=LY0%4srW+17w@xa`4~)+7p$k>Tp`tQ`ObC;#?;VDv zTRq60J&)X~VZ&f}p5U^yesHeun*;u}F!#>!WwgH_+9m{5g}G@N{}p19df+0lOUKf1 z|6I&1>|-f7gRv>iW!csGGok)n?zy5OyTZ|G3GC+7G}nfu>gxRDq`w4+KvI{7l7l#F zR#@e-@6zl{Ich1{-Z#q>vGOvPzaH?~sc70QGCd9k7u|NGkh8U`l`vK*A1!TCH?fLW z6uj2*&4h_KKl_P`Uliiw4aqLTZjA~9-SBS literal 0 HcmV?d00001 diff --git a/monkestation/code/modules/antagonists/borers/icons/animal.dmi b/monkestation/code/modules/antagonists/borers/icons/animal.dmi new file mode 100644 index 0000000000000000000000000000000000000000..68bcff0834a6b87344ea8a661d1484d0505936c4 GIT binary patch literal 2000 zcmaJ?cTm&W7XF0<2q4m>tc#!^gdzwEB1lUF0uf^-A~n*LP=Zl90wRRI^aX@PRxwJ4 zpcFxrfYOx`nof=CMl zhNGPiFO-KPXLExta8z0-*7hF4Xe|U?oiosz>9};M%8q@1{d)`vEPwB->TFK^w%(q93<W9cV5ug>VaWHFvM4KEP$!~ht` z_|N_eps(1;E|9Z5B=hTu0WQm)bL2ntbrwK!dLj9~c)Teu;8za@*uV=3{*(&x>ybCC zZ=2s_{PwiF6`C#I!G*invrj~aX*3An>|gDqI~yL|CG?>vTQV?kx~Xt{VCI~pq!$)Q zyE#=HAZb$@LNHQm;Dv&XE{s(sB`2F7M1f%{l~>Qu&GZcI0kn(#;U5RX&4dtshmmCISz+ z)?utOB@X`d=3I03mkDgPCjUHMJ_zXT#v>UTAd{hlVZm*vFWmy#33e%*HrSay#!2ZlgvLH&*(rI;_z!;S*y z>J5`bH%eKF`)o|~D(-CahIzxsO5f85N)HsH!{u3-a$FNNIAac%iT>&-}lY$w^~5)Dy}6k&X2XGdUp`IXWo(C`>a|PVCt@q5e$youc@k+ zh{?@)!sDzJNHgv!!$UXQZPr|~N(*9q3A%Rh&PiZ+>Y|QNb*~Yc)0MYlva-zJ%0Z z`S0ICex>>zN^a7*ADHm{R=6~o3;yU;#hYB#{to?%FXMgq1NpwtWi$zi3ZsElY^WjM zt`*Wl3Up=Xb5yok=*H0}Q2O!#(yu3kt#OI5d_^b=C+-Tw|6^gy+`Tp8JLfr1y8juS zi-@W%H!g&;CNcc7N5ZIgjp&%LxLivsZ&YHpXqBu86lDx-2^gA`Lv$eA@k1fMq^GZ> z^)!zAa`=~-c@^=h0}}5}7FE7ICal0U?IW4L2mAm%;XA!xYAXbdN=i98zR1>(nAUfS zG^gzWVW-u&B5&xsvcMdGYCkMPC}YFZ6u67Li*oIY?4Lp2j<1bI^AHl~G_LrovaA6D zrwUPv{8t7IOQ^i24j(AxS-Mhss(R!li^d5~M$>h=1knh@OJ5Gjd4U^Mle%%G5Txon zNY2d-*Ps2f$vy1uYENpXj3-I%uq!KUN|b!T#?e~1=h%pt#k=F=lXMCENrkd3qq}u8 z5Bv|-Uf2d4HkQYJ!NQ>Y!}MBa2BYsj8&~#*zHR$>`3>Ric>NS3uzg+V0u82el#_w9 zg62Lm5*aPB@|hD3BOv={i(sa`tLW}cfwJvbn{I(kMWgod66Bqhoppl~KTgq&W1t6^ zq_?b^iS}MQm{9Yh_0{X$JKhEyW;5T_OuxE;uMdjf7VOj@3>LoFdg<1(5nF}S7;kiY z7*RPT_dePlmR^jBsMHWg!RV&HtygsYlz4)vG#R|5H`CE#w5`#YL*DCjeIWHB5$!Z33t z!x;t!YX*jw%{lcz1&k#@e!&b5&u*jvIR#ZA5hX6E#mPmP1tppJc?=8{bArPPib}tK z2`>2f^@*0ZuGYCT=Yuzd8eBAf@JQ#pkLF2+qMqIz7REuwmyNv?<~*8oWKxJiu;yYD z)s-5C#_MhNYlL@p8>?}M>{ZX-_@ z#}JK)$q6DNA}J1RPN&?uRxoKPW-xi3d!f}6$m%jBCV=(GoVfw44cE8~dYT;h8J07% Vh}|#BUi1I} literal 0 HcmV?d00001 diff --git a/monkestation/code/modules/antagonists/borers/icons/items.dmi b/monkestation/code/modules/antagonists/borers/icons/items.dmi new file mode 100644 index 0000000000000000000000000000000000000000..156981031ab7e78d6c47cd0fb5f741eae9b0c455 GIT binary patch literal 1007 zcmVV=-0C=2*%&`i>KoA7b`t~b^q!lsI_8Li$6v;2hnOl>Cn3cUl@$W6th$!i1 z;LYSX)~BXJ)i(5CjX`Eu9JV_$&*0Mti+xFEkBDKWXku*kfK#%Rg&>Mxfd*o&Bx>-%KGm(N8MGZ+J@d1SxlmsU#+G9 z00R$6L_t(|ob8;=YZE~j#@|gt)5zjStCXS$9yAB-#fgGNN}*c6dMJt>1kd>c3SK4W zQZJrDPhR{3s;59O?M1=OA>d^LQlSX(VybQ;h-E#L-K5E8lXYkJ$*%A3l8|KQ-I-^e zcV=FeDCKgQ7#s=o4gBx00AN@EFiG?cj5@lmn|`j(WHO4|_v`={{0{ywZLk1+kTLkf zwB?wBR8=(%!*I2ZSG=^Ts;ackcj6_!5JGl%$Nu*S5LD-_wg(MD=WldfH?15x=>0Ii z9X5V0m-E|IM+${PPkhG|BzyJ;)n@15MwLSX1UdVIh+)lqS?wW+^dcN92L!S3I$;=w zBFhD_azLe02`#9sSg~k2kHwu08FF>h{GD7XqsjkhM{<^8hXX4%Goc@D3qhaitkvC4yqbDY}<%)2`YZ1 zQ&1e}DMtsXzRW^gTsR~^Sk=&=V?+sCfH3#IVa6JD>}qJ3Gm}$Mn*GL=(f7h$h1si= zK6#xT;Fn@4uO*u;@#A~T{%qyR3n>Ri761(Ig21o { + const { act, data } = useBackend(context); + const borerTransferAmounts = data.borerTransferAmounts || []; + return ( + + +
+ + + + {toFixed(data.energy) + ' units'} + + + +
+
( +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/BorerEvolution.tsx b/tgui/packages/tgui/interfaces/BorerEvolution.tsx new file mode 100644 index 000000000000..82a941fd7a3a --- /dev/null +++ b/tgui/packages/tgui/interfaces/BorerEvolution.tsx @@ -0,0 +1,142 @@ +// THIS IS A MONKESTATION UI FILE + +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 ( + + + + + + + + + + ); +}; + +const PastEvolutions = (props, context) => { + const { data } = useBackend(context); + const { learnedEvolution } = data; + + return ( + +
+ + {(!learnedEvolution.length && 'None!') || + learnedEvolution.map((learned) => ( + +
+
+ ); +}; + +const EvolutionList = (props, context) => { + const { data, act } = useBackend(context); + const { learnableEvolution } = data; + + return ( + +
+ {(!learnableEvolution.length && 'None!') || + learnableEvolution.map((toLearn) => ( + +
+
+ ); +}; + +const EvoInfo = (props, context) => { + const { data } = useBackend(context); + const { evolution_points } = data; + + return ( + + + + + You have {evolution_points || 0}  + + evolution point{evolution_points !== 1 ? 's' : ''} + {' '} + to spend. + + + + + + + + + + + ); +}; From c5722c9239f7588fea45f72f2a3d9889b7cf22c1 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:46:40 +0100 Subject: [PATCH 02/67] actually working worms --- code/__DEFINES/mobs.dm | 5 +- code/__DEFINES/span.dm | 1 + .../~monkestation-helpers/logging.dm | 4 - code/datums/components/squashable.dm | 2 + .../borers/code/abilities/_ability.dm | 41 + .../borers/code/abilities/_debug_abilities.dm | 19 + .../code/abilities/chemical_injector.dm | 101 +++ .../borers/code/abilities/enter_host.dm | 107 +++ .../borers/code/abilities/evolution_tree.dm | 87 ++ .../borers/code/abilities/force_speech.dm | 32 + .../borers/code/abilities/hide_presence.dm | 28 + .../borers/code/abilities/host_healthscan.dm | 19 + .../borers/code/abilities/incite_fear.dm | 61 ++ .../borers/code/abilities/learn_chemicals.dm | 99 +++ .../borers/code/abilities/learn_focus.dm | 36 + .../borers/code/abilities/revive_host.dm | 39 + .../borers/code/abilities/spawn_offspring.dm | 102 +++ .../borers/code/abilities/toggle_stealth.dm | 23 + .../borers/code/abilities/upgrade_body.dm | 29 + .../borers/code/abilities/willing_host.dm | 32 + .../antagonists/borers/code/cortical_borer.dm | 94 +- .../borers/code/cortical_borer_abilities.dm | 829 ------------------ .../borers/code/cortical_borer_antagonist.dm | 17 +- .../borers/code/cortical_borer_chems.dm | 23 +- .../borers/code/evolution/evolution_datum.dm | 2 +- .../code/evolution/evolution_diveworm.dm | 3 +- .../code/evolution/evolution_general.dm | 4 +- .../code/evolution/evolution_hivelord.dm | 6 +- .../code/evolution/evolution_symbiote.dm | 4 +- .../antagonists/borers/code/focus_datum.dm | 6 +- .../borers/code/items/debug_egg.dm | 21 + .../{cortical_borer_egg.dm => items/egg.dm} | 21 +- .../empowered_egg.dm | 6 +- .../imprisonment_cage.dm} | 2 +- tgstation.dme | 25 +- 35 files changed, 994 insertions(+), 936 deletions(-) delete mode 100644 code/__HELPERS/~monkestation-helpers/logging.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm delete mode 100644 monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm rename monkestation/code/modules/antagonists/borers/code/{cortical_borer_egg.dm => items/egg.dm} (79%) rename monkestation/code/modules/antagonists/borers/code/{evolution/evolution_things => items}/empowered_egg.dm (84%) rename monkestation/code/modules/antagonists/borers/code/{cortical_borer_items.dm => items/imprisonment_cage.dm} (98%) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index f4dc7d7b6106..67349475c726 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -580,8 +580,11 @@ ///Whether or not the squashing requires the squashed mob to be lying down #define SQUASHED_SHOULD_BE_DOWN (1<<0) ///Whether or not to gib when the squashed mob is moved over -#define SQUASHED_SHOULD_BE_GIBBED (1<<0) +#define SQUASHED_SHOULD_BE_GIBBED (1<<1) + +/// Don't squash our mob if its not located in a turf +#define SQUASHED_DONT_SQUASH_IN_CONTENTS (1<<3) /* * Defines for "AI emotions", allowing the AI to expression emotions * with status displays via emotes. diff --git a/code/__DEFINES/span.dm b/code/__DEFINES/span.dm index 96bd0ce4ddcb..d5f782e6fb05 100644 --- a/code/__DEFINES/span.dm +++ b/code/__DEFINES/span.dm @@ -51,6 +51,7 @@ #define span_greenteamradio(str) ("" + str + "") #define span_greentext(str) ("" + str + "") #define span_grey(str) ("" + str + "") +#define span_header(str) ("" + str + "") #define span_hear(str) ("" + str + "") #define span_hidden(str) ("") #define span_hierophant(str) ("" + str + "") diff --git a/code/__HELPERS/~monkestation-helpers/logging.dm b/code/__HELPERS/~monkestation-helpers/logging.dm deleted file mode 100644 index 405d31d65f71..000000000000 --- a/code/__HELPERS/~monkestation-helpers/logging.dm +++ /dev/null @@ -1,4 +0,0 @@ -/// Logging for borer evolutions -/proc/log_borer_evolution(text) - if (CONFIG_GET(flag/log_uplink)) - WRITE_LOG(GLOB.world_uplink_log, "BORER EVOLUTION: [text]") diff --git a/code/datums/components/squashable.dm b/code/datums/components/squashable.dm index a8304320bdbd..b1661ab73c36 100644 --- a/code/datums/components/squashable.dm +++ b/code/datums/components/squashable.dm @@ -37,6 +37,8 @@ return var/mob/living/parent_as_living = parent + if((squash_flags & SQUASHED_DONT_SQUASH_IN_CONTENTS) && !isturf(parent_as_living.loc)) + return if(squash_flags & SQUASHED_SHOULD_BE_DOWN && parent_as_living.body_position != LYING_DOWN) return diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm new file mode 100644 index 000000000000..75db1c759a65 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm @@ -0,0 +1,41 @@ +// Parent of all borer actions +/datum/action/cooldown/borer + button_icon = 'monkestation/code/modules/antagonists/borers/icons/actions.dmi' + cooldown_time = 0 + /// How many chemicals this costs + var/chemical_cost = 0 + /// How many chem evo points are needed to use this ability + var/chemical_evo_points = 0 + /// How many stat evo points are needed to use this ability + var/stat_evo_points = 0 + +/datum/action/cooldown/borer/New(Target, original) + . = ..() + var/compiled_string = "" + if(chemical_cost) + compiled_string += "([chemical_cost] chemical[chemical_cost == 1 ? "" : "s"])" + if(chemical_evo_points) + compiled_string += " ([chemical_evo_points] chemical point[chemical_evo_points == 1 ? "" : "s"])" + if(stat_evo_points) + compiled_string += " ([stat_evo_points] stat point[stat_evo_points == 1 ? "" : "s"])" + name = "[initial(name)][compiled_string]" + +/datum/action/cooldown/borer/Trigger(trigger_flags, atom/target) + . = ..() + if(!iscorticalborer(owner)) + to_chat(owner, span_warning("You must be a cortical borer to use this action!")) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(owner.stat == DEAD) + return FALSE + if(cortical_owner.chemical_storage < chemical_cost) + cortical_owner.balloon_alert(cortical_owner, "need [chemical_cost] chemicals") + return FALSE + if(cortical_owner.chemical_evolution < chemical_evo_points) + cortical_owner.balloon_alert(cortical_owner, "need [chemical_evo_points] chemical points") + return FALSE + if(cortical_owner.stat_evolution < stat_evo_points) + cortical_owner.balloon_alert(cortical_owner, "need [stat_evo_points] stat points") + return FALSE + + return . == FALSE ? FALSE : TRUE //. can be null, true, or false. There's a difference between null and false here diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm new file mode 100644 index 000000000000..6982956805c8 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm @@ -0,0 +1,19 @@ +/datum/action/cooldown/borer/gain_evolution_point + name = "DEBUG: Gain an evolution point" + button_icon_state = "level" + +/datum/action/cooldown/borer/gain_evolution_point/Trigger(trigger_flags, atom/target) + . = ..() + var/mob/living/basic/cortical_borer/cortical_owner = owner + cortical_owner.stat_evolution++ + to_chat(src, span_notice("You gain a stat evolution point. Spend it to become stronger!")) + +/datum/action/cooldown/borer/gain_chemical_point + name = "DEBUG: Gain maximum possible chemicals" + button_icon_state = "level" + +/datum/action/cooldown/borer/gain_chemical_point/Trigger(trigger_flags, atom/target) + . = ..() + var/mob/living/basic/cortical_borer/cortical_owner = owner + cortical_owner.chemical_evolution++ + to_chat(src, span_notice("You gain a chemical evolution point. Spend it to learn a new chemical!")) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm b/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm new file mode 100644 index 000000000000..a0106cd7d21b --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm @@ -0,0 +1,101 @@ +/// How many of OUR chemicals do we need to spend to inject 1 unit worth of chemicals being injected +#define CHEMICALS_PER_UNIT 2 +/// How long will the cooldown on injection be, per chemical injected? example: 10 chemicals injected, 5 second divisor = 2 seconds +#define CHEMICAL_SECOND_DIVISOR (5 SECONDS) + +/** + * Lets the borer inject chemicals from the "known_chemicals" list into the host + */ +/datum/action/cooldown/borer/inject_chemical + name = "Open Chemical Injector" + button_icon_state = "chemical" + +/datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!cortical_owner.human_host) + owner.balloon_alert(owner, "host required") + return + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + ui_interact(owner) + +/datum/action/cooldown/borer/inject_chemical/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BorerChem", name) + ui.open() + +/datum/action/cooldown/borer/inject_chemical/ui_data(mob/user) + var/list/data = list() + var/mob/living/basic/cortical_borer/cortical_owner = owner + data["amount"] = cortical_owner.injection_rate_current + data["energy"] = cortical_owner.chemical_storage / CHEMICALS_PER_UNIT + data["maxEnergy"] = cortical_owner.max_chemical_storage / CHEMICALS_PER_UNIT + data["borerTransferAmounts"] = cortical_owner.injection_rates_unlocked + data["onCooldown"] = !COOLDOWN_FINISHED(cortical_owner, injection_cooldown) + data["notEnoughChemicals"] = ((cortical_owner.injection_rate_current * CHEMICALS_PER_UNIT) > cortical_owner.chemical_storage) ? TRUE : FALSE + + var/chemicals[0] + for(var/reagent in cortical_owner.known_chemicals) + var/datum/reagent/temp = GLOB.chemical_reagents_list[reagent] + if(temp) + var/chemname = temp.name + chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name)))) + data["chemicals"] = chemicals + + return data + +/datum/action/cooldown/borer/inject_chemical/ui_act(action, params) + . = ..() + if(.) + return + var/mob/living/basic/cortical_borer/cortical_owner = owner + switch(action) + if("amount") + var/target = text2num(params["target"]) + if(target in cortical_owner.injection_rates) + cortical_owner.injection_rate_current = target + . = TRUE + if("inject") + if(!iscorticalborer(usr) || !COOLDOWN_FINISHED(cortical_owner, injection_cooldown)) + return + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + var/reagent_name = params["reagent"] + 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) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + . = TRUE + +/datum/action/cooldown/borer/inject_chemical/ui_state(mob/user) + return GLOB.always_state + +/datum/action/cooldown/borer/inject_chemical/ui_status(mob/user, datum/ui_state/state) + if(!iscorticalborer(user)) + return UI_CLOSE + + var/mob/living/basic/cortical_borer/borer = user + + if(!borer.human_host) + return UI_CLOSE + return ..() + +#undef CHEMICALS_PER_UNIT +#undef CHEMICAL_SECOND_DIVISOR diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm new file mode 100644 index 000000000000..8f659ccefe6b --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -0,0 +1,107 @@ +//to either get inside, or out, of a host +/datum/action/cooldown/borer/choosing_host + name = "Inhabit/Uninhabit Host" + cooldown_time = 10 SECONDS + button_icon_state = "host" + +/datum/action/cooldown/borer/choosing_host/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + + //having a host means we need to leave them then + if(cortical_owner.human_host) + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + owner.balloon_alert(owner, "detached from host") + 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.organs + //log the interaction + var/turf/human_turfone = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] left [key_name(cortical_owner.human_host)] at [loc_name(human_turfone)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + if(borer_organ) + borer_organ.Remove(cortical_owner.human_host) + cortical_owner.forceMove(human_turfone) + cortical_owner.human_host = null + StartCooldown() + return + + //we dont have a host so lets inhabit one + var/list/usable_hosts = list() + for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) + // no non-human hosts + if(!ishuman(listed_human) || ismonkey(listed_human)) + continue + // cannot have multiple borers (for now) + if(listed_human.has_borer()) + continue + // hosts need to be organic + if(!(listed_human.dna.species.inherent_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) + continue + // hosts need to be organic + if(!(listed_human.mob_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) + continue + //hosts cannot be changelings + if(listed_human.mind) + var/datum/antagonist/changeling/changeling = listed_human.mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling && cortical_owner.changeling_restricted) + continue + usable_hosts += listed_human + + //if the list of possible hosts is one, just go straight in, no choosing + if(length(usable_hosts) == 1) + enter_host(usable_hosts[1]) + return + + //if the list of possible host is more than one, allow choosing a host + var/choose_host = tgui_input_list(cortical_owner, "Choose your host!", "Host Choice", usable_hosts) + if(!choose_host) + owner.balloon_alert(owner, "no target selected") + return + enter_host(choose_host) + +/datum/action/cooldown/borer/choosing_host/proc/enter_host(mob/living/carbon/human/singular_host) + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(check_for_bio_protection(singular_host)) + owner.balloon_alert(owner, "target head too protected!") + return + if(singular_host.has_borer()) + owner.balloon_alert(owner, "target already occupied") + return + 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) + owner.balloon_alert(owner, "target too far away") + return + cortical_owner.human_host = singular_host + cortical_owner.forceMove(cortical_owner.human_host) + 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 + borer_organ.Insert(cortical_owner.human_host) + var/turf/human_turftwo = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] went into [key_name(cortical_owner.human_host)] at [loc_name(human_turftwo)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + StartCooldown() + +/// Checks if the target's head is bio protected, returns true if this is the case +/datum/action/cooldown/borer/choosing_host/proc/check_for_bio_protection(mob/living/carbon/human/target) + if(isobj(target.head)) + if(target.head.get_armor_rating(BIO) >= 100) + return TRUE + if(isobj(target.wear_mask)) + if(target.wear_mask.get_armor_rating(BIO) >= 100) + return TRUE + if(isobj(target.wear_neck)) + if(target.wear_neck.get_armor_rating(BIO) >= 100) + return TRUE + return FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm b/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm new file mode 100644 index 000000000000..3f992efd00fe --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm @@ -0,0 +1,87 @@ +/datum/action/cooldown/borer/evolution_tree + name = "Open Evolution Tree" + button_icon_state = "newability" + +/datum/action/cooldown/borer/evolution_tree/Trigger(trigger_flags, atom/target) + . = ..() + 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/basic/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/basic/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 + + 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 diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm new file mode 100644 index 000000000000..3a0ea8b81210 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm @@ -0,0 +1,32 @@ +/datum/action/cooldown/borer/force_speak + name = "Force Host Speak" + cooldown_time = 30 SECONDS + button_icon_state = "speak" + +/datum/action/cooldown/borer/force_speak/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(!cortical_owner.inside_human()) + owner.balloon_alert(owner, "must be in a host") + return + var/borer_message = input(cortical_owner, "What would you like to force your host to say?", "Force Speak") as message|null + if(!borer_message) + owner.balloon_alert(owner, "no message given") + return + borer_message = sanitize(borer_message) + var/mob/living/carbon/human/cortical_host = cortical_owner.human_host + to_chat(cortical_host, span_boldwarning("Your voice moves without your permission!")) + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + 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)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm b/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm new file mode 100644 index 000000000000..30ffd863caf7 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm @@ -0,0 +1,28 @@ +/datum/action/cooldown/borer/stealth_mode + name = "Stealth Mode" + cooldown_time = 2 MINUTES + button_icon_state = "hiding" + chemical_cost = 100 + +/datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags, atom/target) + var/mob/living/basic/cortical_borer/cortical_owner = owner + var/in_stealth = (cortical_owner.upgrade_flags & BORER_STEALTH_MODE) + if(in_stealth) + chemical_cost = 0 + else + chemical_cost = initial(chemical_cost) + . = ..() + if(!.) + return FALSE + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + owner.balloon_alert(owner, "stealth mode [in_stealth ? "disabled" : "enabled"]") + cortical_owner.chemical_storage -= chemical_cost + if(in_stealth) + cortical_owner.upgrade_flags &= ~BORER_STEALTH_MODE + else + cortical_owner.upgrade_flags |= BORER_STEALTH_MODE + + + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm b/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm new file mode 100644 index 000000000000..fc05c80e5fd6 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm @@ -0,0 +1,19 @@ +/datum/action/cooldown/borer/check_blood + name = "Check Blood" + cooldown_time = 5 SECONDS + button_icon_state = "blood" + +/datum/action/cooldown/borer/check_blood/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(!cortical_owner.human_host) + owner.balloon_alert(owner, "host required") + return + healthscan(owner, cortical_owner.human_host, advanced = TRUE) // :thinking: + chemscan(owner, cortical_owner.human_host) + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm b/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm new file mode 100644 index 000000000000..1d14f2421faa --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm @@ -0,0 +1,61 @@ +/datum/action/cooldown/borer/fear_human + name = "Incite Fear" + cooldown_time = 12 SECONDS + button_icon_state = "fear" + +/datum/action/cooldown/borer/fear_human/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(cortical_owner.human_host) + incite_internal_fear() + StartCooldown() + return + var/list/potential_freezers = list() + for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) + if(!ishuman(listed_human)) //no nonhuman hosts + continue + if(listed_human.stat == DEAD) //no dead hosts + continue + if(considered_afk(listed_human.mind)) //no afk hosts + continue + potential_freezers += listed_human + if(length(potential_freezers) == 1) + incite_fear(potential_freezers[1]) + return + var/mob/living/carbon/human/choose_fear = tgui_input_list(cortical_owner, "Choose who you will fear!", "Fear Choice", potential_freezers) + if(!choose_fear) + owner.balloon_alert(owner, "no target chosen") + return + if(get_dist(choose_fear, cortical_owner) > 1) + owner.balloon_alert(owner, "chosen target too far") + return + incite_fear(choose_fear) + StartCooldown() + +/datum/action/cooldown/borer/fear_human/proc/incite_fear(mob/living/carbon/human/singular_fear) + var/mob/living/basic/cortical_borer/cortical_owner = owner + to_chat(singular_fear, span_warning("Something glares menacingly at you!")) + singular_fear.Paralyze(7 SECONDS) + singular_fear.stamina.adjust(-50) + singular_fear.set_confusion_if_lower(9 SECONDS) + var/turf/human_turf = get_turf(singular_fear) + var/logging_text = "[key_name(cortical_owner)] feared/paralyzed [key_name(singular_fear)] at [loc_name(human_turf)]" + cortical_owner.log_message(logging_text, LOG_GAME) + singular_fear.log_message(logging_text, LOG_GAME) + +/datum/action/cooldown/borer/fear_human/proc/incite_internal_fear() + var/mob/living/basic/cortical_borer/cortical_owner = owner + owner.balloon_alert(owner, "fear incited into host") + cortical_owner.human_host.Paralyze(10 SECONDS) + cortical_owner.human_host.stamina.adjust(-100) + cortical_owner.human_host.set_confusion_if_lower(15 SECONDS) + to_chat(cortical_owner.human_host, span_warning("Something moves inside of you violently!")) + var/turf/human_turf = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] feared/paralyzed [key_name(cortical_owner.human_host)] (internal) at [loc_name(human_turf)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm new file mode 100644 index 000000000000..857b9c0f5926 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -0,0 +1,99 @@ +/// If a borer learns this amount of chemicals from blood, it will count for their objective +#define BLOOD_CHEM_OBJECTIVE 3 + +/// How many chemicals does a borer need to count for the objective. We use this exclusivelly for text on the end-round-panel +GLOBAL_VAR_INIT(objective_blood_chem, 3) + +/// Whats the borers progress on getting the chemical objective done? +GLOBAL_VAR_INIT(successful_blood_chem, 0) + +/// How many borers should have to learn "objective_blood_chem" amount of chemicals before we count the objective as complete +GLOBAL_VAR_INIT(objective_blood_borer, 3) + +/** + * Lets borers learn pre-coded chemicals in the "potential_chemicals" list + */ +/datum/action/cooldown/borer/upgrade_chemical + name = "Learn New Chemical" + button_icon_state = "bloodlevel" + chemical_evo_points = 1 + +/datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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(!length(cortical_owner.potential_chemicals)) + owner.balloon_alert(owner, "all chemicals learned") + return + var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.potential_chemicals) + if(!reagent_choice) + owner.balloon_alert(owner, "no chemical chosen") + return + cortical_owner.chemical_evolution -= chemical_evo_points + cortical_owner.known_chemicals += reagent_choice + cortical_owner.potential_chemicals -= reagent_choice + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) + owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") + if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) + to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) + StartCooldown() + +/** + * Lets borers learn chemicals that the host they reside in currently possess unless its in the "blacklisted_chemicals" list + * This ability is required for one of the borer's objectives + */ +/datum/action/cooldown/borer/learn_bloodchemical + name = "Learn Chemical from Blood" + button_icon_state = "bloodchem" + chemical_evo_points = 5 + +/datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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(length(cortical_owner.human_host.reagents.reagent_list) <= 0) + owner.balloon_alert(owner, "no reagents in host") + return + var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.human_host.reagents.reagent_list) + if(!reagent_choice) + owner.balloon_alert(owner, "chemical not chosen") + return + if(locate(reagent_choice) in cortical_owner.known_chemicals) + owner.balloon_alert(owner, "chemical already known") + return + if(locate(reagent_choice) in cortical_owner.blacklisted_chemicals) + owner.balloon_alert(owner, "chemical blacklisted") + return + if(!(reagent_choice.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) + owner.balloon_alert(owner, "cannot learn [initial(reagent_choice.name)]") + return + cortical_owner.chemical_evolution -= chemical_evo_points + cortical_owner.known_chemicals += reagent_choice.type + cortical_owner.blood_chems_learned++ + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) + if(cortical_owner.blood_chems_learned == BLOOD_CHEM_OBJECTIVE) + GLOB.successful_blood_chem += 1 + owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") + if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) + to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) + StartCooldown() + +#undef BLOOD_CHEM_OBJECTIVE diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm new file mode 100644 index 000000000000..a0b89f1b6e00 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm @@ -0,0 +1,36 @@ +/datum/action/cooldown/borer/learn_focus + name = "Learn Focus" + button_icon_state = "getfocus" + +/datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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(!length(cortical_owner.possible_focuses)) + owner.balloon_alert(owner, "all focuses already learned") + return + var/list/fancy_list = list() + for(var/datum/borer_focus/foci as anything in cortical_owner.possible_focuses) + if(foci in cortical_owner.body_focuses) + continue + fancy_list["[foci.name] ([foci.cost] points)"] = foci + var/focus_choice = tgui_input_list(cortical_owner, "Learn a focus!", "Focus Choice", fancy_list) + if(!focus_choice) + owner.balloon_alert(owner, "focus not chosen") + return + var/datum/borer_focus/picked_focus = fancy_list[focus_choice] + if(cortical_owner.stat_evolution < picked_focus.cost) + owner.balloon_alert(owner, "[picked_focus.cost] points required") + return + cortical_owner.stat_evolution -= picked_focus.cost + cortical_owner.body_focuses += picked_focus + picked_focus.on_add(cortical_owner.human_host, owner) + owner.balloon_alert(owner, "focus learned successfully") + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm new file mode 100644 index 000000000000..3c460a927894 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm @@ -0,0 +1,39 @@ +//revive your host +/datum/action/cooldown/borer/revive_host + name = "Revive Host" + cooldown_time = 2 MINUTES + button_icon_state = "revive" + chemical_cost = 200 + +/datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(!cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + cortical_owner.chemical_storage -= chemical_cost + if(cortical_owner.human_host.getBruteLoss()) + cortical_owner.human_host.adjustBruteLoss(-(cortical_owner.human_host.getBruteLoss()*0.5)) + if(cortical_owner.human_host.getToxLoss()) + cortical_owner.human_host.adjustToxLoss(-(cortical_owner.human_host.getToxLoss()*0.5)) + if(cortical_owner.human_host.getFireLoss()) + cortical_owner.human_host.adjustFireLoss(-(cortical_owner.human_host.getFireLoss()*0.5)) + if(cortical_owner.human_host.getOxyLoss()) + cortical_owner.human_host.adjustOxyLoss(-(cortical_owner.human_host.getOxyLoss()*0.5)) + if(cortical_owner.human_host.blood_volume < BLOOD_VOLUME_BAD) + cortical_owner.human_host.blood_volume = BLOOD_VOLUME_BAD + for(var/obj/item/organ/internal/internal_target in cortical_owner.human_host.organs) + internal_target.apply_organ_damage(-internal_target.damage * 0.5) + cortical_owner.human_host.revive() + to_chat(cortical_owner.human_host, span_boldwarning("Your heart jumpstarts!")) + owner.balloon_alert(owner, "host revived") + var/turf/human_turf = get_turf(cortical_owner.human_host) + var/logging_text = "[key_name(cortical_owner)] revived [key_name(cortical_owner.human_host)] at [loc_name(human_turf)]" + cortical_owner.log_message(logging_text, LOG_GAME) + cortical_owner.human_host.log_message(logging_text, LOG_GAME) + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm new file mode 100644 index 000000000000..b1524ae135f4 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -0,0 +1,102 @@ +#define OUT_OF_HOST_EGG_COST 50 + +//we need a way to produce offspring +/datum/action/cooldown/borer/produce_offspring + name = "Produce Offspring" + cooldown_time = 1 MINUTES + button_icon_state = "reproduce" + chemical_cost = 100 + +/datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!(cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + cortical_owner.chemical_storage -= chemical_cost + 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.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25 * cortical_owner.host_harm_multiplier) + var/eggroll = rand(1,100) + if(eggroll <= 75) + switch(eggroll) + if(1 to 34) + cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_BASIC) + if(35 to 60) + cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY) + if(61 to 71) + cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_SURGERY) + 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)]" + cortical_owner.log_message(logging_text, LOG_GAME) + owner.balloon_alert(owner, "egg laid") + StartCooldown() + +/datum/action/cooldown/borer/produce_offspring/proc/no_host_egg() + var/mob/living/basic/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/basic/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 + +#undef OUT_OF_HOST_EGG_COST + +/datum/action/cooldown/borer/empowered_offspring + name = "Produce Empowered Offspring" + cooldown_time = 1 MINUTES + button_icon_state = "reproduce" + chemical_cost = 150 + +/datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + if(cortical_owner.human_host.stat != DEAD) + owner.balloon_alert(owner, "host not dead") + return + + cortical_owner.chemical_storage -= chemical_cost + var/turf/borer_turf = get_turf(cortical_owner) + var/obj/item/bodypart/chest/chest = cortical_owner.human_host.get_bodypart(BODY_ZONE_CHEST) + if((!chest || IS_ORGANIC_LIMB(chest)) && !cortical_owner.human_host.get_organ_by_type(/obj/item/organ/internal/empowered_borer_egg)) + var/obj/item/organ/internal/empowered_borer_egg/spawned_egg = new(cortical_owner.human_host) + spawned_egg.generation = (cortical_owner.generation + 1) + + cortical_owner.children_produced += 1 + 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) + cortical_owner.balloon_alert(owner, "egg laid") + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm new file mode 100644 index 000000000000..370d5a565ab3 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm @@ -0,0 +1,23 @@ +/** + * Allows you to hide under tables or bodies + * Without this, borers are really weak due to NEEDING players being blind or consenting + */ +/datum/action/cooldown/borer/toggle_hiding + name = "Toggle Hiding" + button_icon_state = "hide" + +/datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm new file mode 100644 index 000000000000..7e9afd726991 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm @@ -0,0 +1,29 @@ +/datum/action/cooldown/borer/upgrade_stat + name = "Become Stronger" + button_icon_state = "level" + stat_evo_points = 1 + +/datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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 + cortical_owner.stat_evolution -= stat_evo_points + 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 + cortical_owner.level += 1 + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) + if(victim_brain) + cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10 * cortical_owner.host_harm_multiplier) + cortical_owner.human_host.adjust_eye_blur(6 SECONDS * 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() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm new file mode 100644 index 000000000000..d62baabdb1fb --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm @@ -0,0 +1,32 @@ +/datum/action/cooldown/borer/willing_host + name = "Willing Host" + cooldown_time = 2 MINUTES + button_icon_state = "willing" + chemical_cost = 150 + +/datum/action/cooldown/borer/willing_host/Trigger(trigger_flags, atom/target) + . = ..() + if(!.) + return FALSE + var/mob/living/basic/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 + for(var/ckey_check in GLOB.willing_hosts) + if(ckey_check == cortical_owner.human_host.ckey) + owner.balloon_alert(owner, "host already willing") + return + owner.balloon_alert(owner, "asking host...") + cortical_owner.chemical_storage -= chemical_cost + var/host_choice = tgui_input_list(cortical_owner.human_host,"Do you accept to be a willing host?", "Willing Host Request", list("Yes", "No")) + if(host_choice != "Yes") + owner.balloon_alert(owner, "host not willing!") + StartCooldown() + return + owner.balloon_alert(owner, "host willing!") + to_chat(cortical_owner.human_host, span_notice("You have accepted being a willing host!")) + GLOB.willing_hosts += cortical_owner.human_host.ckey + StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm index 709f49df15dc..facfbd3b84ac 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm @@ -1,12 +1,9 @@ GLOBAL_VAR_INIT(objective_egg_borer_number, 2) GLOBAL_VAR_INIT(objective_egg_egg_number, 5) GLOBAL_VAR_INIT(objective_willing_hosts, 2) -GLOBAL_VAR_INIT(objective_blood_chem, 3) -GLOBAL_VAR_INIT(objective_blood_borer, 3) GLOBAL_VAR_INIT(successful_egg_number, 0) GLOBAL_LIST_EMPTY(willing_hosts) -GLOBAL_VAR_INIT(successful_blood_chem, 0) GLOBAL_LIST_EMPTY(cortical_borers) @@ -64,7 +61,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) . = ..() for(var/datum/borer_focus/body_focus as anything in borer.body_focuses) body_focus.on_add() - carbon_target.hal_screwyhud = SCREWYHUD_HEALTHY + carbon_target.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) //on removal, force the borer out /obj/item/organ/internal/borer_body/Remove(mob/living/carbon/carbon_target, special) @@ -74,7 +71,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) body_focus.on_remove() if(cb_inside) cb_inside.leave_host() - carbon_target.hal_screwyhud = SCREWYHUD_NONE + carbon_target.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) qdel(src) /obj/item/reagent_containers/borer @@ -102,29 +99,30 @@ GLOBAL_LIST_EMPTY(cortical_borers) ///what chemicals borers know, starting with none var/list/known_chemicals = list() ///what chemicals the borer can learn - var/list/potential_chemicals = list(/datum/reagent/medicine/spaceacillin, - /datum/reagent/medicine/potass_iodide, - /datum/reagent/medicine/diphenhydramine, - /datum/reagent/medicine/epinephrine, - /datum/reagent/medicine/haloperidol, - /datum/reagent/toxin/formaldehyde, - /datum/reagent/impurity/libitoil, - /datum/reagent/impurity/mannitol, - /datum/reagent/medicine/c2/libital, - /datum/reagent/medicine/c2/lenturi, - /datum/reagent/medicine/c2/convermol, - /datum/reagent/medicine/c2/seiver, - /datum/reagent/medicine/c2/multiver, - /datum/reagent/lithium, - /datum/reagent/medicine/salglu_solution, - /datum/reagent/medicine/mutadone, - /datum/reagent/toxin/heparin, - /datum/reagent/drug/methamphetamine/borer_version, - /datum/reagent/medicine/morphine, - /datum/reagent/medicine/inacusiate, - /datum/reagent/medicine/oculine, - /datum/reagent/toxin/mindbreaker, - /datum/reagent/medicine/mannitol, + var/list/potential_chemicals = list( + /datum/reagent/medicine/antipathogenic/spaceacillin, + /datum/reagent/medicine/potass_iodide, + /datum/reagent/medicine/diphenhydramine, + /datum/reagent/medicine/epinephrine, + /datum/reagent/medicine/haloperidol, + /datum/reagent/toxin/formaldehyde, + /datum/reagent/impurity/libitoil, + /datum/reagent/impurity/mannitol, + /datum/reagent/medicine/c2/libital, + /datum/reagent/medicine/c2/lenturi, + /datum/reagent/medicine/c2/convermol, + /datum/reagent/medicine/c2/seiver, + /datum/reagent/medicine/c2/multiver, + /datum/reagent/lithium, + /datum/reagent/medicine/salglu_solution, + /datum/reagent/medicine/mutadone, + /datum/reagent/toxin/heparin, + /datum/reagent/drug/methamphetamine/borer_version, + /datum/reagent/medicine/morphine, + /datum/reagent/medicine/inacusiate, + /datum/reagent/medicine/oculine, + /datum/reagent/toxin/mindbreaker, + /datum/reagent/medicine/mannitol, ) //blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these var/list/blacklisted_chemicals = list() //currently may be empty, but leaving the mechanism just in case @@ -151,16 +149,17 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// 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/force_speak, - /datum/action/cooldown/borer/fear_human, - /datum/action/cooldown/borer/check_blood, + 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/force_speak, + /datum/action/cooldown/borer/fear_human, + /datum/action/cooldown/borer/check_blood, ) ///the host var/mob/living/carbon/human/human_host @@ -232,8 +231,9 @@ GLOBAL_LIST_EMPTY(cortical_borers) GLOB.cortical_borers += src reagent_holder = new /obj/item/reagent_containers/borer(src) + for(var/action_type in known_abilities) - var/datum/action/attack_action = new action_type() + var/datum/action/attack_action = new action_type(src) attack_action.Grant(src) if(mind) @@ -279,7 +279,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) . += "2) [GLOB.objective_willing_hosts] willing hosts: [length(GLOB.willing_hosts)]/[GLOB.objective_willing_hosts]" . += "3) [GLOB.objective_blood_borer] borers learning [GLOB.objective_blood_chem] chemicals from the blood: [GLOB.successful_blood_chem]/[GLOB.objective_blood_borer]" -/mob/living/basic/cortical_borer/Life(delta_time, times_fired) +/mob/living/basic/cortical_borer/Life(seconds_per_tick, times_fired) . = ..() //can only do stuff when we are inside a LIVING human if(!inside_human() || human_host?.stat == DEAD) @@ -289,8 +289,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) 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) - if(human_host.hal_screwyhud != SCREWYHUD_HEALTHY) - human_host.hal_screwyhud = SCREWYHUD_HEALTHY + human_host.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) //cant do anything if the host has sugar if(host_sugar()) @@ -346,8 +345,8 @@ GLOBAL_LIST_EMPTY(cortical_borers) return TRUE return FALSE -// Base mob environment handler for body temperature, overriden to take into consideration being inside a host -/mob/living/basic/cortical_borer/handle_environment(datum/gas_mixture/environment, delta_time, times_fired) +/// Base mob environment handler for body temperature, overridden to take into consideration being inside a host +/mob/living/basic/cortical_borer/handle_environment(datum/gas_mixture/environment, seconds_per_tick, times_fired) var/loc_temp if(human_host) loc_temp = human_host.coretemperature // set the local temp to that of the host's core temp @@ -361,9 +360,9 @@ GLOBAL_LIST_EMPTY(cortical_borers) if(temp_delta < 0) // it is cold here if(!on_fire) // do not reduce body temp when on fire - adjust_bodytemperature(max(max(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_COOLING_MAX) * delta_time, temp_delta)) + adjust_bodytemperature(max(max(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_COOLING_MAX) * seconds_per_tick, temp_delta)) else // this is a hot place - adjust_bodytemperature(min(min(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_HEATING_MAX) * delta_time, temp_delta)) + adjust_bodytemperature(min(min(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_HEATING_MAX) * seconds_per_tick, temp_delta)) //leave the host, forced or not /mob/living/basic/cortical_borer/proc/leave_host() @@ -392,6 +391,8 @@ GLOBAL_LIST_EMPTY(cortical_borers) message = scramble_message_replace_chars(message, 10) message = sanitize(message) var/list/split_message = splittext(message, "") + + //this is so they can talk in hivemind if(split_message[1] == ";") message = copytext(message, 2) for(var/borer in GLOB.cortical_borers) @@ -417,7 +418,6 @@ GLOBAL_LIST_EMPTY(cortical_borers) to_chat(src, span_warning("You cannot pull things!")) return - /// Called on Life() for the borer to age a bit /mob/living/basic/cortical_borer/proc/mature() . = TRUE diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm deleted file mode 100644 index cdde8d8bdbfd..000000000000 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_abilities.dm +++ /dev/null @@ -1,829 +0,0 @@ -#define CHEMICALS_PER_UNIT 2 -#define CHEMICAL_SECOND_DIVISOR (5 SECONDS) -#define OUT_OF_HOST_EGG_COST 50 -#define BLOOD_CHEM_OBJECTIVE 3 - -// Parent of all borer actions -/datum/action/cooldown/borer - button_icon = 'monkestation/code/modules/antagonists/borers/icons/actions.dmi' - cooldown_time = 0 - /// How many chemicals this costs - var/chemical_cost = 0 - /// How many chem evo points are needed to use this ability - var/chemical_evo_points = 0 - /// How many stat evo points are needed to use this ability - var/stat_evo_points = 0 - -/datum/action/cooldown/borer/New(Target, original) - . = ..() - var/compiled_string = "" - if(chemical_cost) - compiled_string += "([chemical_cost] chemical[chemical_cost == 1 ? "" : "s"])" - if(chemical_evo_points) - compiled_string += " ([chemical_evo_points] chemical point[chemical_evo_points == 1 ? "" : "s"])" - if(stat_evo_points) - compiled_string += " ([stat_evo_points] stat point[stat_evo_points == 1 ? "" : "s"])" - name = "[initial(name)][compiled_string]" - -/datum/action/cooldown/borer/Trigger(trigger_flags, atom/target) - . = ..() - if(!iscorticalborer(owner)) - to_chat(owner, span_warning("You must be a cortical borer to use this action!")) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(owner.stat == DEAD) - return FALSE - if(cortical_owner.chemical_storage < chemical_cost) - cortical_owner.balloon_alert(cortical_owner, "need [chemical_cost] chemicals") - return FALSE - if(cortical_owner.chemical_evolution < chemical_evo_points) - cortical_owner.balloon_alert(cortical_owner, "need [chemical_evo_points] chemical points") - return FALSE - if(cortical_owner.stat_evolution < stat_evo_points) - cortical_owner.balloon_alert(cortical_owner, "need [stat_evo_points] stat points") - return FALSE - - return . == FALSE ? FALSE : TRUE //. can be null, true, or false. There's a difference between null and false here - -//inject chemicals into your host -/datum/action/cooldown/borer/inject_chemical - name = "Open Chemical Injector" - button_icon_state = "chemical" - -/datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(!cortical_owner.human_host) - owner.balloon_alert(owner, "host required") - return - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - ui_interact(owner) - -/datum/action/cooldown/borer/inject_chemical/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "BorerChem", name) - ui.open() - -/datum/action/cooldown/borer/inject_chemical/ui_data(mob/user) - var/list/data = list() - var/mob/living/basic/cortical_borer/cortical_owner = owner - data["amount"] = cortical_owner.injection_rate_current - data["energy"] = cortical_owner.chemical_storage / CHEMICALS_PER_UNIT - data["maxEnergy"] = cortical_owner.max_chemical_storage / CHEMICALS_PER_UNIT - data["borerTransferAmounts"] = cortical_owner.injection_rates_unlocked - data["onCooldown"] = !COOLDOWN_FINISHED(cortical_owner, injection_cooldown) - data["notEnoughChemicals"] = ((cortical_owner.injection_rate_current * CHEMICALS_PER_UNIT) > cortical_owner.chemical_storage) ? TRUE : FALSE - - var/chemicals[0] - for(var/reagent in cortical_owner.known_chemicals) - var/datum/reagent/temp = GLOB.chemical_reagents_list[reagent] - if(temp) - var/chemname = temp.name - chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name)))) - data["chemicals"] = chemicals - - return data - -/datum/action/cooldown/borer/inject_chemical/ui_act(action, params) - . = ..() - if(.) - return - var/mob/living/basic/cortical_borer/cortical_owner = owner - switch(action) - if("amount") - var/target = text2num(params["target"]) - if(target in cortical_owner.injection_rates) - cortical_owner.injection_rate_current = target - . = TRUE - if("inject") - if(!iscorticalborer(usr) || !COOLDOWN_FINISHED(cortical_owner, injection_cooldown)) - return - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - var/reagent_name = params["reagent"] - 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) - cortical_owner.human_host.log_message(logging_text, LOG_GAME) - . = TRUE - -/datum/action/cooldown/borer/inject_chemical/ui_state(mob/user) - return GLOB.always_state - -/datum/action/cooldown/borer/inject_chemical/ui_status(mob/user, datum/ui_state/state) - if(!iscorticalborer(user)) - return UI_CLOSE - - var/mob/living/basic/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, atom/target) - . = ..() - 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/basic/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/basic/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" - -/datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/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(!length(cortical_owner.possible_focuses)) - owner.balloon_alert(owner, "all focuses already learned") - return - var/list/fancy_list = list() - for(var/datum/borer_focus/foci as anything in cortical_owner.possible_focuses) - if(foci in cortical_owner.body_focuses) - continue - fancy_list["[foci.name] ([foci.cost] points)"] = foci - var/focus_choice = tgui_input_list(cortical_owner, "Learn a focus!", "Focus Choice", fancy_list) - if(!focus_choice) - owner.balloon_alert(owner, "focus not chosen") - return - var/datum/borer_focus/picked_focus = fancy_list[focus_choice] - if(cortical_owner.stat_evolution < picked_focus.cost) - owner.balloon_alert(owner, "[picked_focus.cost] points required") - return - cortical_owner.stat_evolution -= picked_focus.cost - cortical_owner.body_focuses += picked_focus - picked_focus.on_add(cortical_owner.human_host, owner) - owner.balloon_alert(owner, "focus learned successfully") - StartCooldown() - -/datum/action/cooldown/borer/learn_bloodchemical - name = "Learn Chemical from Blood" - button_icon_state = "bloodchem" - chemical_evo_points = 5 - -/datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/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(length(cortical_owner.human_host.reagents.reagent_list) <= 0) - owner.balloon_alert(owner, "no reagents in host") - return - var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.human_host.reagents.reagent_list) - if(!reagent_choice) - owner.balloon_alert(owner, "chemical not chosen") - return - if(locate(reagent_choice) in cortical_owner.known_chemicals) - owner.balloon_alert(owner, "chemical already known") - return - if(locate(reagent_choice) in cortical_owner.blacklisted_chemicals) - owner.balloon_alert(owner, "chemical blacklisted") - return - if(!(reagent_choice.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) - owner.balloon_alert(owner, "cannot learn [initial(reagent_choice.name)]") - return - cortical_owner.chemical_evolution -= chemical_evo_points - cortical_owner.known_chemicals += reagent_choice.type - cortical_owner.blood_chems_learned++ - var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) - if(victim_brain) - cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) - if(cortical_owner.blood_chems_learned == BLOOD_CHEM_OBJECTIVE) - GLOB.successful_blood_chem += 1 - owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") - if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) - to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) - StartCooldown() - -//become stronger by learning new chemicals -/datum/action/cooldown/borer/upgrade_chemical - name = "Learn New Chemical" - button_icon_state = "bloodlevel" - chemical_evo_points = 1 - -/datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/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(!length(cortical_owner.potential_chemicals)) - owner.balloon_alert(owner, "all chemicals learned") - return - var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.potential_chemicals) - if(!reagent_choice) - owner.balloon_alert(owner, "no chemical chosen") - return - cortical_owner.chemical_evolution -= chemical_evo_points - cortical_owner.known_chemicals += reagent_choice - cortical_owner.potential_chemicals -= reagent_choice - var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) - if(victim_brain) - cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) - owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") - if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) - to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) - StartCooldown() - -//become stronger by affecting the stats -/datum/action/cooldown/borer/upgrade_stat - name = "Become Stronger" - button_icon_state = "level" - stat_evo_points = 1 - -/datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/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 - cortical_owner.stat_evolution -= stat_evo_points - 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 - cortical_owner.level += 1 - var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) - if(victim_brain) - cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10 * cortical_owner.host_harm_multiplier) - cortical_owner.human_host.adjust_eye_blur(6 SECONDS * 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() - -//go between either hiding behind tables or behind mobs -/datum/action/cooldown/borer/toggle_hiding - name = "Toggle Hiding" - button_icon_state = "hide" - -/datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/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() - -//to paralyze people -/datum/action/cooldown/borer/fear_human - name = "Incite Fear" - cooldown_time = 12 SECONDS - button_icon_state = "fear" - -/datum/action/cooldown/borer/fear_human/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(cortical_owner.human_host) - incite_internal_fear() - StartCooldown() - return - var/list/potential_freezers = list() - for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) - if(!ishuman(listed_human)) //no nonhuman hosts - continue - if(listed_human.stat == DEAD) //no dead hosts - continue - if(considered_afk(listed_human.mind)) //no afk hosts - continue - potential_freezers += listed_human - if(length(potential_freezers) == 1) - incite_fear(potential_freezers[1]) - return - var/mob/living/carbon/human/choose_fear = tgui_input_list(cortical_owner, "Choose who you will fear!", "Fear Choice", potential_freezers) - if(!choose_fear) - owner.balloon_alert(owner, "no target chosen") - return - if(get_dist(choose_fear, cortical_owner) > 1) - owner.balloon_alert(owner, "chosen target too far") - return - incite_fear(choose_fear) - StartCooldown() - -/datum/action/cooldown/borer/fear_human/proc/incite_fear(mob/living/carbon/human/singular_fear) - var/mob/living/basic/cortical_borer/cortical_owner = owner - to_chat(singular_fear, span_warning("Something glares menacingly at you!")) - singular_fear.Paralyze(7 SECONDS) - singular_fear.adjustStaminaLoss(50) - singular_fear.set_confusion_if_lower(9 SECONDS) - var/turf/human_turf = get_turf(singular_fear) - var/logging_text = "[key_name(cortical_owner)] feared/paralyzed [key_name(singular_fear)] at [loc_name(human_turf)]" - cortical_owner.log_message(logging_text, LOG_GAME) - singular_fear.log_message(logging_text, LOG_GAME) - -/datum/action/cooldown/borer/fear_human/proc/incite_internal_fear() - var/mob/living/basic/cortical_borer/cortical_owner = owner - owner.balloon_alert(owner, "fear incited into host") - cortical_owner.human_host.Paralyze(10 SECONDS) - cortical_owner.human_host.adjustStaminaLoss(100) - cortical_owner.human_host.set_confusion_if_lower(15 SECONDS) - to_chat(cortical_owner.human_host, span_warning("Something moves inside of you violently!")) - var/turf/human_turf = get_turf(cortical_owner.human_host) - var/logging_text = "[key_name(cortical_owner)] feared/paralyzed [key_name(cortical_owner.human_host)] (internal) at [loc_name(human_turf)]" - cortical_owner.log_message(logging_text, LOG_GAME) - cortical_owner.human_host.log_message(logging_text, LOG_GAME) - -//to check the health of the human -/datum/action/cooldown/borer/check_blood - name = "Check Blood" - cooldown_time = 5 SECONDS - button_icon_state = "blood" - -/datum/action/cooldown/borer/check_blood/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(!cortical_owner.human_host) - owner.balloon_alert(owner, "host required") - return - healthscan(owner, cortical_owner.human_host, advanced = TRUE) // :thinking: - chemscan(owner, cortical_owner.human_host) - StartCooldown() - -//to either get inside, or out, of a host -/datum/action/cooldown/borer/choosing_host - name = "Inhabit/Uninhabit Host" - cooldown_time = 10 SECONDS - button_icon_state = "host" - -/datum/action/cooldown/borer/choosing_host/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - - //having a host means we need to leave them then - if(cortical_owner.human_host) - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - owner.balloon_alert(owner, "detached from host") - 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.organs - //log the interaction - var/turf/human_turfone = get_turf(cortical_owner.human_host) - var/logging_text = "[key_name(cortical_owner)] left [key_name(cortical_owner.human_host)] at [loc_name(human_turfone)]" - cortical_owner.log_message(logging_text, LOG_GAME) - cortical_owner.human_host.log_message(logging_text, LOG_GAME) - if(borer_organ) - borer_organ.Remove(cortical_owner.human_host) - cortical_owner.forceMove(human_turfone) - cortical_owner.human_host = null - StartCooldown() - return - - //we dont have a host so lets inhabit one - var/list/usable_hosts = list() - for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) - // no non-human hosts - if(!ishuman(listed_human) || ismonkey(listed_human)) - continue - // cannot have multiple borers (for now) - if(listed_human.has_borer()) - continue - // hosts need to be organic - if(!(listed_human.dna.species.inherent_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) - continue - // hosts need to be organic - if(!(listed_human.mob_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) - continue - //hosts cannot be changelings - if(listed_human.mind) - var/datum/antagonist/changeling/changeling = listed_human.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling && cortical_owner.changeling_restricted) - continue - usable_hosts += listed_human - - //if the list of possible hosts is one, just go straight in, no choosing - if(length(usable_hosts) == 1) - enter_host(usable_hosts[1]) - return - - //if the list of possible host is more than one, allow choosing a host - var/choose_host = tgui_input_list(cortical_owner, "Choose your host!", "Host Choice", usable_hosts) - if(!choose_host) - owner.balloon_alert(owner, "no target selected") - return - enter_host(choose_host) - -/datum/action/cooldown/borer/choosing_host/proc/enter_host(mob/living/carbon/human/singular_host) - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(check_for_bio_protection(singular_host)) - owner.balloon_alert(owner, "target head too protected!") - return - if(singular_host.has_borer()) - owner.balloon_alert(owner, "target already occupied") - return - 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) - owner.balloon_alert(owner, "target too far away") - return - cortical_owner.human_host = singular_host - cortical_owner.forceMove(cortical_owner.human_host) - 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 - borer_organ.Insert(cortical_owner.human_host) - var/turf/human_turftwo = get_turf(cortical_owner.human_host) - var/logging_text = "[key_name(cortical_owner)] went into [key_name(cortical_owner.human_host)] at [loc_name(human_turftwo)]" - cortical_owner.log_message(logging_text, LOG_GAME) - cortical_owner.human_host.log_message(logging_text, LOG_GAME) - StartCooldown() - -/// Checks if the target's head is bio protected, returns true if this is the case -/datum/action/cooldown/borer/choosing_host/proc/check_for_bio_protection(mob/living/carbon/human/target) - if(isobj(target.head)) - if(target.head.get_armor_rating(BIO) >= 100) - return TRUE - if(isobj(target.wear_mask)) - if(target.wear_mask.get_armor_rating(BIO) >= 100) - return TRUE - if(isobj(target.wear_neck)) - if(target.wear_neck.get_armor_rating(BIO) >= 100) - return TRUE - return FALSE - -//you can force your host to speak... dont abuse this -/datum/action/cooldown/borer/force_speak - name = "Force Host Speak" - cooldown_time = 30 SECONDS - button_icon_state = "speak" - -/datum/action/cooldown/borer/force_speak/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(!cortical_owner.inside_human()) - owner.balloon_alert(owner, "must be in a host") - return - var/borer_message = input(cortical_owner, "What would you like to force your host to say?", "Force Speak") as message|null - if(!borer_message) - owner.balloon_alert(owner, "no message given") - return - borer_message = sanitize(borer_message) - var/mob/living/carbon/human/cortical_host = cortical_owner.human_host - to_chat(cortical_host, span_boldwarning("Your voice moves without your permission!")) - var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) - if(victim_brain) - 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)]" - cortical_owner.log_message(logging_text, LOG_GAME) - cortical_owner.human_host.log_message(logging_text, LOG_GAME) - StartCooldown() - -//we need a way to produce offspring -/datum/action/cooldown/borer/produce_offspring - name = "Produce Offspring" - cooldown_time = 1 MINUTES - button_icon_state = "reproduce" - chemical_cost = 100 - -/datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(!(cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) - owner.balloon_alert(owner, "host required") - return - cortical_owner.chemical_storage -= chemical_cost - 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.get_organ_slot(ORGAN_SLOT_BRAIN) - if(victim_brain) - cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 25 * cortical_owner.host_harm_multiplier) - var/eggroll = rand(1,100) - if(eggroll <= 75) - switch(eggroll) - if(1 to 34) - cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_BASIC) - if(35 to 60) - cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY) - if(61 to 71) - cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_SURGERY) - 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)]" - cortical_owner.log_message(logging_text, LOG_GAME) - owner.balloon_alert(owner, "egg laid") - StartCooldown() - -/datum/action/cooldown/borer/produce_offspring/proc/no_host_egg() - var/mob/living/basic/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/basic/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" - cooldown_time = 2 MINUTES - button_icon_state = "revive" - chemical_cost = 200 - -/datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(!cortical_owner.inside_human()) - owner.balloon_alert(owner, "host required") - return - cortical_owner.chemical_storage -= chemical_cost - if(cortical_owner.human_host.getBruteLoss()) - cortical_owner.human_host.adjustBruteLoss(-(cortical_owner.human_host.getBruteLoss()*0.5)) - if(cortical_owner.human_host.getToxLoss()) - cortical_owner.human_host.adjustToxLoss(-(cortical_owner.human_host.getToxLoss()*0.5)) - if(cortical_owner.human_host.getFireLoss()) - cortical_owner.human_host.adjustFireLoss(-(cortical_owner.human_host.getFireLoss()*0.5)) - if(cortical_owner.human_host.getOxyLoss()) - cortical_owner.human_host.adjustOxyLoss(-(cortical_owner.human_host.getOxyLoss()*0.5)) - if(cortical_owner.human_host.blood_volume < BLOOD_VOLUME_BAD) - cortical_owner.human_host.blood_volume = BLOOD_VOLUME_BAD - for(var/obj/item/organ/internal/internal_target in cortical_owner.human_host.organs) - internal_target.applyOrganDamage(-internal_target.damage * 0.5) - cortical_owner.human_host.revive() - to_chat(cortical_owner.human_host, span_boldwarning("Your heart jumpstarts!")) - owner.balloon_alert(owner, "host revived") - var/turf/human_turf = get_turf(cortical_owner.human_host) - var/logging_text = "[key_name(cortical_owner)] revived [key_name(cortical_owner.human_host)] at [loc_name(human_turf)]" - cortical_owner.log_message(logging_text, LOG_GAME) - cortical_owner.human_host.log_message(logging_text, LOG_GAME) - StartCooldown() - -//to ask if a host is willing -/datum/action/cooldown/borer/willing_host - name = "Willing Host" - cooldown_time = 2 MINUTES - button_icon_state = "willing" - chemical_cost = 150 - -/datum/action/cooldown/borer/willing_host/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/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 - for(var/ckey_check in GLOB.willing_hosts) - if(ckey_check == cortical_owner.human_host.ckey) - owner.balloon_alert(owner, "host already willing") - return - owner.balloon_alert(owner, "asking host...") - cortical_owner.chemical_storage -= chemical_cost - var/host_choice = tgui_input_list(cortical_owner.human_host,"Do you accept to be a willing host?", "Willing Host Request", list("Yes", "No")) - if(host_choice != "Yes") - owner.balloon_alert(owner, "host not willing!") - StartCooldown() - return - owner.balloon_alert(owner, "host willing!") - to_chat(cortical_owner.human_host, span_notice("You have accepted being a willing host!")) - GLOB.willing_hosts += cortical_owner.human_host.ckey - StartCooldown() - -/datum/action/cooldown/borer/stealth_mode - name = "Stealth Mode" - cooldown_time = 2 MINUTES - button_icon_state = "hiding" - chemical_cost = 100 - -/datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags, atom/target) - var/mob/living/basic/cortical_borer/cortical_owner = owner - var/in_stealth = (cortical_owner.upgrade_flags & BORER_STEALTH_MODE) - if(in_stealth) - chemical_cost = 0 - else - chemical_cost = initial(chemical_cost) - . = ..() - if(!.) - return FALSE - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - owner.balloon_alert(owner, "stealth mode [in_stealth ? "disabled" : "enabled"]") - cortical_owner.chemical_storage -= chemical_cost - 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" - cooldown_time = 1 MINUTES - button_icon_state = "reproduce" - chemical_cost = 150 - -/datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) - . = ..() - if(!.) - return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(!cortical_owner.inside_human()) - owner.balloon_alert(owner, "host required") - return - if(cortical_owner.human_host.stat != DEAD) - owner.balloon_alert(owner, "host not dead") - return - - cortical_owner.chemical_storage -= chemical_cost - var/turf/borer_turf = get_turf(cortical_owner) - var/obj/item/bodypart/chest/chest = cortical_owner.human_host.get_bodypart(BODY_ZONE_CHEST) - if((!chest || IS_ORGANIC_LIMB(chest)) && !cortical_owner.human_host.getorgan(/obj/item/organ/internal/empowered_borer_egg)) - var/obj/item/organ/internal/empowered_borer_egg/spawned_egg = new(cortical_owner.human_host) - spawned_egg.generation = (cortical_owner.generation + 1) - - cortical_owner.children_produced += 1 - 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) - cortical_owner.balloon_alert(owner, "egg laid") - StartCooldown() - -#undef CHEMICALS_PER_UNIT -#undef CHEMICAL_SECOND_DIVISOR -#undef OUT_OF_HOST_EGG_COST -#undef BLOOD_CHEM_OBJECTIVE diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm index ef793957e59a..24675a2731d3 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm @@ -98,19 +98,21 @@ min_players = 999 max_occurrences = 1 //should only ever happen once dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "A cortical borer has appeared on station. It will also attempt to produce eggs, and will attempt to gather willing hosts and learn chemicals through the blood." /datum/round_event/ghost_role/cortical_borer - announceWhen = 400 + announce_when = 400 /datum/round_event/ghost_role/cortical_borer/setup() - announceWhen = rand(announceWhen, announceWhen + 50) + announce_when = rand(announce_when, announce_when + 50) /datum/round_event/ghost_role/cortical_borer/announce(fake) priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS) /datum/round_event/ghost_role/cortical_borer/start() var/list/vents = list() - for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) if(QDELETED(temp_vent)) continue if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) @@ -139,10 +141,10 @@ for(var/mob/dead_mob in GLOB.dead_mob_list) to_chat(dead_mob, span_notice("The cortical borers have been selected, you are able to orbit them! Remember, they can reproduce!")) -/* /datum/dynamic_ruleset/midround/from_ghosts/cortical_borer name = "Cortical Borer Infestation" antag_datum = /datum/antagonist/cortical_borer + midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT antag_flag = ROLE_BORER enemy_roles = list( JOB_CAPTAIN, @@ -154,13 +156,13 @@ required_candidates = 1 weight = 3 cost = 15 - requirements = list(101,101,101,70,50,40,20,15,10,10) + minimum_players = 20 repeatable = TRUE /// List of on-station vents var/list/vents = list() /datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/execute() - for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) if(QDELETED(temp_vent)) continue if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) @@ -173,7 +175,7 @@ vents += temp_vent if(!length(vents)) return FALSE - return ..() + return TRUE /datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/generate_ruleset_body(mob/applicant) var/obj/vent = pick_n_take(vents) @@ -183,6 +185,5 @@ message_admins("[ADMIN_LOOKUPFLW(new_borer)] has been made into a borer by the midround ruleset.") log_game("DYNAMIC: [key_name(new_borer)] was spawned as a borer by the midround ruleset.") return new_borer -*/ #undef POP_PER_BORER diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm index 7d4ef3f28f4e..cfc66ac86448 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm @@ -1,19 +1,20 @@ /datum/reagent/drug/methamphetamine/borer_version + name = "Unknown Methamphetamine Isomer" overdose_threshold = 40 -/datum/reagent/drug/methamphetamine/borer_version/on_mob_life(mob/living/carbon/M, delta_time, times_fired) +/datum/reagent/drug/methamphetamine/borer_version/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.") - if(DT_PROB(2.5, delta_time)) + if(SPT_PROB(2.5, seconds_per_tick)) to_chat(M, span_notice("[high_message]")) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "tweaking", /datum/mood_event/stimulant_medium, name) - M.AdjustStun(-40 * REM * delta_time) - M.AdjustKnockdown(-40 * REM * delta_time) - M.AdjustUnconscious(-40 * REM * delta_time) - M.AdjustParalyzed(-40 * REM * delta_time) - M.AdjustImmobilized(-40 * REM * delta_time) - M.adjustStaminaLoss(-2 * REM * delta_time, 0) - M.Jitter(2 * REM * delta_time) - if(DT_PROB(2.5, delta_time)) + M.add_mood_event("tweaking", /datum/mood_event/stimulant_medium, name) + M.AdjustStun(-40 * REM * seconds_per_tick) + M.AdjustKnockdown(-40 * REM * seconds_per_tick) + M.AdjustUnconscious(-40 * REM * seconds_per_tick) + M.AdjustParalyzed(-40 * REM * seconds_per_tick) + M.AdjustImmobilized(-40 * REM * seconds_per_tick) + M.stamina.adjust(2 * REM * seconds_per_tick, 0) + M.set_jitter_if_lower(5 SECONDS) + if(SPT_PROB(2.5, seconds_per_tick)) M.emote(pick("twitch", "shiver")) ..() . = TRUE diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm index 657cc24f632c..77d205100c12 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm @@ -20,7 +20,7 @@ /datum/borer_evolution/proc/on_evolve(mob/living/basic/cortical_borer/cortical_owner) SHOULD_CALL_PARENT(TRUE) if(gain_text) - to_chat(cortical_owner, span_notice(span_italics(gain_text))) + to_chat(cortical_owner, span_notice("[gain_text]")) if(mutually_exclusive) cortical_owner.genome_locked = TRUE diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm index 5a07e43d3131..f556a9f16262 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm @@ -44,7 +44,6 @@ /datum/reagent/toxin/mutetoxin, /datum/reagent/toxin/mutagen, /datum/reagent/toxin/cyanide, - /datum/reagent/drug/opium, /datum/reagent/drug/mushroomhallucinogen, /datum/reagent/inverse/oculine, ) @@ -107,5 +106,5 @@ /datum/borer_evolution/diveworm/empowered_offspring/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - var/datum/action/cooldown/borer/empowered_offspring/attack_action = new() + var/datum/action/cooldown/borer/empowered_offspring/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm index 9a21906dbf37..a5245087977d 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_general.dm @@ -50,11 +50,9 @@ 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/oil, /datum/reagent/fuel, ) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm index ca5e11883524..be06cc5d7f41 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm @@ -12,7 +12,7 @@ /datum/borer_evolution/hivelord/produce_offspring/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - var/datum/action/cooldown/borer/produce_offspring/attack_action = new() + var/datum/action/cooldown/borer/produce_offspring/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) // T2 @@ -25,7 +25,7 @@ /datum/borer_evolution/hivelord/blood_chemical/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - var/datum/action/cooldown/borer/learn_bloodchemical/attack_action = new() + var/datum/action/cooldown/borer/learn_bloodchemical/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) // T3 @@ -51,7 +51,7 @@ /datum/borer_evolution/hivelord/stealth_mode/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - var/datum/action/cooldown/borer/stealth_mode/attack_action = new() + var/datum/action/cooldown/borer/stealth_mode/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) // T5 diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm index 5f2000158014..2ff58a125cd4 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm @@ -12,7 +12,7 @@ /datum/borer_evolution/symbiote/willing_host/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - var/datum/action/cooldown/borer/willing_host/attack_action = new() + var/datum/action/cooldown/borer/willing_host/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) // T2 @@ -107,5 +107,5 @@ /datum/borer_evolution/symbiote/revive_host/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - var/datum/action/cooldown/borer/revive_host/attack_action = new() + var/datum/action/cooldown/borer/revive_host/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) diff --git a/monkestation/code/modules/antagonists/borers/code/focus_datum.dm b/monkestation/code/modules/antagonists/borers/code/focus_datum.dm index 86db5e6c772e..b04a0f1a0ec7 100644 --- a/monkestation/code/modules/antagonists/borers/code/focus_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/focus_datum.dm @@ -12,15 +12,15 @@ for(var/trait in traits) if(HAS_TRAIT(host, trait)) continue - ADD_TRAIT(host, trait, borer) + ADD_TRAIT(host, trait, REF(borer)) /// Effects to take when the focus is removed /datum/borer_focus/proc/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) SHOULD_CALL_PARENT(TRUE) for(var/trait in traits) - if(!HAS_TRAIT_FROM(host, trait, borer)) + if(!HAS_TRAIT_FROM(host, trait, REF(borer))) continue - REMOVE_TRAIT(host, trait, borer) + REMOVE_TRAIT(host, trait, REF(borer)) /datum/borer_focus/head name = "head focus" diff --git a/monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm new file mode 100644 index 000000000000..7e5c72005196 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm @@ -0,0 +1,21 @@ +/obj/effect/mob_spawn/ghost_role/borer_egg/debug + name = "debug cortical borer egg" + desc = "An egg of a creature that is known to crawl inside of you. This one looks REALLY DANGEROUS. Consider calling nuclear operatives." + mob_type = /mob/living/basic/cortical_borer/debug + +/mob/living/basic/cortical_borer/debug + 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/force_speak, + /datum/action/cooldown/borer/fear_human, + /datum/action/cooldown/borer/check_blood, + + /datum/action/cooldown/borer/gain_evolution_point, + /datum/action/cooldown/borer/gain_chemical_point, + ) diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm similarity index 79% rename from monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm rename to monkestation/code/modules/antagonists/borers/code/items/egg.dm index d45b307d6f88..fe89a20b3e40 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -41,7 +41,14 @@ forceMove(host_egg) var/area/src_area = get_area(src) if(src_area) - notify_ghosts("A cortical borer egg has been laid in \the [src_area.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_DRONE, notify_suiciders = FALSE) + notify_ghosts( + "A cortical borer egg has been laid in \the [src_area.name].", + source = src, + action = NOTIFY_PLAY, + flashwindow = FALSE, + ignore_key = POLL_IGNORE_DRONE, + notify_suiciders = FALSE, + ) /obj/item/borer_egg name = "borer egg" @@ -82,15 +89,3 @@ desc = "An egg of a creature that came crawling out of someone instead of into them." mob_type = /mob/living/basic/cortical_borer/empowered host_egg = /obj/item/borer_egg/empowered - -/* -/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 \ - learn new chemicals through the blood if old enough. Be careful as there is no way to get the borer to pledge allegiance \ - to yourself. The egg is extremely fragile, do not crush it in your hand nor throw it. \ - The egg is required to sit out in the open in order to hatch. (Cannot be hidden in closets, etc.)" - progression_minimum = 20 MINUTES - item = /obj/item/borer_egg - cost = 20 -*/ diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm similarity index 84% rename from monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm rename to monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm index a685b1d9f710..1b6688514e2c 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_things/empowered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm @@ -21,11 +21,11 @@ /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) + addtimer(CALLBACK(src, PROC_REF(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!"))) + visible_message(span_warning("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) @@ -36,7 +36,7 @@ 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) + var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", 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 diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm b/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm similarity index 98% rename from monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm rename to monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm index 7152787b5730..30bb0efdbfdf 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_items.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm @@ -15,7 +15,7 @@ . = ..() update_appearance() var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = .proc/spring_trap, + COMSIG_ATOM_ENTERED = PROC_REF(spring_trap), ) AddElement(/datum/element/connect_loc, loc_connections) diff --git a/tgstation.dme b/tgstation.dme index 526d0b5744b3..69e64a987dc2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -528,7 +528,6 @@ #include "code\__HELPERS\sorts\MergeSort.dm" #include "code\__HELPERS\sorts\TimSort.dm" #include "code\__HELPERS\~monkestation-helpers\icon_smoothing.dm" -#include "code\__HELPERS\~monkestation-helpers\logging.dm" #include "code\__HELPERS\~monkestation-helpers\time.dm" #include "code\__HELPERS\~monkestation-helpers\virology.dm" #include "code\__HELPERS\~monkestation-helpers\logging\attack.dm" @@ -5729,20 +5728,36 @@ #include "monkestation\code\modules\aesthetics\subsystem\coloring.dm" #include "monkestation\code\modules\aesthetics\walls\iron.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer.dm" -#include "monkestation\code\modules\antagonists\borers\code\cortical_borer_abilities.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_antagonist.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_chems.dm" -#include "monkestation\code\modules\antagonists\borers\code\cortical_borer_egg.dm" -#include "monkestation\code\modules\antagonists\borers\code\cortical_borer_items.dm" #include "monkestation\code\modules\antagonists\borers\code\focus_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\status_effects.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\_ability.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\_debug_abilities.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\chemical_injector.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\enter_host.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\evolution_tree.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\force_speech.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\hide_presence.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\host_healthscan.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\incite_fear.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\learn_chemicals.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\learn_focus.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\revive_host.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\spawn_offspring.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\toggle_stealth.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\upgrade_body.dm" +#include "monkestation\code\modules\antagonists\borers\code\abilities\willing_host.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\borer_evolution.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_diveworm.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_general.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_hivelord.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_symbiote.dm" -#include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_things\empowered_egg.dm" +#include "monkestation\code\modules\antagonists\borers\code\items\debug_egg.dm" +#include "monkestation\code\modules\antagonists\borers\code\items\egg.dm" +#include "monkestation\code\modules\antagonists\borers\code\items\empowered_egg.dm" +#include "monkestation\code\modules\antagonists\borers\code\items\imprisonment_cage.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_alert.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_helpers.dm" From 8723058dbf796d6184ae0ab9a9e6c770c8946fb9 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:03:38 +0100 Subject: [PATCH 03/67] removes the mid-round chance --- .../antagonists/borers/code/cortical_borer_antagonist.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm index 24675a2731d3..f4840734fb49 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm @@ -91,6 +91,8 @@ parts += span_redtext("Borers were unable to learn enough chemicals through the blood!") return "
[parts.Join("
")]
" +/* For now... lets not, I need to find a good place to fit these guys in + /datum/round_event_control/cortical_borer name = "Cortical Borer Infestation" typepath = /datum/round_event/ghost_role/cortical_borer @@ -187,3 +189,5 @@ return new_borer #undef POP_PER_BORER + +*/ From 50dd5ec0976fd63c05c886fcd6c17241de61e468 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:10:27 +0100 Subject: [PATCH 04/67] readme.md changes part 1 --- .../code/modules/antagonists/borers/readme.md | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/readme.md b/monkestation/code/modules/antagonists/borers/readme.md index 9e0a98672184..8f52a4cb1c92 100644 --- a/monkestation/code/modules/antagonists/borers/readme.md +++ b/monkestation/code/modules/antagonists/borers/readme.md @@ -1,24 +1,31 @@ -## Title: Cortical Borer +https://github.com/Monkestation/Monkestation2.0/pull/insert da pull PR when i PR it here :3 + +## Cortical Borers MODULE ID: CORTICAL_BORERS ### Description: -Adds the Cortical Borer. - -### TG Proc Changes: - -N/A +This file is responsible for all cortical worm related files +Cortical worms are antagonists whose sole purpose is to reproduce infintelly -### Defines: +### TG Proc/File Changes: -N/A +code\__DEFINES\role_preferences.dm +code\_globalvars\lists\poll_ignore.dm +code\datums\mutations\_mutations.dm +code\modules\admin\sql_ban_system.dm +code\modules\antagonists\changeling\powers\panacea.dm -### Included files: +### Included files that are not contained in this module: -N/A +code\__DEFINES\~monkestation\actionspeed_modification.dm +code\__DEFINES\~monkestation\antagonists.dm +code\__DEFINES\~monkestation\is_helpers.dm +code\__DEFINES\~monkestation\role_preferences.dm ### Credits: -Jake Park - Code +Jake Park - Original borer Code /vg/station - Partial Icons +Gboster - Porting the code to monkestation From 3281d93c653526d3a566a3e8918e1b2672cb5653 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:15:15 +0100 Subject: [PATCH 05/67] readme.md changes part 2 --- monkestation/code/modules/antagonists/borers/readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/readme.md b/monkestation/code/modules/antagonists/borers/readme.md index 8f52a4cb1c92..a90efa52fa91 100644 --- a/monkestation/code/modules/antagonists/borers/readme.md +++ b/monkestation/code/modules/antagonists/borers/readme.md @@ -1,4 +1,4 @@ -https://github.com/Monkestation/Monkestation2.0/pull/insert da pull PR when i PR it here :3 +https://github.com/Monkestation/Monkestation2.0/pull/976 ## Cortical Borers @@ -24,6 +24,9 @@ code\__DEFINES\~monkestation\antagonists.dm code\__DEFINES\~monkestation\is_helpers.dm code\__DEFINES\~monkestation\role_preferences.dm +tgui\packages\tgui\interfaces\BorerChem.jsx +tgui\packages\tgui\interfaces\BorerEvolution.tsx + ### Credits: Jake Park - Original borer Code From 279c9a19db7771e1bb5929c929972180f2c4068e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:29:04 +0100 Subject: [PATCH 06/67] mayhaps we dont support jsx files? --- tgui/packages/tgui/interfaces/{BorerChem.jsx => BorerChem.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tgui/packages/tgui/interfaces/{BorerChem.jsx => BorerChem.js} (100%) diff --git a/tgui/packages/tgui/interfaces/BorerChem.jsx b/tgui/packages/tgui/interfaces/BorerChem.js similarity index 100% rename from tgui/packages/tgui/interfaces/BorerChem.jsx rename to tgui/packages/tgui/interfaces/BorerChem.js From c471d73effa342cc00159379bda240d421c97b09 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 20 Jan 2024 07:56:00 +0100 Subject: [PATCH 07/67] traitor borers & code improvement --- .../borers/code/abilities/_ability.dm | 12 +++ .../code/abilities/chemical_injector.dm | 9 +- .../borers/code/abilities/enter_host.dm | 5 +- .../borers/code/abilities/force_speech.dm | 8 +- .../borers/code/abilities/hide_presence.dm | 4 +- .../borers/code/abilities/host_healthscan.dm | 8 +- .../borers/code/abilities/incite_fear.dm | 4 +- .../borers/code/abilities/learn_chemicals.dm | 16 +-- .../borers/code/abilities/learn_focus.dm | 8 +- .../borers/code/abilities/revive_host.dm | 8 +- .../borers/code/abilities/spawn_offspring.dm | 11 +- .../borers/code/abilities/upgrade_body.dm | 8 +- .../borers/code/abilities/willing_host.dm | 8 +- .../borers/code/cortical_borer_antagonist.dm | 101 ------------------ .../antagonists/borers/code/items/egg.dm | 39 +++---- .../borers/code/items/empowered_egg.dm | 10 ++ .../borers/code/items/neutered_egg.dm | 19 ++++ .../borers/code/{ => mobs}/cortical_borer.dm | 50 +++++---- .../borers/code/mobs/empowered_borer.dm | 17 +++ .../borers/code/mobs/neutered_borer.dm | 6 ++ .../code/modules/uplink/uplink_items/misc.dm | 17 +++ tgstation.dme | 5 +- 22 files changed, 163 insertions(+), 210 deletions(-) create mode 100644 monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm rename monkestation/code/modules/antagonists/borers/code/{ => mobs}/cortical_borer.dm (95%) create mode 100644 monkestation/code/modules/antagonists/borers/code/mobs/empowered_borer.dm create mode 100644 monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm index 75db1c759a65..26fd66c4b5e6 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm @@ -8,6 +8,10 @@ var/chemical_evo_points = 0 /// How many stat evo points are needed to use this ability var/stat_evo_points = 0 + /// Does this ability need a human host to be triggered? + var/requires_host = FALSE + /// Does this ability stop working when the host has sugar? + var/sugar_restricted = FALSE /datum/action/cooldown/borer/New(Target, original) . = ..() @@ -28,6 +32,14 @@ var/mob/living/basic/cortical_borer/cortical_owner = owner if(owner.stat == DEAD) return FALSE + + if(requires_host == TRUE && !cortical_owner.inside_human()) + owner.balloon_alert(owner, "host required") + return + if(sugar_restricted == TRUE && cortical_owner.host_sugar()) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + if(cortical_owner.chemical_storage < chemical_cost) cortical_owner.balloon_alert(cortical_owner, "need [chemical_cost] chemicals") return FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm b/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm index a0106cd7d21b..f6647d8a9957 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm @@ -9,18 +9,13 @@ /datum/action/cooldown/borer/inject_chemical name = "Open Chemical Injector" button_icon_state = "chemical" + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE - var/mob/living/basic/cortical_borer/cortical_owner = owner - if(!cortical_owner.human_host) - owner.balloon_alert(owner, "host required") - return - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return ui_interact(owner) /datum/action/cooldown/borer/inject_chemical/ui_interact(mob/user, datum/tgui/ui) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index 8f659ccefe6b..1992444eb13f 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -46,11 +46,14 @@ // hosts need to be organic if(!(listed_human.mob_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) continue - //hosts cannot be changelings + // hosts cannot be changelings if(listed_human.mind) var/datum/antagonist/changeling/changeling = listed_human.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling && cortical_owner.changeling_restricted) continue + // hosts cannot have bio protected headgear on + if(check_for_bio_protection(listed_human) == TRUE) + continue usable_hosts += listed_human //if the list of possible hosts is one, just go straight in, no choosing diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm index 3a0ea8b81210..137c6aed8ab4 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm @@ -2,18 +2,14 @@ name = "Force Host Speak" cooldown_time = 30 SECONDS button_icon_state = "speak" + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/force_speak/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(!cortical_owner.inside_human()) - owner.balloon_alert(owner, "must be in a host") - return var/borer_message = input(cortical_owner, "What would you like to force your host to say?", "Force Speak") as message|null if(!borer_message) owner.balloon_alert(owner, "no message given") diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm b/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm index 30ffd863caf7..bcb63b2a55b6 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm @@ -3,6 +3,7 @@ cooldown_time = 2 MINUTES button_icon_state = "hiding" chemical_cost = 100 + sugar_restricted = TRUE /datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags, atom/target) var/mob/living/basic/cortical_borer/cortical_owner = owner @@ -14,9 +15,6 @@ . = ..() if(!.) return FALSE - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return owner.balloon_alert(owner, "stealth mode [in_stealth ? "disabled" : "enabled"]") cortical_owner.chemical_storage -= chemical_cost if(in_stealth) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm b/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm index fc05c80e5fd6..8b7b3dfdca9a 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm @@ -2,18 +2,14 @@ name = "Check Blood" cooldown_time = 5 SECONDS button_icon_state = "blood" + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/check_blood/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(!cortical_owner.human_host) - owner.balloon_alert(owner, "host required") - return healthscan(owner, cortical_owner.human_host, advanced = TRUE) // :thinking: chemscan(owner, cortical_owner.human_host) StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm b/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm index 1d14f2421faa..a1ba23980077 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm @@ -2,15 +2,13 @@ name = "Incite Fear" cooldown_time = 12 SECONDS button_icon_state = "fear" + sugar_restricted = TRUE /datum/action/cooldown/borer/fear_human/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return if(cortical_owner.human_host) incite_internal_fear() StartCooldown() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm index 857b9c0f5926..10a226542aee 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -17,18 +17,14 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) name = "Learn New Chemical" button_icon_state = "bloodlevel" chemical_evo_points = 1 + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/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(!length(cortical_owner.potential_chemicals)) owner.balloon_alert(owner, "all chemicals learned") return @@ -55,18 +51,14 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) name = "Learn Chemical from Blood" button_icon_state = "bloodchem" chemical_evo_points = 5 + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/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(length(cortical_owner.human_host.reagents.reagent_list) <= 0) owner.balloon_alert(owner, "no reagents in host") return diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm index a0b89f1b6e00..9204c81195e9 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm @@ -1,18 +1,14 @@ /datum/action/cooldown/borer/learn_focus name = "Learn Focus" button_icon_state = "getfocus" + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/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(!length(cortical_owner.possible_focuses)) owner.balloon_alert(owner, "all focuses already learned") return diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm index 3c460a927894..bf8873f78b53 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm @@ -4,18 +4,14 @@ cooldown_time = 2 MINUTES button_icon_state = "revive" chemical_cost = 200 + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return - if(!cortical_owner.inside_human()) - owner.balloon_alert(owner, "host required") - return cortical_owner.chemical_storage -= chemical_cost if(cortical_owner.human_host.getBruteLoss()) cortical_owner.human_host.adjustBruteLoss(-(cortical_owner.human_host.getBruteLoss()*0.5)) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index b1524ae135f4..f9b46bb25117 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -12,9 +12,15 @@ if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner + if(cortical_owner.neutered == TRUE) + owner.balloon_alert(owner, "You cannot reproduce!") + return if(!(cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) owner.balloon_alert(owner, "host required") return + if(cortical_owner.human_host.stat == DEAD) + owner.balloon_alert(owner, "host dead") + return cortical_owner.chemical_storage -= chemical_cost if((cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) no_host_egg() @@ -71,14 +77,15 @@ cooldown_time = 1 MINUTES button_icon_state = "reproduce" chemical_cost = 150 + requires_host = TRUE /datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(!cortical_owner.inside_human()) - owner.balloon_alert(owner, "host required") + if(cortical_owner.neutered == TRUE) + owner.balloon_alert(owner, "You cannot reproduce!") return if(cortical_owner.human_host.stat != DEAD) owner.balloon_alert(owner, "host not dead") diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm index 7e9afd726991..12bda3f47d05 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm @@ -2,18 +2,14 @@ name = "Become Stronger" button_icon_state = "level" stat_evo_points = 1 + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/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 cortical_owner.stat_evolution -= stat_evo_points cortical_owner.maxHealth += cortical_owner.health_per_level cortical_owner.health_regen += cortical_owner.health_regen_per_level diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm index d62baabdb1fb..2f451b338496 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm @@ -3,18 +3,14 @@ cooldown_time = 2 MINUTES button_icon_state = "willing" chemical_cost = 150 + requires_host = TRUE + sugar_restricted = TRUE /datum/action/cooldown/borer/willing_host/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/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 for(var/ckey_check in GLOB.willing_hosts) if(ckey_check == cortical_owner.human_host.ckey) owner.balloon_alert(owner, "host already willing") diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm index f4840734fb49..64f3c20aedd0 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm @@ -90,104 +90,3 @@ else parts += span_redtext("Borers were unable to learn enough chemicals through the blood!") return "
[parts.Join("
")]
" - -/* For now... lets not, I need to find a good place to fit these guys in - -/datum/round_event_control/cortical_borer - name = "Cortical Borer Infestation" - typepath = /datum/round_event/ghost_role/cortical_borer - weight = 10 - min_players = 999 - max_occurrences = 1 //should only ever happen once - dynamic_should_hijack = TRUE - category = EVENT_CATEGORY_ENTITIES - description = "A cortical borer has appeared on station. It will also attempt to produce eggs, and will attempt to gather willing hosts and learn chemicals through the blood." - -/datum/round_event/ghost_role/cortical_borer - announce_when = 400 - -/datum/round_event/ghost_role/cortical_borer/setup() - announce_when = rand(announce_when, announce_when + 50) - -/datum/round_event/ghost_role/cortical_borer/announce(fake) - priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS) - -/datum/round_event/ghost_role/cortical_borer/start() - var/list/vents = list() - for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) - if(QDELETED(temp_vent)) - continue - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] - if(!temp_vent_parent) - continue // No parent vent - // Stops Cortical Borers getting stuck in small networks. - // See: Security, Virology - if(length(temp_vent_parent.other_atmos_machines) > 20) - vents += temp_vent - if(!length(vents)) - return MAP_ERROR - var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER) - if(!length(candidates)) - return NOT_ENOUGH_PLAYERS - var/living_number = max(length(GLOB.player_list) / POP_PER_BORER, 1) - var/choosing_number = min(length(candidates), living_number) - for(var/repeating_code in 1 to choosing_number) - var/mob/dead/observer/new_borer = pick(candidates) - candidates -= new_borer - var/turf/vent_turf = get_turf(pick(vents)) - var/mob/living/basic/cortical_borer/spawned_cb = new /mob/living/basic/cortical_borer(vent_turf) - spawned_cb.ckey = new_borer.ckey - spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) - to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) - for(var/mob/dead_mob in GLOB.dead_mob_list) - to_chat(dead_mob, span_notice("The cortical borers have been selected, you are able to orbit them! Remember, they can reproduce!")) - -/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer - name = "Cortical Borer Infestation" - antag_datum = /datum/antagonist/cortical_borer - midround_ruleset_style = MIDROUND_RULESET_STYLE_LIGHT - antag_flag = ROLE_BORER - enemy_roles = list( - JOB_CAPTAIN, - JOB_DETECTIVE, - JOB_HEAD_OF_SECURITY, - JOB_SECURITY_OFFICER, - ) - required_enemies = list(2,2,1,1,1,1,1,0,0,0) - required_candidates = 1 - weight = 3 - cost = 15 - minimum_players = 20 - repeatable = TRUE - /// List of on-station vents - var/list/vents = list() - -/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/execute() - for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) - if(QDELETED(temp_vent)) - continue - if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] - if(!temp_vent_parent) - continue // No parent vent - // Stops Borers getting stuck in small networks. - // See: Security, Virology - if(length(temp_vent_parent.other_atmos_machines) > 20) - vents += temp_vent - if(!length(vents)) - return FALSE - return TRUE - -/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/generate_ruleset_body(mob/applicant) - var/obj/vent = pick_n_take(vents) - var/mob/living/basic/cortical_borer/new_borer = new(vent.loc) - new_borer.key = applicant.key - new_borer.move_into_vent(vent) - message_admins("[ADMIN_LOOKUPFLW(new_borer)] has been made into a borer by the midround ruleset.") - log_game("DYNAMIC: [key_name(new_borer)] was spawned as a borer by the midround ruleset.") - return new_borer - -#undef POP_PER_BORER - -*/ diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index fe89a20b3e40..c23047c34639 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -1,3 +1,12 @@ +/obj/item/borer_egg + name = "borer egg" + desc = "An egg of a creature that is known to crawl inside of you, be careful." + icon = 'monkestation/code/modules/antagonists/borers/icons/animal.dmi' + icon_state = "brainegg" + layer = BELOW_MOB_LAYER + ///the spawner that is attached to this item + var/obj/effect/mob_spawn/ghost_role/borer_egg/host_spawner + /obj/effect/mob_spawn/ghost_role/borer_egg name = "borer egg" desc = "An egg of a creature that is known to crawl inside of you, be careful." @@ -9,7 +18,7 @@ ///Type of mob that will be spawned mob_type = /mob/living/basic/cortical_borer role_ban = ROLE_ALIEN - show_flavor = FALSE + show_flavor = TRUE prompt_name = "cortical borer" you_are_text = "You are a Cortical Borer." flavour_text = "You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! \ @@ -20,7 +29,7 @@ You can talk to other borers using ; and your host by just speaking normally. \ You are unable to speak outside of a host, but are able to emote." ///what the generation of the borer egg is - var/generation = 1 + var/generation = 0 ///the egg that is attached to this mob spawn var/obj/item/borer_egg/host_egg = /obj/item/borer_egg @@ -31,7 +40,12 @@ /obj/effect/mob_spawn/ghost_role/borer_egg/special(mob/living/spawned_mob, mob/mob_possessor) . = ..() spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer) - spawned_mob.name = "cortical borer ([generation]-[rand(100,999)])" + if(generation == 0) + //The first ever borer gets a special name + spawned_mob.name = "The hivequeen [initial(name)]" + else + //so their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 + spawned_mob.name = "[initial(name)] ([generation]-[rand(100,999)])" QDEL_NULL(host_egg) /obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team) @@ -50,15 +64,6 @@ notify_suiciders = FALSE, ) -/obj/item/borer_egg - name = "borer egg" - desc = "An egg of a creature that is known to crawl inside of you, be careful." - icon = 'monkestation/code/modules/antagonists/borers/icons/animal.dmi' - icon_state = "brainegg" - layer = BELOW_MOB_LAYER - ///the spawner that is attached to this item - var/obj/effect/mob_spawn/ghost_role/borer_egg/host_spawner - /obj/item/borer_egg/attack_ghost(mob/user) if(host_spawner) host_spawner.attack_ghost(user) @@ -79,13 +84,3 @@ new /obj/effect/decal/cleanable/food/egg_smudge(hit_turf) QDEL_NULL(host_spawner) qdel(src) - -/obj/item/borer_egg/empowered - name = "empowered borer egg" - icon_state = "empowered_brainegg" - -/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/basic/cortical_borer/empowered - host_egg = /obj/item/borer_egg/empowered diff --git a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm index 1b6688514e2c..99b0903591b0 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm @@ -1,3 +1,13 @@ +/obj/item/borer_egg/empowered + name = "empowered borer egg" + icon_state = "empowered_brainegg" + +/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/basic/cortical_borer/empowered + host_egg = /obj/item/borer_egg/empowered + /obj/item/organ/internal/empowered_borer_egg name = "strange egg" desc = "All slimy and yuck." diff --git a/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm new file mode 100644 index 000000000000..760f53b86b94 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm @@ -0,0 +1,19 @@ +/obj/item/borer_egg/neutered + name = "strange borer egg" + icon_state = "empowered_brainegg" + +/obj/effect/mob_spawn/ghost_role/borer_egg/neutered + name = "strange borer egg" + desc = "An egg of a creature that is known to crawl inside of you, be careful." + mob_type = /mob/living/basic/cortical_borer/neutered + host_egg = /obj/item/borer_egg/neutered + you_are_text = "You are a Neutered Cortical Borer." + flavour_text = "You are a neutered cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! \ + You only grow/heal/talk when inside a host!" + important_text = "As a borer, you have the option to be friendly or not. \ + Note that how you act will determine how a host responds. \ + Do not wordlessly resort to mechanics within a host. \ + You can talk to other borers using ; and your host by just speaking normally. \ + You are unable to speak outside of a host, but are able to emote. \ + Additionally you have been trained by the syndicate to obey every command and protect whomever is the nearest to you when you crawled out of your egg." + generation = 1 // you dont exactly have balls, so how can you be the hive's queen? diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm similarity index 95% rename from monkestation/code/modules/antagonists/borers/code/cortical_borer.dm rename to monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index facfbd3b84ac..7f457292a1e6 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -125,29 +125,37 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/reagent/medicine/mannitol, ) //blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these - var/list/blacklisted_chemicals = list() //currently may be empty, but leaving the mechanism just in case + var/list/blacklisted_chemicals = list() + ///how old the borer is, starting from zero. Goes up only when inside a host var/maturity_age = 0 + //just a little "timer" to compare to world.time + var/timed_maturity = 0 + /// How many times you've levelled up over all + var/level = 0 + ///the amount of "evolution" points a borer has for chemicals. Start with one var/chemical_evolution = 1 ///the amount of "evolution" points a borer has for stats var/stat_evolution = 0 + ///how many chemical points the borer can have. Can be upgraded var/max_chemical_storage = 50 ///how many chemical points the borer has 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, @@ -161,12 +169,12 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/action/cooldown/borer/fear_human, /datum/action/cooldown/borer/check_blood, ) + ///the host var/mob/living/carbon/human/human_host //what the host gains or loses with the borer var/list/hosts_abilities = list() - //just a little "timer" to compare to world.time - var/timed_maturity = 0 + ///multiplies the current health up to the max health var/health_regen = 1.02 //holds the chems right before injection @@ -213,6 +221,11 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// Multiplier for a borer's negative effects to their host var/host_harm_multiplier = 1 + /// Controls if the borer can reproduce or not, TRUE means it wont be able to spawn eggs + var/neutered = FALSE + /// Used to give the borer the antagonist datum + var/antagonist_datum = /datum/antagonist/cortical_borer + /mob/living/basic/cortical_borer/Initialize(mapload) . = ..() AddComponent( \ @@ -227,7 +240,12 @@ GLOBAL_LIST_EMPTY(cortical_borers) borer_matrix.Scale(0.5, 0.5) transform = borer_matrix - name = "[initial(name)] ([generation]-[rand(100,999)])" //so their gen and a random. ex 1-288 is first gen named 288, 4-483 if fourth gen named 483 + if(generation == 0) + //The first ever borer gets a special name + name = "The hivequeen [initial(name)]" + else + //so their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 + name = "[initial(name)] ([generation]-[rand(100,999)])" GLOB.cortical_borers += src reagent_holder = new /obj/item/reagent_containers/borer(src) @@ -237,8 +255,8 @@ GLOBAL_LIST_EMPTY(cortical_borers) attack_action.Grant(src) if(mind) - if(!mind.has_antag_datum(/datum/antagonist/cortical_borer)) - mind.add_antag_datum(/datum/antagonist/cortical_borer) + if(!mind.has_antag_datum(antagonist_datum)) + mind.add_antag_datum(antagonist_datum) for(var/focus_path in subtypesof(/datum/borer_focus)) possible_focuses += new focus_path @@ -329,7 +347,8 @@ GLOBAL_LIST_EMPTY(cortical_borers) to_chat(user, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) ckey = user.ckey if(mind) - mind.add_antag_datum(/datum/antagonist/cortical_borer) + mind.add_antag_datum(antagonist_datum) + //check if we are inside a human /mob/living/basic/cortical_borer/proc/inside_human() @@ -458,17 +477,4 @@ GLOBAL_LIST_EMPTY(cortical_borers) chemical_regen = initial(chemical_regen) + (level * chem_regen_per_level) health = clamp(old_health, 1, maxHealth) -// Only able to spawn from an egg burst from a corpse, starts off stronger -/mob/living/basic/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 - #undef BODYTEMP_DIVISOR diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/empowered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/empowered_borer.dm new file mode 100644 index 000000000000..092dd92a621b --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/mobs/empowered_borer.dm @@ -0,0 +1,17 @@ +/** + * They can only spawn from a dead body that had an egg implanted into it + * Starts SIGNIFICANTLY stronger than any other option you can get + */ +/mob/living/basic/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 diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm new file mode 100644 index 000000000000..0b31e3fd1b6b --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm @@ -0,0 +1,6 @@ +/** + * A version of the standard borer that can't reproduce + */ + +/mob/living/basic/cortical_borer/neutered + neutered = TRUE diff --git a/monkestation/code/modules/uplink/uplink_items/misc.dm b/monkestation/code/modules/uplink/uplink_items/misc.dm index 6cbea05e1b38..0fa9dd55ce5b 100644 --- a/monkestation/code/modules/uplink/uplink_items/misc.dm +++ b/monkestation/code/modules/uplink/uplink_items/misc.dm @@ -6,3 +6,20 @@ purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) item = /obj/item/syndie_glue cost = 2 + +/datum/uplink_item/device_tools/neutered_borer_egg + name = "Neutered borer egg" + desc = "A borer egg specifically bred to aid operatives. \ + It will obey every command and protect whatever operative they first see when hatched. \ + Unfortunatelly due to extreme radiation exposure, they cannot reproduce." + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) + item = /obj/effect/mob_spawn/ghost_role/borer_egg/neutered + cost = 20 + +/datum/uplink_item/device_tools/borer_egg + name = "Hive queen borer egg" + desc = "A borer egg of a queen we captured and safelly stored away. \ + Be warned, the borer queen is not necessarily allied to you." + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) + item = /obj/effect/mob_spawn/ghost_role/borer_egg + cost = 30 diff --git a/tgstation.dme b/tgstation.dme index 69e64a987dc2..2c45f05b3e4d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5727,7 +5727,6 @@ #include "monkestation\code\modules\aesthetics\objects\windows.dm" #include "monkestation\code\modules\aesthetics\subsystem\coloring.dm" #include "monkestation\code\modules\aesthetics\walls\iron.dm" -#include "monkestation\code\modules\antagonists\borers\code\cortical_borer.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_antagonist.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_chems.dm" #include "monkestation\code\modules\antagonists\borers\code\focus_datum.dm" @@ -5758,6 +5757,10 @@ #include "monkestation\code\modules\antagonists\borers\code\items\egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\empowered_egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\imprisonment_cage.dm" +#include "monkestation\code\modules\antagonists\borers\code\items\neutered_egg.dm" +#include "monkestation\code\modules\antagonists\borers\code\mobs\cortical_borer.dm" +#include "monkestation\code\modules\antagonists\borers\code\mobs\empowered_borer.dm" +#include "monkestation\code\modules\antagonists\borers\code\mobs\neutered_borer.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_alert.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_helpers.dm" From cfc1eb5cef7ff0470007cf01c2a778071b961b36 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 20 Jan 2024 08:39:01 +0100 Subject: [PATCH 08/67] im sorry, but we cant have eggs running around can we? --- .../modules/antagonists/borers/code/items/egg.dm | 12 ++++++------ .../antagonists/borers/code/items/neutered_egg.dm | 10 +++++----- .../antagonists/borers/code/mobs/cortical_borer.dm | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index c23047c34639..3fa1a1af904b 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -23,10 +23,10 @@ you_are_text = "You are a Cortical Borer." flavour_text = "You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! \ You only grow/heal/talk when inside a host!" - important_text = "As a borer, you have the option to be friendly or not. \ - Note that how you act will determine how a host responds. \ - Do not wordlessly resort to mechanics within a host. \ - You can talk to other borers using ; and your host by just speaking normally. \ + important_text = "As a borer, you have the option to be friendly or not. \n\ + Note that how you act will determine how a host responds. \n\ + Do not wordlessly resort to mechanics within a host. \n\ + You can talk to other borers using ; and your host by just speaking normally. \n\ You are unable to speak outside of a host, but are able to emote." ///what the generation of the borer egg is var/generation = 0 @@ -42,10 +42,10 @@ spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer) if(generation == 0) //The first ever borer gets a special name - spawned_mob.name = "The hivequeen [initial(name)]" + spawned_mob.name = "The hivequeen cortical borer" else //so their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 - spawned_mob.name = "[initial(name)] ([generation]-[rand(100,999)])" + spawned_mob.name = "cortical borer ([generation]-[rand(100,999)])" QDEL_NULL(host_egg) /obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team) diff --git a/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm index 760f53b86b94..010283d60590 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm @@ -10,10 +10,10 @@ you_are_text = "You are a Neutered Cortical Borer." flavour_text = "You are a neutered cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! \ You only grow/heal/talk when inside a host!" - important_text = "As a borer, you have the option to be friendly or not. \ - Note that how you act will determine how a host responds. \ - Do not wordlessly resort to mechanics within a host. \ - You can talk to other borers using ; and your host by just speaking normally. \ - You are unable to speak outside of a host, but are able to emote. \ + important_text = "As a borer, you have the option to be friendly or not. \n\ + Note that how you act will determine how a host responds. \n\ + Do not wordlessly resort to mechanics within a host. \n\ + You can talk to other borers using ; and your host by just speaking normally. \n\ + You are unable to speak outside of a host, but are able to emote. \n\ Additionally you have been trained by the syndicate to obey every command and protect whomever is the nearest to you when you crawled out of your egg." generation = 1 // you dont exactly have balls, so how can you be the hive's queen? diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 7f457292a1e6..fd53badb8117 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -180,7 +180,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) //holds the chems right before injection var/obj/item/reagent_containers/reagent_holder //just a flavor kind of thing - var/generation = 1 + var/generation = 0 /// List of focus datums var/list/possible_focuses = list() /// What focuses the borer has unlocked From 0f68e4d5ad55541823a9549ba7b0b64c94acbaa2 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:42:32 +0100 Subject: [PATCH 09/67] lets not --- code/__DEFINES/research/anomalies.dm | 1 + monkestation/code/modules/antagonists/borers/readme.md | 1 + 2 files changed, 2 insertions(+) diff --git a/code/__DEFINES/research/anomalies.dm b/code/__DEFINES/research/anomalies.dm index 911a2958d89e..1c7b7fd908fc 100644 --- a/code/__DEFINES/research/anomalies.dm +++ b/code/__DEFINES/research/anomalies.dm @@ -43,6 +43,7 @@ GLOBAL_LIST_INIT(bioscrambler_organs_blacklist, typecacheof(list ( /obj/item/organ/internal/monster_core, /obj/item/organ/internal/vocal_cords/colossus, /obj/item/organ/internal/zombie_infection, + /obj/item/organ/internal/empowered_borer_egg, // MONKESTATION ADDITION -- CORTICAL_BORERS ))) /// List of body parts we can apply to people diff --git a/monkestation/code/modules/antagonists/borers/readme.md b/monkestation/code/modules/antagonists/borers/readme.md index a90efa52fa91..db4cfa544839 100644 --- a/monkestation/code/modules/antagonists/borers/readme.md +++ b/monkestation/code/modules/antagonists/borers/readme.md @@ -12,6 +12,7 @@ Cortical worms are antagonists whose sole purpose is to reproduce infintelly ### TG Proc/File Changes: code\__DEFINES\role_preferences.dm +code\__DEFINES\research\anomalies.dm code\_globalvars\lists\poll_ignore.dm code\datums\mutations\_mutations.dm code\modules\admin\sql_ban_system.dm From 67f3ea36a7c91081072c7d1a688e1c828e9054ca Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 26 Jan 2024 21:49:50 +0100 Subject: [PATCH 10/67] post-upstream fixes --- code/__DEFINES/~monkestation/antagonists.dm | 3 +++ code/__DEFINES/~monkestation/is_helpers.dm | 1 - tgstation.dme | 2 ++ tgui/packages/tgui/interfaces/BorerChem.js | 3 ++- 4 files changed, 7 insertions(+), 2 deletions(-) delete mode 100644 code/__DEFINES/~monkestation/is_helpers.dm diff --git a/code/__DEFINES/~monkestation/antagonists.dm b/code/__DEFINES/~monkestation/antagonists.dm index 6228d16e5bd1..b42eb8c6d574 100644 --- a/code/__DEFINES/~monkestation/antagonists.dm +++ b/code/__DEFINES/~monkestation/antagonists.dm @@ -18,6 +18,9 @@ /// is something an eminence #define iseminence(checked) (istype(checked, /mob/living/eminence)) +/// is something a worm +#define iscorticalborer(A) (istype(A, /mob/living/basic/cortical_borer)) + // Borer evolution defines // The three primary paths that eventually diverge #define BORER_EVOLUTION_SYMBIOTE "Symbiote" diff --git a/code/__DEFINES/~monkestation/is_helpers.dm b/code/__DEFINES/~monkestation/is_helpers.dm deleted file mode 100644 index b4157e80d274..000000000000 --- a/code/__DEFINES/~monkestation/is_helpers.dm +++ /dev/null @@ -1 +0,0 @@ -#define iscorticalborer(A) (istype(A, /mob/living/basic/cortical_borer)) diff --git a/tgstation.dme b/tgstation.dme index 482ea5f8d1c9..4281287221ec 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5733,6 +5733,7 @@ #include "monkestation\code\modules\aesthetics\objects\windows.dm" #include "monkestation\code\modules\aesthetics\subsystem\coloring.dm" #include "monkestation\code\modules\aesthetics\walls\iron.dm" +#include "monkestation\code\modules\antagonists\_common\antag_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_antagonist.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_chems.dm" #include "monkestation\code\modules\antagonists\borers\code\focus_datum.dm" @@ -5767,6 +5768,7 @@ #include "monkestation\code\modules\antagonists\borers\code\mobs\cortical_borer.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\empowered_borer.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\neutered_borer.dm" +#include "monkestation\code\modules\antagonists\brainwashing\brainwashing.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_alert.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_helpers.dm" #include "monkestation\code\modules\antagonists\clock_cult\area.dm" diff --git a/tgui/packages/tgui/interfaces/BorerChem.js b/tgui/packages/tgui/interfaces/BorerChem.js index de5408519774..70a6bbee1ee3 100644 --- a/tgui/packages/tgui/interfaces/BorerChem.js +++ b/tgui/packages/tgui/interfaces/BorerChem.js @@ -46,7 +46,8 @@ export const BorerChem = (props, context) => { disabled={data.onCooldown || data.notEnoughChemicals} onClick={() => act('inject', { - reagent: chemical.title, + // reagent: chemical.title, REQUIRES PR #78637? + reagent: chemical.id, }) } /> From f0693d2b9f91f40a42858effe24fea20d9509b48 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 27 Jan 2024 01:22:59 +0100 Subject: [PATCH 11/67] entering hosts now gives a text --- .../antagonists/borers/code/abilities/enter_host.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index 1992444eb13f..b0fab9d0ae7a 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -36,23 +36,29 @@ for(var/mob/living/carbon/human/listed_human in range(1, cortical_owner)) // no non-human hosts if(!ishuman(listed_human) || ismonkey(listed_human)) + to_chat(cortical_owner, span_warning("[listed_human] is not a human!")) continue // cannot have multiple borers (for now) if(listed_human.has_borer()) + to_chat(cortical_owner, span_warning("[listed_human] already has our sister within them!")) continue // hosts need to be organic if(!(listed_human.dna.species.inherent_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) + to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) continue // hosts need to be organic if(!(listed_human.mob_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) + to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) continue - // hosts cannot be changelings + // hosts cannot be changelings unless we specify otherwise if(listed_human.mind) + to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) var/datum/antagonist/changeling/changeling = listed_human.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling && cortical_owner.changeling_restricted) continue // hosts cannot have bio protected headgear on if(check_for_bio_protection(listed_human) == TRUE) + to_chat(cortical_owner, span_warning("[listed_human] has too hard of a helmet to crawl inside of their ear!")) continue usable_hosts += listed_human From 7c0e51f3018ea04c8eef2ef919a31546fdd37c70 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 27 Jan 2024 01:55:32 +0100 Subject: [PATCH 12/67] lets learn chemicals by names, and not a path --- .../borers/code/abilities/learn_chemicals.dm | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm index 10a226542aee..4f6cb75fae61 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -25,22 +25,41 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner + if(!length(cortical_owner.potential_chemicals)) owner.balloon_alert(owner, "all chemicals learned") return - var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.potential_chemicals) + + var/named_chemicals = list() + for(var/datum/reagent/thing as anything in cortical_owner.potential_chemicals) + named_chemicals += initial(thing.name) + + var/reagent_choice = tgui_input_list( + cortical_owner, + "Choose a chemical to learn.", + "Chemical Selection", + named_chemicals, + ) if(!reagent_choice) owner.balloon_alert(owner, "no chemical chosen") return + + var/datum/reagent/learned_reagent + for(var/datum/reagent/thing as anything in cortical_owner.potential_chemicals) + if(initial(thing.name) == reagent_choice) + learned_reagent = reagent_choice + + cortical_owner.known_chemicals += learned_reagent cortical_owner.chemical_evolution -= chemical_evo_points - cortical_owner.known_chemicals += reagent_choice cortical_owner.potential_chemicals -= reagent_choice + owner.balloon_alert(owner, "[initial(learned_reagent.name)] learned") + if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) + to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(learned_reagent.taste_description)]!")) + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) if(victim_brain) cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) - owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") - if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) - to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) + StartCooldown() /** From 2d7d5f641025cb5088e545a63d981507a580910e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 27 Jan 2024 02:22:28 +0100 Subject: [PATCH 13/67] fixes --- .../borers/code/abilities/learn_chemicals.dm | 8 ++--- .../borers/code/mobs/cortical_borer.dm | 36 ++++++++++--------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm index 4f6cb75fae61..22a5976221a7 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -45,13 +45,13 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) return var/datum/reagent/learned_reagent - for(var/datum/reagent/thing as anything in cortical_owner.potential_chemicals) - if(initial(thing.name) == reagent_choice) - learned_reagent = reagent_choice + for(var/datum/reagent/chemical as anything in cortical_owner.potential_chemicals) + if(initial(chemical.name) == reagent_choice) + learned_reagent = chemical cortical_owner.known_chemicals += learned_reagent cortical_owner.chemical_evolution -= chemical_evo_points - cortical_owner.potential_chemicals -= reagent_choice + cortical_owner.potential_chemicals -= learned_reagent owner.balloon_alert(owner, "[initial(learned_reagent.name)] learned") if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(learned_reagent.taste_description)]!")) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index fd53badb8117..8ed4604aed2a 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -100,29 +100,33 @@ GLOBAL_LIST_EMPTY(cortical_borers) var/list/known_chemicals = list() ///what chemicals the borer can learn var/list/potential_chemicals = list( - /datum/reagent/medicine/antipathogenic/spaceacillin, - /datum/reagent/medicine/potass_iodide, - /datum/reagent/medicine/diphenhydramine, - /datum/reagent/medicine/epinephrine, - /datum/reagent/medicine/haloperidol, - /datum/reagent/toxin/formaldehyde, + /datum/reagent/drug/methamphetamine/borer_version, + /datum/reagent/impurity/libitoil, /datum/reagent/impurity/mannitol, - /datum/reagent/medicine/c2/libital, - /datum/reagent/medicine/c2/lenturi, + + /datum/reagent/lithium, + + /datum/reagent/medicine/antipathogenic/spaceacillin, /datum/reagent/medicine/c2/convermol, - /datum/reagent/medicine/c2/seiver, + /datum/reagent/medicine/c2/lenturi, + /datum/reagent/medicine/c2/libital, /datum/reagent/medicine/c2/multiver, - /datum/reagent/lithium, - /datum/reagent/medicine/salglu_solution, - /datum/reagent/medicine/mutadone, - /datum/reagent/toxin/heparin, - /datum/reagent/drug/methamphetamine/borer_version, - /datum/reagent/medicine/morphine, + /datum/reagent/medicine/c2/seiver, + /datum/reagent/medicine/diphenhydramine, + /datum/reagent/medicine/epinephrine, + /datum/reagent/medicine/haloperidol, /datum/reagent/medicine/inacusiate, + /datum/reagent/medicine/mannitol, + /datum/reagent/medicine/morphine, + /datum/reagent/medicine/mutadone, /datum/reagent/medicine/oculine, + /datum/reagent/medicine/potass_iodide, + /datum/reagent/medicine/salglu_solution, + + /datum/reagent/toxin/formaldehyde, + /datum/reagent/toxin/heparin, /datum/reagent/toxin/mindbreaker, - /datum/reagent/medicine/mannitol, ) //blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these var/list/blacklisted_chemicals = list() From 03f35294436992e7d8aa39ced00bcf117481dc86 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 27 Jan 2024 02:48:26 +0100 Subject: [PATCH 14/67] requested changes --- .../modules/antagonists/borers/code/mobs/cortical_borer.dm | 2 ++ monkestation/code/modules/antagonists/borers/readme.md | 1 + monkestation/code/modules/uplink/uplink_items/misc.dm | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 8ed4604aed2a..f228cd141b08 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -108,11 +108,13 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/reagent/lithium, /datum/reagent/medicine/antipathogenic/spaceacillin, + /datum/reagent/medicine/c2/convermol, /datum/reagent/medicine/c2/lenturi, /datum/reagent/medicine/c2/libital, /datum/reagent/medicine/c2/multiver, /datum/reagent/medicine/c2/seiver, + /datum/reagent/medicine/diphenhydramine, /datum/reagent/medicine/epinephrine, /datum/reagent/medicine/haloperidol, diff --git a/monkestation/code/modules/antagonists/borers/readme.md b/monkestation/code/modules/antagonists/borers/readme.md index db4cfa544839..5d18680130ec 100644 --- a/monkestation/code/modules/antagonists/borers/readme.md +++ b/monkestation/code/modules/antagonists/borers/readme.md @@ -32,4 +32,5 @@ tgui\packages\tgui\interfaces\BorerEvolution.tsx Jake Park - Original borer Code /vg/station - Partial Icons +Zonespace - Lots of TGUI work, and gave borers the evolution tree Gboster - Porting the code to monkestation diff --git a/monkestation/code/modules/uplink/uplink_items/misc.dm b/monkestation/code/modules/uplink/uplink_items/misc.dm index 0fa9dd55ce5b..f72294a1957d 100644 --- a/monkestation/code/modules/uplink/uplink_items/misc.dm +++ b/monkestation/code/modules/uplink/uplink_items/misc.dm @@ -11,14 +11,14 @@ name = "Neutered borer egg" desc = "A borer egg specifically bred to aid operatives. \ It will obey every command and protect whatever operative they first see when hatched. \ - Unfortunatelly due to extreme radiation exposure, they cannot reproduce." + Unfortunately due to extreme radiation exposure, they cannot reproduce." purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) item = /obj/effect/mob_spawn/ghost_role/borer_egg/neutered cost = 20 /datum/uplink_item/device_tools/borer_egg name = "Hive queen borer egg" - desc = "A borer egg of a queen we captured and safelly stored away. \ + desc = "A borer egg of a queen we captured and safely stored away. \ Be warned, the borer queen is not necessarily allied to you." purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) item = /obj/effect/mob_spawn/ghost_role/borer_egg From 228e616fb2cd7b33e443b92ae751c8ecc455c45e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 27 Jan 2024 03:21:11 +0100 Subject: [PATCH 15/67] better blood learning --- .../borers/code/abilities/learn_chemicals.dm | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm index 22a5976221a7..ced38d1b8f3c 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -30,9 +30,10 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) owner.balloon_alert(owner, "all chemicals learned") return + // Give the chemicals we can learn all proper names instead of datum/chemical/whatever, and show that to the user var/named_chemicals = list() - for(var/datum/reagent/thing as anything in cortical_owner.potential_chemicals) - named_chemicals += initial(thing.name) + for(var/datum/reagent/learnable_chemical as anything in cortical_owner.potential_chemicals) + named_chemicals += initial(learnable_chemical.name) var/reagent_choice = tgui_input_list( cortical_owner, @@ -44,6 +45,7 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) owner.balloon_alert(owner, "no chemical chosen") return + // We only know the chosen chemicals name at this point, so we gotta check what chemical do we actually give them var/datum/reagent/learned_reagent for(var/datum/reagent/chemical as anything in cortical_owner.potential_chemicals) if(initial(chemical.name) == reagent_choice) @@ -52,7 +54,8 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) cortical_owner.known_chemicals += learned_reagent cortical_owner.chemical_evolution -= chemical_evo_points cortical_owner.potential_chemicals -= learned_reagent - owner.balloon_alert(owner, "[initial(learned_reagent.name)] learned") + + owner.balloon_alert(owner, "[initial(reagent_choice)] learned") if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(learned_reagent.taste_description)]!")) @@ -78,33 +81,57 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner + if(length(cortical_owner.human_host.reagents.reagent_list) <= 0) owner.balloon_alert(owner, "no reagents in host") return - var/datum/reagent/reagent_choice = tgui_input_list(cortical_owner, "Choose a chemical to learn.", "Chemical Selection", cortical_owner.human_host.reagents.reagent_list) + + // Give the chemicals we can learn all proper names instead of datum/chemical/whatever, and show that to the user + var/named_chemicals = list() + for(var/datum/reagent/learnable_chemical as anything in cortical_owner.human_host.reagents.reagent_list) + named_chemicals += initial(learnable_chemical.name) + + var/reagent_choice = tgui_input_list( + cortical_owner, + "Choose a chemical to learn.", + "Chemical Selection", + named_chemicals, + ) if(!reagent_choice) - owner.balloon_alert(owner, "chemical not chosen") + owner.balloon_alert(owner, "no chemical chosen") return - if(locate(reagent_choice) in cortical_owner.known_chemicals) + + // We only know the chosen chemicals name at this point, so we gotta check what chemical do we actually give them + var/datum/reagent/learned_reagent + for(var/datum/reagent/chemical as anything in cortical_owner.human_host.reagents.reagent_list) + if(initial(chemical.name) == reagent_choice) + learned_reagent = chemical + + if(locate(learned_reagent) in cortical_owner.known_chemicals) owner.balloon_alert(owner, "chemical already known") return - if(locate(reagent_choice) in cortical_owner.blacklisted_chemicals) + if(locate(learned_reagent) in cortical_owner.blacklisted_chemicals) owner.balloon_alert(owner, "chemical blacklisted") return - if(!(reagent_choice.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) - owner.balloon_alert(owner, "cannot learn [initial(reagent_choice.name)]") + if(!(learned_reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) + owner.balloon_alert(owner, "cannot learn [initial(reagent_choice)]") return + cortical_owner.chemical_evolution -= chemical_evo_points - cortical_owner.known_chemicals += reagent_choice.type + cortical_owner.known_chemicals += learned_reagent.type cortical_owner.blood_chems_learned++ + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) if(victim_brain) cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * cortical_owner.host_harm_multiplier) + if(cortical_owner.blood_chems_learned == BLOOD_CHEM_OBJECTIVE) GLOB.successful_blood_chem += 1 - owner.balloon_alert(owner, "[initial(reagent_choice.name)] learned") + + owner.balloon_alert(owner, "[initial(reagent_choice)] learned") if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) - to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(reagent_choice.taste_description)]!")) + to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(learned_reagent.taste_description)]!")) + StartCooldown() #undef BLOOD_CHEM_OBJECTIVE From 7a145027350c3044a972d94bc5121c950d9cc3e3 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 27 Jan 2024 13:48:11 +0100 Subject: [PATCH 16/67] alphabetical lists --- code/_globalvars/lists/poll_ignore.dm | 4 ++-- code/modules/admin/sql_ban_system.dm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index c9b10eb43d60..eee6e1b92910 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -1,6 +1,5 @@ //Each lists stores ckeys for "Never for this round" option category -#define POLL_IGNORE_CORTICAL_BORER "cortical_borer" // MONKESTATION ADDITION -- CORTICAL_BORERS #define POLL_IGNORE_ACADEMY_WIZARD "academy_wizard" #define POLL_IGNORE_ALIEN_LARVA "alien_larva" #define POLL_IGNORE_ASH_SPIRIT "ash_spirit" @@ -10,6 +9,7 @@ #define POLL_IGNORE_CARGORILLA "cargorilla" #define POLL_IGNORE_CONTRACTOR_SUPPORT "contractor_support" #define POLL_IGNORE_CONSTRUCT "construct" +#define POLL_IGNORE_CORTICAL_BORER "cortical_borer" // MONKESTATION ADDITION -- CORTICAL_BORERS #define POLL_IGNORE_DRONE "drone" #define POLL_IGNORE_FIRE_SHARK "fire_shark" #define POLL_IGNORE_FUGITIVE "fugitive" @@ -39,7 +39,6 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( - POLL_IGNORE_CORTICAL_BORER = "Cortical Borer", // MONKESTATION ADDITION -- CORTICAL_BORERS POLL_IGNORE_ACADEMY_WIZARD = "Academy Wizard Defender", POLL_IGNORE_ALIEN_LARVA = "Xenomorph larva", POLL_IGNORE_ASH_SPIRIT = "Ash Spirit", @@ -49,6 +48,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_CARGORILLA = "Cargorilla", POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit", POLL_IGNORE_CONSTRUCT = "Construct", + POLL_IGNORE_CORTICAL_BORER = "Cortical Borer", // MONKESTATION ADDITION -- CORTICAL_BORERS POLL_IGNORE_DRONE = "Drone shells", POLL_IGNORE_FIRE_SHARK = "Fire Shark", POLL_IGNORE_FUGITIVE = "Fugitive Hunter", diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index d2ad68674bae..3c7e8b8e1e8d 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -348,6 +348,7 @@ ROLE_BROTHER, ROLE_BLOODSUCKER, ROLE_BLOODSUCKERBREAKOUT, + ROLE_BORER, // MONKESTATION ADDITION -- CORTICAL_BORERS ROLE_CHANGELING, ROLE_CLOCK_CULTIST, ROLE_CULTIST, @@ -369,7 +370,6 @@ ROLE_TRAITOR, ROLE_VAMPIRICACCIDENT, ROLE_WIZARD, - ROLE_BORER, // MONKESTATION ADDITION -- CORTICAL_BORERS ), ) for(var/department in long_job_lists) From 1d519519933c005d9c6ff7da091fcb416404de5e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 28 Jan 2024 05:03:12 +0100 Subject: [PATCH 17/67] moar variables for controlling ability requirements --- .../borers/code/abilities/_ability.dm | 22 +++++++++++++++---- .../borers/code/abilities/revive_host.dm | 1 + .../borers/code/abilities/spawn_offspring.dm | 8 ++----- .../borers/code/cortical_borer_antagonist.dm | 1 - .../borers/code/cortical_borer_chems.dm | 1 + 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm index 26fd66c4b5e6..21dbe3b1b379 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm @@ -2,14 +2,20 @@ /datum/action/cooldown/borer button_icon = 'monkestation/code/modules/antagonists/borers/icons/actions.dmi' cooldown_time = 0 + /// How many chemicals this costs var/chemical_cost = 0 /// How many chem evo points are needed to use this ability var/chemical_evo_points = 0 /// How many stat evo points are needed to use this ability var/stat_evo_points = 0 + /// Does this ability need a human host to be triggered? var/requires_host = FALSE + /// Can this ability function within a living host? + var/needs_living_host = FALSE + /// Can this ability function within a dead host? + var/needs_dead_host = FALSE /// Does this ability stop working when the host has sugar? var/sugar_restricted = FALSE @@ -26,20 +32,28 @@ /datum/action/cooldown/borer/Trigger(trigger_flags, atom/target) . = ..() + + // Safety checks if(!iscorticalborer(owner)) to_chat(owner, span_warning("You must be a cortical borer to use this action!")) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(owner.stat == DEAD) - return FALSE + // Status Requirements if(requires_host == TRUE && !cortical_owner.inside_human()) owner.balloon_alert(owner, "host required") - return + return FALSE + if(needs_living_host == TRUE && owner.stat == DEAD) + owner.balloon_alert(owner, "Alive host required") + return FALSE + if(needs_dead_host == TRUE && !owner.stat == DEAD) + owner.balloon_alert(owner, "Dead host required") + return FALSE if(sugar_restricted == TRUE && cortical_owner.host_sugar()) owner.balloon_alert(owner, "cannot function with sugar in host") - return + return FALSE + // Resource costs if(cortical_owner.chemical_storage < chemical_cost) cortical_owner.balloon_alert(cortical_owner, "need [chemical_cost] chemicals") return FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm index bf8873f78b53..2c9f27d62ed4 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm @@ -6,6 +6,7 @@ chemical_cost = 200 requires_host = TRUE sugar_restricted = TRUE + needs_dead_host = TRUE /datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index f9b46bb25117..ebbe75a8019c 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -6,6 +6,7 @@ cooldown_time = 1 MINUTES button_icon_state = "reproduce" chemical_cost = 100 + needs_living_host = TRUE /datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags, atom/target) . = ..() @@ -18,9 +19,6 @@ if(!(cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) owner.balloon_alert(owner, "host required") return - if(cortical_owner.human_host.stat == DEAD) - owner.balloon_alert(owner, "host dead") - return cortical_owner.chemical_storage -= chemical_cost if((cortical_owner.upgrade_flags & BORER_ALONE_PRODUCTION) && !cortical_owner.inside_human()) no_host_egg() @@ -78,6 +76,7 @@ button_icon_state = "reproduce" chemical_cost = 150 requires_host = TRUE + needs_dead_host = TRUE /datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) . = ..() @@ -87,9 +86,6 @@ if(cortical_owner.neutered == TRUE) owner.balloon_alert(owner, "You cannot reproduce!") return - if(cortical_owner.human_host.stat != DEAD) - owner.balloon_alert(owner, "host not dead") - return cortical_owner.chemical_storage -= chemical_cost var/turf/borer_turf = get_turf(cortical_owner) diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm index 64f3c20aedd0..c23b13b7cf6a 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm @@ -32,7 +32,6 @@ /datum/antagonist/cortical_borer name = "Cortical Borer" job_rank = ROLE_BORER - show_in_antagpanel = TRUE roundend_category = "cortical borers" antagpanel_category = "Cortical Borers" prevent_roundtype_conversion = FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm index cfc66ac86448..2ad142cc7579 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm @@ -1,3 +1,4 @@ +// Double the OD treshold, no brain damage /datum/reagent/drug/methamphetamine/borer_version name = "Unknown Methamphetamine Isomer" overdose_threshold = 40 From c1e21d152983609cae8892573e456d8d2ea2bb4b Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 28 Jan 2024 05:17:13 +0100 Subject: [PATCH 18/67] removes the debug borer (it isnt helpfull for debugging, may return later) --- .../borers/code/abilities/_debug_abilities.dm | 19 ----------------- .../borers/code/items/debug_egg.dm | 21 ------------------- tgstation.dme | 2 -- 3 files changed, 42 deletions(-) delete mode 100644 monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm delete mode 100644 monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm deleted file mode 100644 index 6982956805c8..000000000000 --- a/monkestation/code/modules/antagonists/borers/code/abilities/_debug_abilities.dm +++ /dev/null @@ -1,19 +0,0 @@ -/datum/action/cooldown/borer/gain_evolution_point - name = "DEBUG: Gain an evolution point" - button_icon_state = "level" - -/datum/action/cooldown/borer/gain_evolution_point/Trigger(trigger_flags, atom/target) - . = ..() - var/mob/living/basic/cortical_borer/cortical_owner = owner - cortical_owner.stat_evolution++ - to_chat(src, span_notice("You gain a stat evolution point. Spend it to become stronger!")) - -/datum/action/cooldown/borer/gain_chemical_point - name = "DEBUG: Gain maximum possible chemicals" - button_icon_state = "level" - -/datum/action/cooldown/borer/gain_chemical_point/Trigger(trigger_flags, atom/target) - . = ..() - var/mob/living/basic/cortical_borer/cortical_owner = owner - cortical_owner.chemical_evolution++ - to_chat(src, span_notice("You gain a chemical evolution point. Spend it to learn a new chemical!")) diff --git a/monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm deleted file mode 100644 index 7e5c72005196..000000000000 --- a/monkestation/code/modules/antagonists/borers/code/items/debug_egg.dm +++ /dev/null @@ -1,21 +0,0 @@ -/obj/effect/mob_spawn/ghost_role/borer_egg/debug - name = "debug cortical borer egg" - desc = "An egg of a creature that is known to crawl inside of you. This one looks REALLY DANGEROUS. Consider calling nuclear operatives." - mob_type = /mob/living/basic/cortical_borer/debug - -/mob/living/basic/cortical_borer/debug - 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/force_speak, - /datum/action/cooldown/borer/fear_human, - /datum/action/cooldown/borer/check_blood, - - /datum/action/cooldown/borer/gain_evolution_point, - /datum/action/cooldown/borer/gain_chemical_point, - ) diff --git a/tgstation.dme b/tgstation.dme index 4281287221ec..8a1609065293 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5739,7 +5739,6 @@ #include "monkestation\code\modules\antagonists\borers\code\focus_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\status_effects.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\_ability.dm" -#include "monkestation\code\modules\antagonists\borers\code\abilities\_debug_abilities.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\chemical_injector.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\enter_host.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\evolution_tree.dm" @@ -5760,7 +5759,6 @@ #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_general.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_hivelord.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_symbiote.dm" -#include "monkestation\code\modules\antagonists\borers\code\items\debug_egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\empowered_egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\imprisonment_cage.dm" From a5842f1c619570bea4859c1eb7d994d6203cd0bd Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 28 Jan 2024 06:23:32 +0100 Subject: [PATCH 19/67] midround borers maybe? --- .../antagonists/borers/code/midround_event.dm | 108 ++++++++++++++++++ .../code/modules/uplink/uplink_items/misc.dm | 8 -- tgstation.dme | 1 + 3 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 monkestation/code/modules/antagonists/borers/code/midround_event.dm diff --git a/monkestation/code/modules/antagonists/borers/code/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/midround_event.dm new file mode 100644 index 000000000000..a3e91be85dc9 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/midround_event.dm @@ -0,0 +1,108 @@ +/datum/round_event_control/antagonist/solo/from_ghosts/cortical_borer + name = "Cortical Borer Infestation" + tags = list(TAG_TEAM_ANTAG, TAG_EXTERNAL, TAG_ALIEN) + typepath = /datum/round_event/ghost_role/cortical_borer + antag_flag = ROLE_BORER + enemy_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + ) + required_enemies = 1 + weight = 5 // as rare as a natural blob + min_players = 10 + max_occurrences = 1 //should only ever happen once + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "A cortical borer has appeared on station. It will also attempt to produce eggs, and will attempt to gather willing hosts and learn chemicals through the blood." + +/datum/round_event/ghost_role/cortical_borer + announce_when = 400 + +/datum/round_event/ghost_role/cortical_borer/setup() + announce_when = rand(announce_when, announce_when + 50) + +/datum/round_event/ghost_role/cortical_borer/announce(fake) + priority_announce( + "Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", + "Lifesign Alert", + ANNOUNCER_ALIENS, + ) + +/datum/round_event/ghost_role/cortical_borer/start() + var/list/vents = list() + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) + if(QDELETED(temp_vent)) + continue + if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] + if(!temp_vent_parent) + continue // No parent vent + // Stops Cortical Borers getting stuck in small networks. + // See: Security, Virology + if(length(temp_vent_parent.other_atmos_machines) > 20) + vents += temp_vent + if(!length(vents)) + return MAP_ERROR + var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER) + if(!length(candidates)) + return NOT_ENOUGH_PLAYERS + var/living_number = max(length(GLOB.player_list) / POP_PER_BORER, 1) + var/choosing_number = min(length(candidates), living_number) + for(var/repeating_code in 1 to choosing_number) + var/mob/dead/observer/new_borer = pick(candidates) + candidates -= new_borer + var/turf/vent_turf = get_turf(pick(vents)) + var/mob/living/basic/cortical_borer/spawned_cb = new /mob/living/basic/cortical_borer(vent_turf) + spawned_cb.ckey = new_borer.ckey + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) + to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) + for(var/mob/dead_mob in GLOB.dead_mob_list) + to_chat(dead_mob, span_notice("The cortical borers have been selected, you are able to orbit them! Remember, they can reproduce!")) + +/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer + name = "Cortical Borer Infestation" + antag_datum = /datum/antagonist/cortical_borer + midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY + antag_flag = ROLE_BORER + enemy_roles = list( + JOB_CAPTAIN, + JOB_DETECTIVE, + JOB_HEAD_OF_SECURITY, + JOB_SECURITY_OFFICER, + ) + required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_candidates = 1 + weight = 3 + cost = 30 + minimum_players = 10 + /// List of on-station vents + var/list/vents = list() + +/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/execute() + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) + if(QDELETED(temp_vent)) + continue + if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] + if(!temp_vent_parent) + continue // No parent vent + // Stops Borers getting stuck in small networks. + // See: Security, Virology + if(length(temp_vent_parent.other_atmos_machines) > 20) + vents += temp_vent + if(!length(vents)) + return FALSE + return TRUE + +/datum/dynamic_ruleset/midround/from_ghosts/cortical_borer/generate_ruleset_body(mob/applicant) + var/obj/vent = pick_n_take(vents) + var/mob/living/basic/cortical_borer/new_borer = new(vent.loc) + new_borer.key = applicant.key + new_borer.move_into_vent(vent) + message_admins("[ADMIN_LOOKUPFLW(new_borer)] has been made into a borer by the midround ruleset.") + log_game("DYNAMIC: [key_name(new_borer)] was spawned as a borer by the midround ruleset.") + return new_borer + +#undef POP_PER_BORER diff --git a/monkestation/code/modules/uplink/uplink_items/misc.dm b/monkestation/code/modules/uplink/uplink_items/misc.dm index f72294a1957d..a1000754a0b8 100644 --- a/monkestation/code/modules/uplink/uplink_items/misc.dm +++ b/monkestation/code/modules/uplink/uplink_items/misc.dm @@ -15,11 +15,3 @@ purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) item = /obj/effect/mob_spawn/ghost_role/borer_egg/neutered cost = 20 - -/datum/uplink_item/device_tools/borer_egg - name = "Hive queen borer egg" - desc = "A borer egg of a queen we captured and safely stored away. \ - Be warned, the borer queen is not necessarily allied to you." - purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) - item = /obj/effect/mob_spawn/ghost_role/borer_egg - cost = 30 diff --git a/tgstation.dme b/tgstation.dme index 8a1609065293..8474632ac880 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5737,6 +5737,7 @@ #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_antagonist.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_chems.dm" #include "monkestation\code\modules\antagonists\borers\code\focus_datum.dm" +#include "monkestation\code\modules\antagonists\borers\code\midround_event.dm" #include "monkestation\code\modules\antagonists\borers\code\status_effects.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\_ability.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\chemical_injector.dm" From 9be0621570947d8b537cf19c8b910820eb752415 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 28 Jan 2024 18:55:03 +0100 Subject: [PATCH 20/67] le midround changes --- .../code/modules/antagonists/borers/code/midround_event.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/midround_event.dm index a3e91be85dc9..f131d974e0f7 100644 --- a/monkestation/code/modules/antagonists/borers/code/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/midround_event.dm @@ -9,9 +9,9 @@ JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, ) - required_enemies = 1 + required_enemies = 2 weight = 5 // as rare as a natural blob - min_players = 10 + min_players = 20 max_occurrences = 1 //should only ever happen once dynamic_should_hijack = TRUE category = EVENT_CATEGORY_ENTITIES From 6c4a2d09f8332384dacb2d9b7178e291297ee2dc Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 29 Jan 2024 03:02:14 +0100 Subject: [PATCH 21/67] adds some spaces, fixes a minor edge-case bug --- .../modules/antagonists/borers/code/abilities/enter_host.dm | 4 ++-- .../modules/antagonists/borers/code/abilities/upgrade_body.dm | 3 +++ .../modules/antagonists/borers/code/abilities/willing_host.dm | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index b0fab9d0ae7a..4c3d50a0b519 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -52,11 +52,11 @@ continue // hosts cannot be changelings unless we specify otherwise if(listed_human.mind) - to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) var/datum/antagonist/changeling/changeling = listed_human.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling && cortical_owner.changeling_restricted) + to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) continue - // hosts cannot have bio protected headgear on + // hosts cannot have bio protected headgear if(check_for_bio_protection(listed_human) == TRUE) to_chat(cortical_owner, span_warning("[listed_human] has too hard of a helmet to crawl inside of their ear!")) continue diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm index 12bda3f47d05..320cc413c2a9 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm @@ -10,15 +10,18 @@ if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner + cortical_owner.stat_evolution -= stat_evo_points 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 cortical_owner.level += 1 + var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) if(victim_brain) cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10 * cortical_owner.host_harm_multiplier) + cortical_owner.human_host.adjust_eye_blur(6 SECONDS * 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!")) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm index 2f451b338496..15fa409cb505 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm @@ -15,13 +15,16 @@ if(ckey_check == cortical_owner.human_host.ckey) owner.balloon_alert(owner, "host already willing") return + owner.balloon_alert(owner, "asking host...") cortical_owner.chemical_storage -= chemical_cost + var/host_choice = tgui_input_list(cortical_owner.human_host,"Do you accept to be a willing host?", "Willing Host Request", list("Yes", "No")) if(host_choice != "Yes") owner.balloon_alert(owner, "host not willing!") StartCooldown() return + owner.balloon_alert(owner, "host willing!") to_chat(cortical_owner.human_host, span_notice("You have accepted being a willing host!")) GLOB.willing_hosts += cortical_owner.human_host.ckey From cb775ce7803bbe666e665ea73ccb1e6340f5233a Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 30 Jan 2024 05:26:57 +0100 Subject: [PATCH 22/67] borer objectives --- .../borers/code/abilities/revive_host.dm | 5 +++++ .../cortical_borer_antagonist.dm | 21 +++++++++++++++++-- .../{ => antagonist_stuff}/midround_event.dm | 2 ++ tgstation.dme | 3 +-- 4 files changed, 27 insertions(+), 4 deletions(-) rename monkestation/code/modules/antagonists/borers/code/{ => antagonist_stuff}/cortical_borer_antagonist.dm (77%) rename monkestation/code/modules/antagonists/borers/code/{ => antagonist_stuff}/midround_event.dm (99%) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm index 2c9f27d62ed4..9b4a136c800c 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm @@ -13,7 +13,9 @@ if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner + cortical_owner.chemical_storage -= chemical_cost + if(cortical_owner.human_host.getBruteLoss()) cortical_owner.human_host.adjustBruteLoss(-(cortical_owner.human_host.getBruteLoss()*0.5)) if(cortical_owner.human_host.getToxLoss()) @@ -22,10 +24,13 @@ cortical_owner.human_host.adjustFireLoss(-(cortical_owner.human_host.getFireLoss()*0.5)) if(cortical_owner.human_host.getOxyLoss()) cortical_owner.human_host.adjustOxyLoss(-(cortical_owner.human_host.getOxyLoss()*0.5)) + if(cortical_owner.human_host.blood_volume < BLOOD_VOLUME_BAD) cortical_owner.human_host.blood_volume = BLOOD_VOLUME_BAD + for(var/obj/item/organ/internal/internal_target in cortical_owner.human_host.organs) internal_target.apply_organ_damage(-internal_target.damage * 0.5) + cortical_owner.human_host.revive() to_chat(cortical_owner.human_host, span_boldwarning("Your heart jumpstarts!")) owner.balloon_alert(owner, "host revived") diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm similarity index 77% rename from monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm rename to monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index c23b13b7cf6a..cfebd79476a9 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -1,5 +1,3 @@ -#define POP_PER_BORER 30 - /proc/printborer(datum/mind/borer) var/list/text = list() var/mob/living/basic/cortical_borer/player_borer = borer.current @@ -39,6 +37,25 @@ /// The team of borers var/datum/team/cortical_borers/borers +/datum/antagonist/cortical_borer/on_gain() + forge_objectives() + return ..() + +/datum/antagonist/cortical_borer/forge_objectives() + var/datum/objective/custom/borer_objective_produce_eggs = new + borer_objective_produce_eggs.explanation_text = "we need to produce [GLOB.objective_egg_egg_number] eggs, \ + we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs" + + var/datum/objective/custom/borer_objective_willing_hosts = new + borer_objective_willing_hosts.explanation_text = "any amount of the borers need to gain [GLOB.objective_willing_hosts] willing hosts" + + var/datum/objective/custom/borer_objective_learn_chemicals = new + borer_objective_learn_chemicals.explanation_text = "any amount of the borers need to learn [GLOB.objective_blood_borer] chemicals from blood" + + objectives += borer_objective_produce_eggs + objectives += borer_objective_willing_hosts + objectives += borer_objective_learn_chemicals + /datum/antagonist/cortical_borer/get_preview_icon() return finish_preview_icon(icon('monkestation/code/modules/antagonists/borers/icons/animal.dmi', "brainslug")) diff --git a/monkestation/code/modules/antagonists/borers/code/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm similarity index 99% rename from monkestation/code/modules/antagonists/borers/code/midround_event.dm rename to monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index f131d974e0f7..00a78831d4a1 100644 --- a/monkestation/code/modules/antagonists/borers/code/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -1,3 +1,5 @@ +#define POP_PER_BORER 30 + /datum/round_event_control/antagonist/solo/from_ghosts/cortical_borer name = "Cortical Borer Infestation" tags = list(TAG_TEAM_ANTAG, TAG_EXTERNAL, TAG_ALIEN) diff --git a/tgstation.dme b/tgstation.dme index 8474632ac880..b49187a3bd1a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5734,10 +5734,8 @@ #include "monkestation\code\modules\aesthetics\subsystem\coloring.dm" #include "monkestation\code\modules\aesthetics\walls\iron.dm" #include "monkestation\code\modules\antagonists\_common\antag_datum.dm" -#include "monkestation\code\modules\antagonists\borers\code\cortical_borer_antagonist.dm" #include "monkestation\code\modules\antagonists\borers\code\cortical_borer_chems.dm" #include "monkestation\code\modules\antagonists\borers\code\focus_datum.dm" -#include "monkestation\code\modules\antagonists\borers\code\midround_event.dm" #include "monkestation\code\modules\antagonists\borers\code\status_effects.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\_ability.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\chemical_injector.dm" @@ -5754,6 +5752,7 @@ #include "monkestation\code\modules\antagonists\borers\code\abilities\toggle_stealth.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\upgrade_body.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\willing_host.dm" +#include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\cortical_borer_antagonist.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\borer_evolution.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_diveworm.dm" From 96c42a55f128d6fede50d73753b6d844f75b40e9 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 30 Jan 2024 05:55:33 +0100 Subject: [PATCH 23/67] borer hiding ability cleanup --- .../borers/code/abilities/toggle_stealth.dm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm index 370d5a565ab3..1b30bee3c97e 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm @@ -2,22 +2,25 @@ * Allows you to hide under tables or bodies * Without this, borers are really weak due to NEEDING players being blind or consenting */ + /datum/action/cooldown/borer/toggle_hiding name = "Toggle Hiding" button_icon_state = "hide" + var/hide_layer = ABOVE_NORMAL_TURF_LAYER /datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - if(owner.layer == PROJECTILE_HIT_THRESHHOLD_LAYER) + if(owner.layer != hide_layer) + cortical_owner.upgrade_flags |= BORER_HIDING + owner.balloon_alert(owner, "started hiding") + owner.layer = hide_layer + + else 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() From 3a70774206c3b5086844cbcb216f620d6365055e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 30 Jan 2024 09:31:35 +0100 Subject: [PATCH 24/67] some cleanup --- .../borers/code/abilities/spawn_offspring.dm | 1 + .../borers/code/abilities/toggle_stealth.dm | 5 -- .../cortical_borer_antagonist.dm | 72 +++---------------- .../code/antagonist_stuff/midround_event.dm | 1 + .../code/antagonist_stuff/round_end_text.dm | 58 +++++++++++++++ .../borers/code/mobs/cortical_borer.dm | 1 - .../borers/code/mobs/neutered_borer.dm | 2 + tgstation.dme | 1 + 8 files changed, 74 insertions(+), 67 deletions(-) create mode 100644 monkestation/code/modules/antagonists/borers/code/antagonist_stuff/round_end_text.dm diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index ebbe75a8019c..5a8ca51a6eb9 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -1,3 +1,4 @@ +/// How much health do we take from the borer if its producing eggs without a host? #define OUT_OF_HOST_EGG_COST 50 //we need a way to produce offspring diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm index 1b30bee3c97e..809aa3c63963 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm @@ -1,8 +1,3 @@ -/** - * Allows you to hide under tables or bodies - * Without this, borers are really weak due to NEEDING players being blind or consenting - */ - /datum/action/cooldown/borer/toggle_hiding name = "Toggle Hiding" button_icon_state = "hide" diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index cfebd79476a9..4a90e2cf60ca 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -1,32 +1,3 @@ -/proc/printborer(datum/mind/borer) - var/list/text = list() - var/mob/living/basic/cortical_borer/player_borer = borer.current - if(!player_borer) - text += span_redtext("[span_bold(borer.name)] had their body destroyed.") - return text.Join("
") - if(borer.current.stat != DEAD) - text += "[span_bold(player_borer.name)] [span_greentext("survived")]" - else - text += "[span_bold(player_borer.name)] [span_redtext("died")]" - text += span_bold("[span_bold(player_borer.name)] produced [player_borer.children_produced] borers.") - var/list/string_of_genomes = list() - - for(var/evo_index in player_borer.past_evolutions) - var/datum/borer_evolution/evolution = player_borer.past_evolutions[evo_index] - string_of_genomes += evolution.name - - text += "[span_bold(player_borer.name)] had the following evolutions: [english_list(string_of_genomes)]" - return text.Join("
") - -/proc/printborerlist(list/players,fleecheck) - var/list/parts = list() - - parts += "
    " - for(var/datum/mind/M in players) - parts += "
  • [printborer(M)]
  • " - parts += "
" - return parts.Join("
") - /datum/antagonist/cortical_borer name = "Cortical Borer" job_rank = ROLE_BORER @@ -43,14 +14,13 @@ /datum/antagonist/cortical_borer/forge_objectives() var/datum/objective/custom/borer_objective_produce_eggs = new - borer_objective_produce_eggs.explanation_text = "we need to produce [GLOB.objective_egg_egg_number] eggs, \ - we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs" + borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly to reduce the chances of survival" var/datum/objective/custom/borer_objective_willing_hosts = new - borer_objective_willing_hosts.explanation_text = "any amount of the borers need to gain [GLOB.objective_willing_hosts] willing hosts" + borer_objective_willing_hosts.explanation_text = "we require any amount of the borers to get [GLOB.objective_willing_hosts] willing host's trust to ensure our survival" var/datum/objective/custom/borer_objective_learn_chemicals = new - borer_objective_learn_chemicals.explanation_text = "any amount of the borers need to learn [GLOB.objective_blood_borer] chemicals from blood" + borer_objective_learn_chemicals.explanation_text = "we require any amount of the borers to learn [GLOB.objective_blood_borer] chemicals from blood to aquire further chemical insight" objectives += borer_objective_produce_eggs objectives += borer_objective_willing_hosts @@ -77,32 +47,12 @@ stack_trace("Wrong team type passed to [type] initialization.") borers = new_team -/datum/team/cortical_borers - name = "Cortical Borers" +/datum/antagonist/cortical_borer/neutered + name = "Neutered Cortical Borer" + roundend_category = "neutered cortical borers" + +/datum/antagonist/cortical_borer/neutered/forge_objectives() + var/datum/objective/custom/borer_objective_protect_target = new + borer_objective_protect_target.explanation_text = "Protect whomever was nearest to the egg when you hatched" -/datum/team/cortical_borers/roundend_report() - var/list/parts = list() - parts += span_header("The [name] were:") - parts += printborerlist(members) - var/survival = FALSE - for(var/mob/living/basic/cortical_borer/check_borer in GLOB.cortical_borers) - if(check_borer.stat == DEAD) - continue - survival = TRUE - if(survival) - parts += span_greentext("Borers were able to survive the shift!") - else - parts += span_redtext("Borers were unable to survive the shift!") - if(GLOB.successful_egg_number >= GLOB.objective_egg_borer_number) - parts += span_greentext("Borers were able to produce enough eggs!") - else - parts += span_redtext("Borers were unable to produce enough eggs!") - if(length(GLOB.willing_hosts) >= GLOB.objective_willing_hosts) - parts += span_greentext("Borers were able to gather enough willing hosts!") - else - parts += span_redtext("Borers were unable to gather enough willing hosts!") - if(GLOB.successful_blood_chem >= GLOB.objective_blood_borer) - parts += span_greentext("Borers were able to learn enough chemicals through the blood!") - else - parts += span_redtext("Borers were unable to learn enough chemicals through the blood!") - return "
[parts.Join("
")]
" + objectives += borer_objective_protect_target diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index 00a78831d4a1..396f18b3704c 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -1,3 +1,4 @@ +/// How many people do we need per borer spawned #define POP_PER_BORER 30 /datum/round_event_control/antagonist/solo/from_ghosts/cortical_borer diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/round_end_text.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/round_end_text.dm new file mode 100644 index 000000000000..0c8ba9a417bf --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/round_end_text.dm @@ -0,0 +1,58 @@ +/proc/printborer(datum/mind/borer) + var/list/text = list() + var/mob/living/basic/cortical_borer/player_borer = borer.current + if(!player_borer) + text += span_redtext("[span_bold(borer.name)] had their body destroyed.") + return text.Join("
") + if(borer.current.stat != DEAD) + text += "[span_bold(player_borer.name)] [span_greentext("survived")]" + else + text += "[span_bold(player_borer.name)] [span_redtext("died")]" + text += span_bold("[span_bold(player_borer.name)] produced [player_borer.children_produced] borers.") + var/list/string_of_genomes = list() + + for(var/evo_index in player_borer.past_evolutions) + var/datum/borer_evolution/evolution = player_borer.past_evolutions[evo_index] + string_of_genomes += evolution.name + + text += "[span_bold(player_borer.name)] had the following evolutions: [english_list(string_of_genomes)]" + return text.Join("
") + +/proc/printborerlist(list/players,fleecheck) + var/list/parts = list() + + parts += "
    " + for(var/datum/mind/M in players) + parts += "
  • [printborer(M)]
  • " + parts += "
" + return parts.Join("
") + +/datum/team/cortical_borers + name = "Cortical Borers" + +/datum/team/cortical_borers/roundend_report() + var/list/parts = list() + parts += span_header("The [name] were:") + parts += printborerlist(members) + var/survival = FALSE + for(var/mob/living/basic/cortical_borer/check_borer in GLOB.cortical_borers) + if(check_borer.stat == DEAD) + continue + survival = TRUE + if(survival) + parts += span_greentext("Borers were able to survive the shift!") + else + parts += span_redtext("Borers were unable to survive the shift!") + if(GLOB.successful_egg_number >= GLOB.objective_egg_borer_number) + parts += span_greentext("Borers were able to produce enough eggs!") + else + parts += span_redtext("Borers were unable to produce enough eggs!") + if(length(GLOB.willing_hosts) >= GLOB.objective_willing_hosts) + parts += span_greentext("Borers were able to gather enough willing hosts!") + else + parts += span_redtext("Borers were unable to gather enough willing hosts!") + if(GLOB.successful_blood_chem >= GLOB.objective_blood_borer) + parts += span_greentext("Borers were able to learn enough chemicals through the blood!") + else + parts += span_redtext("Borers were unable to learn enough chemicals through the blood!") + return "
[parts.Join("
")]
" diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index f228cd141b08..0e5cd44732bc 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -103,7 +103,6 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/reagent/drug/methamphetamine/borer_version, /datum/reagent/impurity/libitoil, - /datum/reagent/impurity/mannitol, /datum/reagent/lithium, diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm index 0b31e3fd1b6b..241d0a6a2729 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm @@ -4,3 +4,5 @@ /mob/living/basic/cortical_borer/neutered neutered = TRUE + antagonist_datum = /datum/antagonist/cortical_borer/neutered + generation = 1 diff --git a/tgstation.dme b/tgstation.dme index b49187a3bd1a..274486d6dc9e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5753,6 +5753,7 @@ #include "monkestation\code\modules\antagonists\borers\code\abilities\upgrade_body.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\willing_host.dm" #include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\cortical_borer_antagonist.dm" +#include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\round_end_text.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\borer_evolution.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_diveworm.dm" From ad84bdc78ff7865595f3adbdfa03dc7fbf277e44 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 30 Jan 2024 14:44:43 +0100 Subject: [PATCH 25/67] small objective text change --- .../borers/code/antagonist_stuff/cortical_borer_antagonist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index 4a90e2cf60ca..f0c9c654de1c 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -53,6 +53,6 @@ /datum/antagonist/cortical_borer/neutered/forge_objectives() var/datum/objective/custom/borer_objective_protect_target = new - borer_objective_protect_target.explanation_text = "Protect whomever was nearest to the egg when you hatched" + borer_objective_protect_target.explanation_text = "Protect whomever was nearest to the egg when you hatched, and listen to their every command" objectives += borer_objective_protect_target From b271c26c63a210ce478f9c1ec0f03b6cdd60a57a Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:10:52 +0100 Subject: [PATCH 26/67] requested changes --- .../borers/code/antagonist_stuff/midround_event.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index 396f18b3704c..dd7857c3f52f 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -60,9 +60,8 @@ var/mob/living/basic/cortical_borer/spawned_cb = new /mob/living/basic/cortical_borer(vent_turf) spawned_cb.ckey = new_borer.ckey spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) + announce_to_ghosts(spawned_cb) to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) - for(var/mob/dead_mob in GLOB.dead_mob_list) - to_chat(dead_mob, span_notice("The cortical borers have been selected, you are able to orbit them! Remember, they can reproduce!")) /datum/dynamic_ruleset/midround/from_ghosts/cortical_borer name = "Cortical Borer Infestation" @@ -78,7 +77,7 @@ required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 3 - cost = 30 + cost = 20 minimum_players = 10 /// List of on-station vents var/list/vents = list() From 53725739efc3c3dbd40f66a91bbed15d4198f0ab Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 31 Jan 2024 19:21:53 +0100 Subject: [PATCH 27/67] some misc things --- .../borers/code/antagonist_stuff/midround_event.dm | 8 ++++++++ tgstation.dme | 1 + 2 files changed, 9 insertions(+) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index dd7857c3f52f..f855c6a370f6 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -25,6 +25,7 @@ /datum/round_event/ghost_role/cortical_borer/setup() announce_when = rand(announce_when, announce_when + 50) + setup = TRUE /datum/round_event/ghost_role/cortical_borer/announce(fake) priority_announce( @@ -46,13 +47,19 @@ // See: Security, Virology if(length(temp_vent_parent.other_atmos_machines) > 20) vents += temp_vent + if(!length(vents)) + message_admins("An event attempted to spawn a borer but no suitable vents were found. Shutting down.") return MAP_ERROR + var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER) + if(!length(candidates)) return NOT_ENOUGH_PLAYERS + var/living_number = max(length(GLOB.player_list) / POP_PER_BORER, 1) var/choosing_number = min(length(candidates), living_number) + for(var/repeating_code in 1 to choosing_number) var/mob/dead/observer/new_borer = pick(candidates) candidates -= new_borer @@ -61,6 +68,7 @@ spawned_cb.ckey = new_borer.ckey spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) announce_to_ghosts(spawned_cb) + message_admins("[ADMIN_LOOKUPFLW(spawned_cb)] has been made into a borer by an event.") to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) /datum/dynamic_ruleset/midround/from_ghosts/cortical_borer diff --git a/tgstation.dme b/tgstation.dme index 1fc4bce834c7..cf892a7249e2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5753,6 +5753,7 @@ #include "monkestation\code\modules\antagonists\borers\code\abilities\upgrade_body.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\willing_host.dm" #include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\cortical_borer_antagonist.dm" +#include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\midround_event.dm" #include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\round_end_text.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\borer_evolution.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_datum.dm" From dae920150a24bc9391e6e951e38213ed8f31c5f1 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 1 Feb 2024 00:00:01 +0100 Subject: [PATCH 28/67] boop --- .../borers/code/items/borer_spawner.dm | 43 +++++++++++++++++++ .../borers/code/items/neutered_egg.dm | 19 -------- tgstation.dme | 2 +- 3 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm delete mode 100644 monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm new file mode 100644 index 000000000000..7f4837bd6e02 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -0,0 +1,43 @@ +/obj/item/neutered_borer_spawner + name = "syndicate cortical borer cage" + desc = "The opposite of a harmless cage that is intended to capture cortical borer, \ + as this one contains a borer trained to assist anyone who it first sees in completing their goals." + icon = 'monkestation/code/modules/antagonists/borers/icons/items.dmi' + icon_state = "cage" + var/opened = FALSE // used purelly for sprite manipulation + +/obj/item/neutered_borer_spawner/Initialize(mapload) + . = ..() + update_appearance() + +/obj/item/neutered_borer_spawner/update_overlays() + . = ..() + . += "borer" + if(opened) + . += "doors_open" + else + . += "doors_closed" + +/obj/item/neutered_borer_spawner/attack_self(mob/living/user) + user.visible_message("[user] opens [src].", "You have opened the [src], awaiting for the borer to come out.", "You hear a metallic thunk.") + opened = TRUE + playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + var/list/mob/dead/observer/candidates = poll_ghost_candidates( + "Do you want to play as a neutered cortical borer?", + ROLE_BORER, + poll_time = 5 SECONDS + ) + if(!LAZYLEN(candidates)) + opened = FALSE + to_chat(user, "... After waiting the borer does not seem to come out, maybe try again a bit later?") + playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + + var/mob/dead/observer/spawned_borer = pick(candidates) + var/mob/living/basic/cortical_borer/neutered/new_mob = new /mob/living/basic/cortical_borer/neutered(get_turf(src)) + spawned_borer.mind.transfer_to(new_mob, TRUE) + if(!new_mob.mind.has_antag_datum(/datum/antagonist/cortical_borer/neutered)) + var/datum/antagonist/cortical_borer/neutered/borer_antagonist_datum = new + new_mob.mind.add_antag_datum(borer_antagonist_datum) + + new /obj/item/cortical_cage(get_turf(src)) + QDEL_NULL(src) diff --git a/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm deleted file mode 100644 index 010283d60590..000000000000 --- a/monkestation/code/modules/antagonists/borers/code/items/neutered_egg.dm +++ /dev/null @@ -1,19 +0,0 @@ -/obj/item/borer_egg/neutered - name = "strange borer egg" - icon_state = "empowered_brainegg" - -/obj/effect/mob_spawn/ghost_role/borer_egg/neutered - name = "strange borer egg" - desc = "An egg of a creature that is known to crawl inside of you, be careful." - mob_type = /mob/living/basic/cortical_borer/neutered - host_egg = /obj/item/borer_egg/neutered - you_are_text = "You are a Neutered Cortical Borer." - flavour_text = "You are a neutered cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! \ - You only grow/heal/talk when inside a host!" - important_text = "As a borer, you have the option to be friendly or not. \n\ - Note that how you act will determine how a host responds. \n\ - Do not wordlessly resort to mechanics within a host. \n\ - You can talk to other borers using ; and your host by just speaking normally. \n\ - You are unable to speak outside of a host, but are able to emote. \n\ - Additionally you have been trained by the syndicate to obey every command and protect whomever is the nearest to you when you crawled out of your egg." - generation = 1 // you dont exactly have balls, so how can you be the hive's queen? diff --git a/tgstation.dme b/tgstation.dme index cf892a7249e2..f1d99daa38f6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5761,10 +5761,10 @@ #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_general.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_hivelord.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\evolution_symbiote.dm" +#include "monkestation\code\modules\antagonists\borers\code\items\borer_spawner.dm" #include "monkestation\code\modules\antagonists\borers\code\items\egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\empowered_egg.dm" #include "monkestation\code\modules\antagonists\borers\code\items\imprisonment_cage.dm" -#include "monkestation\code\modules\antagonists\borers\code\items\neutered_egg.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\cortical_borer.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\empowered_borer.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\neutered_borer.dm" From a5babda7322cd414c15abaff23d9e3dd97c4b75c Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 1 Feb 2024 00:02:36 +0100 Subject: [PATCH 29/67] whoops, forgot dat --- monkestation/code/modules/uplink/uplink_items/misc.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/uplink/uplink_items/misc.dm b/monkestation/code/modules/uplink/uplink_items/misc.dm index a1000754a0b8..1c8feeb87fc1 100644 --- a/monkestation/code/modules/uplink/uplink_items/misc.dm +++ b/monkestation/code/modules/uplink/uplink_items/misc.dm @@ -11,7 +11,8 @@ name = "Neutered borer egg" desc = "A borer egg specifically bred to aid operatives. \ It will obey every command and protect whatever operative they first see when hatched. \ - Unfortunately due to extreme radiation exposure, they cannot reproduce." + Unfortunately due to extreme radiation exposure, they cannot reproduce. \ + It was put into a cage for easy tranportation" purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) - item = /obj/effect/mob_spawn/ghost_role/borer_egg/neutered + item = /obj/item/neutered_borer_spawner cost = 20 From f7608bd4c3ad3fc269ab1c36bb3804befa63caa4 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 1 Feb 2024 00:27:42 +0100 Subject: [PATCH 30/67] lil bit of improvements --- .../antagonist_stuff/cortical_borer_antagonist.dm | 5 ++++- .../antagonists/borers/code/items/borer_spawner.dm | 2 +- .../antagonists/borers/code/mobs/cortical_borer.dm | 4 ++++ .../antagonists/borers/code/mobs/neutered_borer.dm | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index f0c9c654de1c..1454c2d37403 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -53,6 +53,9 @@ /datum/antagonist/cortical_borer/neutered/forge_objectives() var/datum/objective/custom/borer_objective_protect_target = new - borer_objective_protect_target.explanation_text = "Protect whomever was nearest to the egg when you hatched, and listen to their every command" + borer_objective_protect_target.explanation_text = "Protect whomever was nearest to the egg when you hatched" + var/datum/objective/custom/borer_objective_listen_to_target = new + borer_objective_protect_target.explanation_text = "Listen to whatever command the human you first have seen may have for you" objectives += borer_objective_protect_target + objectives += borer_objective_listen_to_target diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 7f4837bd6e02..c7b79e90f73a 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -25,7 +25,7 @@ var/list/mob/dead/observer/candidates = poll_ghost_candidates( "Do you want to play as a neutered cortical borer?", ROLE_BORER, - poll_time = 5 SECONDS + poll_time = 10 SECONDS ) if(!LAZYLEN(candidates)) opened = FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 0e5cd44732bc..4abb9e916045 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -231,6 +231,8 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// Used to give the borer the antagonist datum var/antagonist_datum = /datum/antagonist/cortical_borer + var/skip_status_tab = FALSE + /mob/living/basic/cortical_borer/Initialize(mapload) . = ..() AddComponent( \ @@ -290,6 +292,8 @@ GLOBAL_LIST_EMPTY(cortical_borers) //so we can add some stuff to status, making it easier to read... maybe some hud some day /mob/living/basic/cortical_borer/get_status_tab_items() . = ..() + if(skip_status_tab) + return . += "Chemical Storage: [chemical_storage]/[max_chemical_storage]" . += "Chemical Evolution Points: [chemical_evolution]" . += "Stat Evolution Points: [stat_evolution]" diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm index 241d0a6a2729..371c7e42e33f 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm @@ -6,3 +6,17 @@ neutered = TRUE antagonist_datum = /datum/antagonist/cortical_borer/neutered generation = 1 + skip_status_tab = TRUE + +/mob/living/basic/cortical_borer/neutered/get_status_tab_items() + . = ..() + . += "Chemical Storage: [chemical_storage]/[max_chemical_storage]" + . += "Chemical Evolution Points: [chemical_evolution]" + . += "Stat Evolution Points: [stat_evolution]" + . += "" + if(host_sugar()) + . += "Sugar detected! Unable to generate resources!" + . += "" + . += "OBJECTIVES:" + . += "1) Protect whomever human you see first" + . += "2) Listen to every command of whatever human you saw first" From d85d6809d2376cfb6c0d66bf5cdf4601df3a4c1c Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:34:44 +0100 Subject: [PATCH 31/67] better objectives --- .../cortical_borer_antagonist.dm | 37 +++++++------------ .../borers/code/items/borer_spawner.dm | 28 +++++++++++--- .../borers/code/mobs/cortical_borer.dm | 2 +- .../borers/code/mobs/neutered_borer.dm | 3 -- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index 1454c2d37403..d4af1d385544 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -12,20 +12,6 @@ forge_objectives() return ..() -/datum/antagonist/cortical_borer/forge_objectives() - var/datum/objective/custom/borer_objective_produce_eggs = new - borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly to reduce the chances of survival" - - var/datum/objective/custom/borer_objective_willing_hosts = new - borer_objective_willing_hosts.explanation_text = "we require any amount of the borers to get [GLOB.objective_willing_hosts] willing host's trust to ensure our survival" - - var/datum/objective/custom/borer_objective_learn_chemicals = new - borer_objective_learn_chemicals.explanation_text = "we require any amount of the borers to learn [GLOB.objective_blood_borer] chemicals from blood to aquire further chemical insight" - - objectives += borer_objective_produce_eggs - objectives += borer_objective_willing_hosts - objectives += borer_objective_learn_chemicals - /datum/antagonist/cortical_borer/get_preview_icon() return finish_preview_icon(icon('monkestation/code/modules/antagonists/borers/icons/animal.dmi', "brainslug")) @@ -47,15 +33,18 @@ stack_trace("Wrong team type passed to [type] initialization.") borers = new_team -/datum/antagonist/cortical_borer/neutered - name = "Neutered Cortical Borer" - roundend_category = "neutered cortical borers" +/datum/antagonist/cortical_borer/default + +/datum/antagonist/cortical_borer/default/forge_objectives() + var/datum/objective/custom/borer_objective_produce_eggs = new + borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly to reduce the chances of survival" + + var/datum/objective/custom/borer_objective_willing_hosts = new + borer_objective_willing_hosts.explanation_text = "we require any amount of the borers to get [GLOB.objective_willing_hosts] willing host's trust to ensure our survival" -/datum/antagonist/cortical_borer/neutered/forge_objectives() - var/datum/objective/custom/borer_objective_protect_target = new - borer_objective_protect_target.explanation_text = "Protect whomever was nearest to the egg when you hatched" - var/datum/objective/custom/borer_objective_listen_to_target = new - borer_objective_protect_target.explanation_text = "Listen to whatever command the human you first have seen may have for you" + var/datum/objective/custom/borer_objective_learn_chemicals = new + borer_objective_learn_chemicals.explanation_text = "we require any amount of the borers to learn [GLOB.objective_blood_borer] chemicals from blood to aquire further chemical insight" - objectives += borer_objective_protect_target - objectives += borer_objective_listen_to_target + objectives += borer_objective_produce_eggs + objectives += borer_objective_willing_hosts + objectives += borer_objective_learn_chemicals diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index c7b79e90f73a..05e6b9a183b7 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -32,12 +32,28 @@ to_chat(user, "... After waiting the borer does not seem to come out, maybe try again a bit later?") playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) - var/mob/dead/observer/spawned_borer = pick(candidates) - var/mob/living/basic/cortical_borer/neutered/new_mob = new /mob/living/basic/cortical_borer/neutered(get_turf(src)) - spawned_borer.mind.transfer_to(new_mob, TRUE) - if(!new_mob.mind.has_antag_datum(/datum/antagonist/cortical_borer/neutered)) - var/datum/antagonist/cortical_borer/neutered/borer_antagonist_datum = new - new_mob.mind.add_antag_datum(borer_antagonist_datum) + var/mob/dead/observer/picked_candidate = pick(candidates) + spawn_borer(user, picked_candidate) + visible_message("A borer wriggles out of the [src]!") + +/obj/item/neutered_borer_spawner/proc/spawn_borer(mob/living/user, mob/dead/candidate) + var/mob/living/basic/cortical_borer/neutered/new_mob = new(get_turf(src)) + candidate.mind.transfer_to(new_mob, TRUE) + + var/datum/antagonist/cortical_borer/borer_antagonist_datum = new + + var/datum/objective/protect/protect_objective = new + var/datum/objective/custom/listen_objective = new + + protect_objective.target = user.mind + protect_objective.update_explanation_text() + + listen_objective.explanation_text = "Listen to any commands given by [user.real_Name]" + + borer_antagonist_datum.objectives += protect_objective + borer_antagonist_datum.objectives += listen_objective + + new_mob.mind.add_antag_datum(borer_antagonist_datum) new /obj/item/cortical_cage(get_turf(src)) QDEL_NULL(src) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 4abb9e916045..1fddd1e21ee3 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -229,7 +229,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// Controls if the borer can reproduce or not, TRUE means it wont be able to spawn eggs var/neutered = FALSE /// Used to give the borer the antagonist datum - var/antagonist_datum = /datum/antagonist/cortical_borer + var/antagonist_datum = /datum/antagonist/cortical_borer/default var/skip_status_tab = FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm index 371c7e42e33f..fa8c918bf69b 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm @@ -17,6 +17,3 @@ if(host_sugar()) . += "Sugar detected! Unable to generate resources!" . += "" - . += "OBJECTIVES:" - . += "1) Protect whomever human you see first" - . += "2) Listen to every command of whatever human you saw first" From 70b4f8e8264575b316722069dc3f67c668c5f4be Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:41:56 +0100 Subject: [PATCH 32/67] whoops --- .../code/modules/antagonists/borers/code/items/borer_spawner.dm | 2 +- .../code/modules/antagonists/borers/code/mobs/neutered_borer.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 05e6b9a183b7..2b534ab920df 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -48,7 +48,7 @@ protect_objective.target = user.mind protect_objective.update_explanation_text() - listen_objective.explanation_text = "Listen to any commands given by [user.real_Name]" + listen_objective.explanation_text = "Listen to any commands given by [user.name]" borer_antagonist_datum.objectives += protect_objective borer_antagonist_datum.objectives += listen_objective diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm index fa8c918bf69b..1e47813ba02e 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm @@ -4,7 +4,7 @@ /mob/living/basic/cortical_borer/neutered neutered = TRUE - antagonist_datum = /datum/antagonist/cortical_borer/neutered + antagonist_datum = /datum/antagonist/cortical_borer generation = 1 skip_status_tab = TRUE From b0ba2d044c91a9c09362319aaeb0a1904fb531c4 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:13:22 +0100 Subject: [PATCH 33/67] bap --- .../borers/code/antagonist_stuff/cortical_borer_antagonist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index d4af1d385544..fce26050fb0f 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -37,7 +37,7 @@ /datum/antagonist/cortical_borer/default/forge_objectives() var/datum/objective/custom/borer_objective_produce_eggs = new - borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly to reduce the chances of survival" + borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly for increasing our chances of survival" var/datum/objective/custom/borer_objective_willing_hosts = new borer_objective_willing_hosts.explanation_text = "we require any amount of the borers to get [GLOB.objective_willing_hosts] willing host's trust to ensure our survival" From f8a5824687790f79c3bf5868fbf3cd371851ba76 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 2 Feb 2024 04:33:49 +0100 Subject: [PATCH 34/67] taking away the neutered borers balls that i already took --- .../antagonists/borers/code/evolution/evolution_datum.dm | 4 ++-- .../antagonists/borers/code/evolution/evolution_diveworm.dm | 2 ++ .../antagonists/borers/code/evolution/evolution_hivelord.dm | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm index 77d205100c12..f71d95a3302b 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm @@ -19,10 +19,10 @@ /// What happens when a borer gets this evolution /datum/borer_evolution/proc/on_evolve(mob/living/basic/cortical_borer/cortical_owner) SHOULD_CALL_PARENT(TRUE) - if(gain_text) - to_chat(cortical_owner, span_notice("[gain_text]")) if(mutually_exclusive) cortical_owner.genome_locked = TRUE + if(gain_text) + to_chat(cortical_owner, span_notice("[gain_text]")) /datum/borer_evolution/base name = "The Beginning" diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm index f556a9f16262..01eb0ea2a9b4 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm @@ -106,5 +106,7 @@ /datum/borer_evolution/diveworm/empowered_offspring/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() + if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) + return var/datum/action/cooldown/borer/empowered_offspring/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm index be06cc5d7f41..65cfc05e3c1a 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm @@ -7,11 +7,13 @@ 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) evo_cost = 1 + unlocked_evolutions = list(/datum/borer_evolution/hivelord/blood_chemical) /datum/borer_evolution/hivelord/produce_offspring/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() + if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) + return var/datum/action/cooldown/borer/produce_offspring/attack_action = new(cortical_owner) attack_action.Grant(cortical_owner) @@ -70,4 +72,6 @@ /datum/borer_evolution/hivelord/produce_offspring_alone/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() + if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) + return cortical_owner.upgrade_flags |= BORER_ALONE_PRODUCTION From a09e0040d81a83e7f69e49f81afa62e3d21ad5f2 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 2 Feb 2024 23:12:03 +0100 Subject: [PATCH 35/67] simplifies the cage --- .../modules/antagonists/borers/code/items/borer_spawner.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 2b534ab920df..74a22f15a071 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -33,12 +33,10 @@ playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) var/mob/dead/observer/picked_candidate = pick(candidates) - spawn_borer(user, picked_candidate) visible_message("A borer wriggles out of the [src]!") -/obj/item/neutered_borer_spawner/proc/spawn_borer(mob/living/user, mob/dead/candidate) var/mob/living/basic/cortical_borer/neutered/new_mob = new(get_turf(src)) - candidate.mind.transfer_to(new_mob, TRUE) + picked_candidate.mind.transfer_to(new_mob, TRUE) var/datum/antagonist/cortical_borer/borer_antagonist_datum = new From 986a30b689c1d72fa71d6786a1492dd213c1bf4a Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 3 Feb 2024 01:21:48 +0100 Subject: [PATCH 36/67] sets it on a major track, didnt know how to do dat before --- .../antagonists/borers/code/antagonist_stuff/midround_event.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index f855c6a370f6..cb8896f27919 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -6,6 +6,7 @@ tags = list(TAG_TEAM_ANTAG, TAG_EXTERNAL, TAG_ALIEN) typepath = /datum/round_event/ghost_role/cortical_borer antag_flag = ROLE_BORER + track = EVENT_TRACK_MAJOR enemy_roles = list( JOB_CAPTAIN, JOB_DETECTIVE, From c1949205dff7d86d3b76275fb0b1fceb5e727ac9 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 4 Feb 2024 03:33:12 +0100 Subject: [PATCH 37/67] TGUI with help, and borer egg fixes --- .../borers/code/abilities/_ability.dm | 16 +- .../code/abilities/chemical_injector.dm | 5 + .../borers/code/abilities/enter_host.dm | 9 + .../borers/code/abilities/evolution_tree.dm | 7 + .../borers/code/abilities/force_speech.dm | 3 + .../borers/code/abilities/hide_presence.dm | 5 + .../borers/code/abilities/host_healthscan.dm | 4 + .../borers/code/abilities/incite_fear.dm | 4 + .../borers/code/abilities/learn_chemicals.dm | 8 + .../borers/code/abilities/learn_focus.dm | 4 + .../borers/code/abilities/revive_host.dm | 4 + .../borers/code/abilities/spawn_offspring.dm | 8 + .../borers/code/abilities/toggle_stealth.dm | 5 + .../borers/code/abilities/upgrade_body.dm | 4 + .../borers/code/abilities/willing_host.dm | 5 + .../cortical_borer_antagonist.dm | 40 ++++ .../antagonists/borers/code/items/egg.dm | 2 +- .../borers/code/mobs/cortical_borer.dm | 2 +- .../tgui/interfaces/AntagInfoBorer.tsx | 224 ++++++++++++++++++ 19 files changed, 355 insertions(+), 4 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/AntagInfoBorer.tsx diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm index 21dbe3b1b379..9a8583ba24fc 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm @@ -2,6 +2,8 @@ /datum/action/cooldown/borer button_icon = 'monkestation/code/modules/antagonists/borers/icons/actions.dmi' cooldown_time = 0 + /// Text used to explain the ability more closelly in the antagonist TGUI panel + var/ability_explanation = "" /// How many chemicals this costs var/chemical_cost = 0 @@ -24,10 +26,10 @@ var/compiled_string = "" if(chemical_cost) compiled_string += "([chemical_cost] chemical[chemical_cost == 1 ? "" : "s"])" - if(chemical_evo_points) - compiled_string += " ([chemical_evo_points] chemical point[chemical_evo_points == 1 ? "" : "s"])" if(stat_evo_points) compiled_string += " ([stat_evo_points] stat point[stat_evo_points == 1 ? "" : "s"])" + if(chemical_evo_points) + compiled_string += " ([chemical_evo_points] chemical point[chemical_evo_points == 1 ? "" : "s"])" name = "[initial(name)][compiled_string]" /datum/action/cooldown/borer/Trigger(trigger_flags, atom/target) @@ -65,3 +67,13 @@ return FALSE return . == FALSE ? FALSE : TRUE //. can be null, true, or false. There's a difference between null and false here + +/datum/asset/simple/borer_icons + +/datum/asset/simple/borer_icons/register() + for(var/datum/action/cooldown/borer/ability as anything in subtypesof(/datum/action/cooldown/borer)) + add_borer_icon(initial(ability.button_icon), initial(ability.button_icon_state)) + return ..() + +/datum/asset/simple/borer_icons/proc/add_borer_icon(borer_icon, borer_icon_state) + assets[SANITIZE_FILENAME("borer.[borer_icon_state].png")] = icon(borer_icon, borer_icon_state) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm b/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm index f6647d8a9957..a687156797cc 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/chemical_injector.dm @@ -11,6 +11,11 @@ button_icon_state = "chemical" requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "chemical" + ability_explanation = "\ + This ability allows us to inject chemicals into our host.\n\ + Our internal chemicals can be converted to human-compatible chemicals at a ratio of 2:1\n\ + " /datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index 4c3d50a0b519..8f6bda2c5fe1 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -3,6 +3,15 @@ name = "Inhabit/Uninhabit Host" cooldown_time = 10 SECONDS button_icon_state = "host" + ability_explanation = "\ + Using this ability we can eighter enter or exit a host.\n\ + Whilst leaving a host, they cannot have sugar within them and we require to be carefull in order to not immediatelly get squished.\n\ + Going inside of a host will usually take 6 seconds if we are not a hivelord, we must take causion for the host to not move.\n\ + Whilst going inside of a host we require the following:\n\ + - they must not have one of us within them\n\ + - they must be of compatible species\n\ + - and they must not have helmets designed against us\n\ + " /datum/action/cooldown/borer/choosing_host/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm b/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm index 3f992efd00fe..8783099f8b12 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/evolution_tree.dm @@ -1,6 +1,13 @@ /datum/action/cooldown/borer/evolution_tree name = "Open Evolution Tree" button_icon_state = "newability" + ability_explanation = "\ + Allows you to evolve essential to survive abilities.\n\ + Beware, as evolving a tier 3 path will lock you out of all other tier 3 paths.\n\ + - The Diveworm path focuses on killing hosts, and making eggs in their corpses.\n\ + - The Hivelord path focuses on making lots of eggs.\n\ + - The Symbiote path focuses on helping their host, for mutual benefit.\n\ + " /datum/action/cooldown/borer/evolution_tree/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm index 137c6aed8ab4..418b922b4a2e 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm @@ -4,6 +4,9 @@ button_icon_state = "speak" requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Forces your host to speak any words you desire.\ + " /datum/action/cooldown/borer/force_speak/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm b/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm index bcb63b2a55b6..9dc7157e3d4f 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/hide_presence.dm @@ -4,6 +4,11 @@ button_icon_state = "hiding" chemical_cost = 100 sugar_restricted = TRUE + ability_explanation = "\ + Very effectivelly hides your presence\n\ + While in stealth, you will crawl onto people without any noticable signs nor warning\n\ + Additionally you will not have any negative effects onto your host, but wont generate internal chemicals\n\ + " /datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags, atom/target) var/mob/living/basic/cortical_borer/cortical_owner = owner diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm b/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm index 8b7b3dfdca9a..df07155bea6a 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/host_healthscan.dm @@ -4,6 +4,10 @@ button_icon_state = "blood" requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Allows you to check your host's health\n\ + Additionally you will be able to taste the host's chemicals and measure them acuratelly\n\ + " /datum/action/cooldown/borer/check_blood/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm b/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm index a1ba23980077..1986ac9fa651 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/incite_fear.dm @@ -3,6 +3,10 @@ cooldown_time = 12 SECONDS button_icon_state = "fear" sugar_restricted = TRUE + ability_explanation = "\ + Causes an extreme fear reaction in a person near you whilst outside of a host\n\ + While inside of a host, it is much more effective and is used on the host itself\n\ + " /datum/action/cooldown/borer/fear_human/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm index ced38d1b8f3c..3d2be9a73b12 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -19,6 +19,10 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) chemical_evo_points = 1 requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Allows you to learn various unlocked chemicals\n\ + To expand the chemical choice you need to use the evolution ability\n\ + " /datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags, atom/target) . = ..() @@ -75,6 +79,10 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) chemical_evo_points = 5 requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Allows you to learn chemicals from blood at a much steeper price\n\ + Does not work on certain chemicals whose mollecular complexity is too high\n\ + " /datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm index 9204c81195e9..612f0441d1cf 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_focus.dm @@ -3,6 +3,10 @@ button_icon_state = "getfocus" requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Lets you evolve strong passive modifiers into the hosts you inhabit\n\ + Your focuses will follow you when you leave your host\n\ + " /datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm index 9b4a136c800c..58c2c536113a 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/revive_host.dm @@ -7,6 +7,10 @@ requires_host = TRUE sugar_restricted = TRUE needs_dead_host = TRUE + ability_explanation = "\ + Halfs all the damage, including organ damage that your host has. Then defiblirates their heart\n\ + You may need to use this ability multiple times depending on how badly your host is damaged\n\ + " /datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index 5a8ca51a6eb9..a2ceadfb3dbb 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -8,6 +8,10 @@ button_icon_state = "reproduce" chemical_cost = 100 needs_living_host = TRUE + ability_explanation = "\ + Forces your host to produce a borer egg inside of their stomach, then vomit it up\n\ + Be carefull as the egg is fragile and can be broken very easily by any human, along with being extremelly noticable\n\ + " /datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags, atom/target) . = ..() @@ -78,6 +82,10 @@ chemical_cost = 150 requires_host = TRUE needs_dead_host = TRUE + ability_explanation = "\ + Implants an egg onto a dead host, the egg will take 3 minutes to hatch and will die if the host gets revived\n\ + If the egg hatches, a massivelly stronger than normal borer will be created. Surpassing all others.\n\ + " /datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm index 809aa3c63963..7cbef00ae148 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/toggle_stealth.dm @@ -2,6 +2,11 @@ name = "Toggle Hiding" button_icon_state = "hide" var/hide_layer = ABOVE_NORMAL_TURF_LAYER + ability_explanation = "\ + Turns your hiding abilities on/off\n\ + Whilst on, you will hide under most objects, like tables.\n\ + If you are a diveworm, you will bore into hosts twice as fast whilst not hidden\n\ + " /datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm index 320cc413c2a9..6648da839962 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/upgrade_body.dm @@ -4,6 +4,10 @@ stat_evo_points = 1 requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Lets you become stronger in exchange for an evolution point\n\ + Your maximum health, regeneration, chemical storage and chemical regeneration will all be faster\n\ + " /datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm index 15fa409cb505..085d40b489e5 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/willing_host.dm @@ -5,6 +5,11 @@ chemical_cost = 150 requires_host = TRUE sugar_restricted = TRUE + ability_explanation = "\ + Asks your host if they accept your existance inside of them\n\ + If the host agrees, you will progress one of your objectives.\n\ + Whilst this does not immediatelly provide a benefit to you, enough willing hosts will make your evolution and chemical points accumulate quicker.\n\ + " /datum/action/cooldown/borer/willing_host/Trigger(trigger_flags, atom/target) . = ..() diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index fce26050fb0f..2eeb9fca82a7 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -3,12 +3,16 @@ job_rank = ROLE_BORER roundend_category = "cortical borers" antagpanel_category = "Cortical Borers" + ui_name = "AntagInfoBorer" prevent_roundtype_conversion = FALSE show_to_ghosts = TRUE /// The team of borers var/datum/team/cortical_borers/borers + /// Our linked borer, used for the antagonist panel TGUI + var/mob/living/basic/cortical_borer/cortical_owner /datum/antagonist/cortical_borer/on_gain() + cortical_owner = owner.current forge_objectives() return ..() @@ -48,3 +52,39 @@ objectives += borer_objective_produce_eggs objectives += borer_objective_willing_hosts objectives += borer_objective_learn_chemicals + +/datum/antagonist/cortical_borer/ui_static_data(mob/user) + var/list/data = list() + for(var/datum/action/cooldown/borer/ability as anything in cortical_owner.known_abilities) + var/list/ability_data = list() + + ability_data["ability_name"] = initial(ability.name) + ability_data["ability_explanation"] = initial(ability.ability_explanation) +/* Temporarily disabled -- Turn dis on once i figure out how to space stuff out properly in the TGUI + ability_data["ability_explanation"] += "Restrictions:" + if(ability.chemical_cost) + ability_data["ability_explanation"] += "

-To use this ability we need to use [ability.chemical_cost] of our internally synthesized chemicals. " + if(ability.stat_evo_points) + ability_data["ability_explanation"] += "-To make effective use of this ability we need to spend [ability.stat_evo_points] evolution points. " + if(ability.chemical_evo_points) + ability_data["ability_explanation"] += "-We have to use [ability.chemical_evo_points] chemical evolution points to use this ability. " + + if(ability.requires_host) + ability_data["ability_explanation"] += "-We require a host to use this ability. " + if(ability.needs_living_host) + ability_data["ability_explanation"] += "-Our host requires to be alive in order for us to use this ability. " + if(ability.needs_dead_host) + ability_data["ability_explanation"] += "-Our host must be deceased in order for us to make effective use of this ability. " + if(ability.sugar_restricted) + ability_data["ability_explanation"] += "-We cannot use this ability when our host is under the effect of a highly dangerous chemical known as \"sugar\". " +*/ + ability_data["ability_icon"] = initial(ability.button_icon_state) + + data["ability"] += list(ability_data) + + return data + ..() + +/datum/antagonist/cortical_borer/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/borer_icons), + ) diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index 3fa1a1af904b..e493874dd086 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -39,7 +39,7 @@ /obj/effect/mob_spawn/ghost_role/borer_egg/special(mob/living/spawned_mob, mob/mob_possessor) . = ..() - spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer) + spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer/default) if(generation == 0) //The first ever borer gets a special name spawned_mob.name = "The hivequeen cortical borer" diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 1fddd1e21ee3..a74a82ce557f 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -162,7 +162,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) var/chem_regen_per_level = 1 ///the list of actions that the borer has - var/list/known_abilities = list( + var/list/datum/action/cooldown/borer/known_abilities = list( /datum/action/cooldown/borer/toggle_hiding, /datum/action/cooldown/borer/choosing_host, /datum/action/cooldown/borer/evolution_tree, diff --git a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx new file mode 100644 index 000000000000..2ce27e532d26 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx @@ -0,0 +1,224 @@ +// THIS IS A MONKESTATION UI FILE + +import { resolveAsset } from '../assets'; +import { BooleanLike } from 'common/react'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Divider, Dropdown, Section, Stack, Tabs } from '../components'; +import { Window } from '../layouts'; + +type Objective = { + count: number; + name: string; + explanation: string; + complete: BooleanLike; + was_uncompleted: BooleanLike; + reward: number; +}; + +type BorerInformation = { + ability: AbilityInfo[]; +}; + +type AbilityInfo = { + ability_name: string; + ability_explanation: string; + ability_icon: string; +}; + +type Info = { + objectives: Objective[]; +}; + +const ObjectivePrintout = (props: any, context: any) => { + const { data } = useBackend(context); + const { objectives } = data; + return ( + + Your current objectives: + + {(!objectives && 'None!') || + objectives.map((objective) => ( + + #{objective.count}: {objective.explanation} + + ))} + + + ); +}; + +export const AntagInfoBorer = (props: any, context: any) => { + const [tab, setTab] = useLocalState(context, 'tab', 1); + return ( + + + + setTab(1)}> + Introduction + + setTab(2)}> + Ability explanations + + + {tab === 1 && } + {tab === 2 && } + + + ); +}; + +const MainPage = () => { + return ( + + +

+ + + You are a Cortical Borer, a creature that crawls into peoples + ear's to then settle on the brain + + + + + +
+ + +
+ + + Host and you +
+ + You depend on a host for survival and reproduction, you slowly + regenerate your health whilst inside of a host but whilst + outside of one you can be squished by anyone stepping onto you, + killing you. + +
+
+ + When speaking, you will directly communicate to your host, by + adding " ; " to the start of your message you will + instead speak to the hivemind of all the borers + +
+
+ + Creating resources and their uses + +
+
+ + While inside of a host you will slowly generate internal + chemicals, evolution points and chemical points. + +
+
+ + Internal chemical points + are used for using most of the abilities, their main use is in + injecting chemicals into your host using the chemical injector + +
+
+ + Evolution points + are mostly used in the evolution tree and choosing your focus, + both of those being essential to surviving and completing your + objectives + +
+
+ + Chemical evolution points + are used in learning new chemicals from your possible list of + learn-able chemicals, along with learning chemicals from the + hosts blood for both their benefit and your objectives + +
+
+
+
+ + ); +}; + +const BorerAbilities = (props: any, context: any) => { + const { act, data } = useBackend(context); + return ( + + + + + + ); +}; + +const AbilitySection = (props: any, context: any) => { + const { act, data } = useBackend(context); + const { ability } = data; + if (!ability) { + return
; + } + + const [selectedAbility, setSelectedAbility] = useLocalState( + context, + 'ability', + ability[0] + ); + + return ( +
+ }> + + + abilities.ability_name)} + onSelected={(abilityName: string) => + setSelectedAbility( + ability.find((p) => p.ability_name === abilityName) || + ability[0] + ) + } + /> + {selectedAbility && ( + + )} + + + + + {selectedAbility && selectedAbility.ability_explanation} + + +
+ ); +}; From 63c136c9f335fdea3dabc2ef51f76340acace3a0 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 4 Feb 2024 05:10:54 +0100 Subject: [PATCH 38/67] adds borers to the antag token thingy --- .../cortical_borer_antagonist.dm | 36 +++++++++++++++++++ .../code/antagonist_stuff/midround_event.dm | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm index 2eeb9fca82a7..b1568eca26a5 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm @@ -11,6 +11,42 @@ /// Our linked borer, used for the antagonist panel TGUI var/mob/living/basic/cortical_borer/cortical_owner +/datum/antagonist/cortical_borer/antag_token(datum/mind/hosts_mind, mob/spender) + var/list/vents = list() + if(isliving(spender)) + hosts_mind.current.unequip_everything() + new /obj/effect/holy(hosts_mind.current.loc) + QDEL_IN(hosts_mind.current, 20) + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) + if(QDELETED(temp_vent)) + continue + if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] + if(!temp_vent_parent) + continue // No parent vent + // Stops Cortical Borers getting stuck in small networks. + // See: Security, Virology + if(length(temp_vent_parent.other_atmos_machines) > 20) + vents += temp_vent + + if(!length(vents)) + message_admins("Spawning in as a borer failed!") + return MAP_ERROR + + var/mob/dead/observer/new_borer = spender + var/turf/vent_turf = get_turf(pick(vents)) + var/mob/living/basic/cortical_borer/spawned_cb = new(vent_turf) + spawned_cb.ckey = new_borer.ckey + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/default) + notify_ghosts( + "Someone has become a borer due to spending an antag token ([spawned_cb])!", + source = spawned_cb, + action = NOTIFY_ORBIT, + header = "Something's Interesting!", + ) + message_admins("[ADMIN_LOOKUPFLW(spawned_cb)] has been made into a borer by using an antag token.") + to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) + /datum/antagonist/cortical_borer/on_gain() cortical_owner = owner.current forge_objectives() diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index cb8896f27919..608a2842de9e 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -67,7 +67,7 @@ var/turf/vent_turf = get_turf(pick(vents)) var/mob/living/basic/cortical_borer/spawned_cb = new /mob/living/basic/cortical_borer(vent_turf) spawned_cb.ckey = new_borer.ckey - spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/default) announce_to_ghosts(spawned_cb) message_admins("[ADMIN_LOOKUPFLW(spawned_cb)] has been made into a borer by an event.") to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) From a13c8e781ecadaa6f7b65bb8f3bbf0ba26e1b02f Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 5 Feb 2024 04:57:19 +0100 Subject: [PATCH 39/67] some re-naming, neutered round-end section, eyecandy for the borer cage --- ...orer_antagonist.dm => antagonist_datum.dm} | 47 ++++++++++--------- .../code/antagonist_stuff/midround_event.dm | 3 +- .../borers/code/items/borer_spawner.dm | 39 +++++++++++++-- .../antagonists/borers/code/items/egg.dm | 2 +- .../borers/code/mobs/cortical_borer.dm | 2 +- tgstation.dme | 2 +- 6 files changed, 64 insertions(+), 31 deletions(-) rename monkestation/code/modules/antagonists/borers/code/antagonist_stuff/{cortical_borer_antagonist.dm => antagonist_datum.dm} (91%) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm similarity index 91% rename from monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm rename to monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm index b1568eca26a5..fbd48166dcd1 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/cortical_borer_antagonist.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm @@ -1,13 +1,11 @@ /datum/antagonist/cortical_borer name = "Cortical Borer" job_rank = ROLE_BORER - roundend_category = "cortical borers" + roundend_category = "enslaved cortical borers" // may look a bit confusing, but these borers are not a part of a hivemind. So they are probably enslaved antagpanel_category = "Cortical Borers" ui_name = "AntagInfoBorer" prevent_roundtype_conversion = FALSE show_to_ghosts = TRUE - /// The team of borers - var/datum/team/cortical_borers/borers /// Our linked borer, used for the antagonist panel TGUI var/mob/living/basic/cortical_borer/cortical_owner @@ -37,7 +35,7 @@ var/turf/vent_turf = get_turf(pick(vents)) var/mob/living/basic/cortical_borer/spawned_cb = new(vent_turf) spawned_cb.ckey = new_borer.ckey - spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/default) + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) notify_ghosts( "Someone has become a borer due to spending an antag token ([spawned_cb])!", source = spawned_cb, @@ -55,12 +53,28 @@ /datum/antagonist/cortical_borer/get_preview_icon() return finish_preview_icon(icon('monkestation/code/modules/antagonists/borers/icons/animal.dmi', "brainslug")) -/datum/antagonist/cortical_borer/get_team() - return borers +/datum/antagonist/cortical_borer/hivemind + roundend_category = "cortical borers" + /// The team of borers + var/datum/team/cortical_borers/borers + +/datum/antagonist/cortical_borer/hivemind/forge_objectives() + var/datum/objective/custom/borer_objective_produce_eggs = new + borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly for increasing our chances of survival" + + var/datum/objective/custom/borer_objective_willing_hosts = new + borer_objective_willing_hosts.explanation_text = "we require any amount of the borers to get [GLOB.objective_willing_hosts] willing host's trust to ensure our survival" + + var/datum/objective/custom/borer_objective_learn_chemicals = new + borer_objective_learn_chemicals.explanation_text = "we require any amount of the borers to learn [GLOB.objective_blood_borer] chemicals from blood to aquire further chemical insight" + + objectives += borer_objective_produce_eggs + objectives += borer_objective_willing_hosts + objectives += borer_objective_learn_chemicals -/datum/antagonist/cortical_borer/create_team(datum/team/cortical_borers/new_team) +/datum/antagonist/cortical_borer/hivemind/create_team(datum/team/cortical_borers/new_team) if(!new_team) - for(var/datum/antagonist/cortical_borer/borer in GLOB.antagonists) + for(var/datum/antagonist/cortical_borer/hivemind/borer in GLOB.antagonists) if(!borer.owner) stack_trace("Antagonist datum without owner in GLOB.antagonists: [borer]") continue @@ -73,21 +87,8 @@ stack_trace("Wrong team type passed to [type] initialization.") borers = new_team -/datum/antagonist/cortical_borer/default - -/datum/antagonist/cortical_borer/default/forge_objectives() - var/datum/objective/custom/borer_objective_produce_eggs = new - borer_objective_produce_eggs.explanation_text = "we require [GLOB.objective_egg_borer_number] different borers to produce [GLOB.objective_egg_egg_number] eggs to make sure our hive can spread widelly for increasing our chances of survival" - - var/datum/objective/custom/borer_objective_willing_hosts = new - borer_objective_willing_hosts.explanation_text = "we require any amount of the borers to get [GLOB.objective_willing_hosts] willing host's trust to ensure our survival" - - var/datum/objective/custom/borer_objective_learn_chemicals = new - borer_objective_learn_chemicals.explanation_text = "we require any amount of the borers to learn [GLOB.objective_blood_borer] chemicals from blood to aquire further chemical insight" - - objectives += borer_objective_produce_eggs - objectives += borer_objective_willing_hosts - objectives += borer_objective_learn_chemicals +/datum/antagonist/cortical_borer/hivemind/get_team() + return borers /datum/antagonist/cortical_borer/ui_static_data(mob/user) var/list/data = list() diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index 608a2842de9e..1120dfa0e1f9 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -67,9 +67,10 @@ var/turf/vent_turf = get_turf(pick(vents)) var/mob/living/basic/cortical_borer/spawned_cb = new /mob/living/basic/cortical_borer(vent_turf) spawned_cb.ckey = new_borer.ckey - spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/default) + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) announce_to_ghosts(spawned_cb) message_admins("[ADMIN_LOOKUPFLW(spawned_cb)] has been made into a borer by an event.") + log_game("STORYTELLER: [key_name(new_borer)] was spawned as a borer by the storyteller.") to_chat(spawned_cb, span_warning("You are a cortical borer! You can fear someone to make them stop moving, but make sure to inhabit them! You only grow/heal/talk when inside a host!")) /datum/dynamic_ruleset/midround/from_ghosts/cortical_borer diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 74a22f15a071..5ea40fa2b8a7 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -4,7 +4,12 @@ as this one contains a borer trained to assist anyone who it first sees in completing their goals." icon = 'monkestation/code/modules/antagonists/borers/icons/items.dmi' icon_state = "cage" - var/opened = FALSE // used purelly for sprite manipulation + /// Used to animate the cage opening when you use the borer spawner, and closing if it fails to spawn a borer. Also midly against spam + var/opened = FALSE + /// Toggles if the borer spawner should be delayed or not, if this gets a value if will use that value to delay (for example: 5 SECONDS) + var/delayed = FALSE + /// Dictates the poll time + var/polling_time = 10 SECONDS /obj/item/neutered_borer_spawner/Initialize(mapload) . = ..() @@ -18,22 +23,38 @@ else . += "doors_closed" +/obj/item/neutered_borer_spawner/proc/do_wriggler_messages() + if(!opened) // there were no candidates at all somehow, probably tests on local. Lets not give messages after the fail message comes up + return + sleep(polling_time * 0.2) + visible_message(span_notice("The borer seems to have woken up")) + sleep(polling_time * 0.2) + visible_message(span_notice("The borer has perked up their head, finally noticing the opened cage...")) + sleep(polling_time * 0.2) + visible_message(span_notice("The borer seems to slither cautiously to the cage entrance...")) + sleep(polling_time * 0.1) + visible_message(span_notice("The borer's head peeks outside of the cage...")) + /obj/item/neutered_borer_spawner/attack_self(mob/living/user) + if(opened) + return user.visible_message("[user] opens [src].", "You have opened the [src], awaiting for the borer to come out.", "You hear a metallic thunk.") opened = TRUE playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + if(delayed) + sleep(delayed) + INVOKE_ASYNC(src, PROC_REF(do_wriggler_messages)) // give them something to look at whilst we poll the ghosts var/list/mob/dead/observer/candidates = poll_ghost_candidates( "Do you want to play as a neutered cortical borer?", ROLE_BORER, - poll_time = 10 SECONDS + poll_time = polling_time ) if(!LAZYLEN(candidates)) opened = FALSE - to_chat(user, "... After waiting the borer does not seem to come out, maybe try again a bit later?") + to_chat(user, "Yet the borer after looking at you quickly retreats back into their cage, visibly scared. Perhaps try later?") playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) var/mob/dead/observer/picked_candidate = pick(candidates) - visible_message("A borer wriggles out of the [src]!") var/mob/living/basic/cortical_borer/neutered/new_mob = new(get_turf(src)) picked_candidate.mind.transfer_to(new_mob, TRUE) @@ -53,5 +74,15 @@ new_mob.mind.add_antag_datum(borer_antagonist_datum) + notify_ghosts( + "[new_mob] has been chosen from the ghost pool!", + source = new_mob, + action = NOTIFY_ORBIT, + header = "Someone just got a new friend!" + ) + message_admins("[ADMIN_LOOKUPFLW(new_mob)] has been made into a borer via a traitor item used by [user]") + log_game("[key_name(new_borer)] was spawned as a borer by [key_name(user)]") + visible_message("A borer wriggles out of the [src]!") + new /obj/item/cortical_cage(get_turf(src)) QDEL_NULL(src) diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index e493874dd086..2521b1da6aed 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -39,7 +39,7 @@ /obj/effect/mob_spawn/ghost_role/borer_egg/special(mob/living/spawned_mob, mob/mob_possessor) . = ..() - spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer/default) + spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) if(generation == 0) //The first ever borer gets a special name spawned_mob.name = "The hivequeen cortical borer" diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index a74a82ce557f..7c5ae6c89946 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -229,7 +229,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// Controls if the borer can reproduce or not, TRUE means it wont be able to spawn eggs var/neutered = FALSE /// Used to give the borer the antagonist datum - var/antagonist_datum = /datum/antagonist/cortical_borer/default + var/antagonist_datum = /datum/antagonist/cortical_borer/hivemind var/skip_status_tab = FALSE diff --git a/tgstation.dme b/tgstation.dme index 2cad5cd32e3c..29f82276d8f7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5754,7 +5754,7 @@ #include "monkestation\code\modules\antagonists\borers\code\abilities\toggle_stealth.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\upgrade_body.dm" #include "monkestation\code\modules\antagonists\borers\code\abilities\willing_host.dm" -#include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\cortical_borer_antagonist.dm" +#include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\antagonist_datum.dm" #include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\midround_event.dm" #include "monkestation\code\modules\antagonists\borers\code\antagonist_stuff\round_end_text.dm" #include "monkestation\code\modules\antagonists\borers\code\evolution\borer_evolution.dm" From b62016e78c9211ba4da2bd967dbdff66fe51003f Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 5 Feb 2024 05:13:22 +0100 Subject: [PATCH 40/67] "i'll just quickly add in one line of logging" i said, "it surelly wont take 4 commits" i said... --- .../code/modules/antagonists/borers/code/items/borer_spawner.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 5ea40fa2b8a7..914330021632 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -81,7 +81,7 @@ header = "Someone just got a new friend!" ) message_admins("[ADMIN_LOOKUPFLW(new_mob)] has been made into a borer via a traitor item used by [user]") - log_game("[key_name(new_borer)] was spawned as a borer by [key_name(user)]") + log_game("[key_name(new_mob)] was spawned as a borer by [key_name(user)]") visible_message("A borer wriggles out of the [src]!") new /obj/item/cortical_cage(get_turf(src)) From 7aa24a78704dfbb0f602cef26b8200e36d458eab Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 6 Feb 2024 11:28:51 +0100 Subject: [PATCH 41/67] that isnt a proper comment --- .../code/modules/antagonists/borers/code/mobs/cortical_borer.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 7c5ae6c89946..91128fc3a901 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -129,7 +129,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/reagent/toxin/heparin, /datum/reagent/toxin/mindbreaker, ) - //blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these + ///blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these var/list/blacklisted_chemicals = list() ///how old the borer is, starting from zero. Goes up only when inside a host From f9817d9bd3ff8798053e2315d4a541077748c34b Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 11 Feb 2024 02:04:07 +0100 Subject: [PATCH 42/67] Update readme.md --- .../code/modules/antagonists/borers/readme.md | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/readme.md b/monkestation/code/modules/antagonists/borers/readme.md index 5d18680130ec..c2d9f0835f9d 100644 --- a/monkestation/code/modules/antagonists/borers/readme.md +++ b/monkestation/code/modules/antagonists/borers/readme.md @@ -11,22 +11,25 @@ Cortical worms are antagonists whose sole purpose is to reproduce infintelly ### TG Proc/File Changes: -code\__DEFINES\role_preferences.dm -code\__DEFINES\research\anomalies.dm -code\_globalvars\lists\poll_ignore.dm -code\datums\mutations\_mutations.dm -code\modules\admin\sql_ban_system.dm -code\modules\antagonists\changeling\powers\panacea.dm +code/__DEFINES/research/anomalies.dm -- Needed to blacklist the borer organs from the bioscrambler +code/__DEFINES/role_preferences.dm -- Needed a define here for cortical borers +code/__DEFINES/~monkestation/actionspeed_modification.dm -- Added the actionspeed modifier ID for the borers here... maybe should move it +code/__DEFINES/~monkestation/antagonists.dm -- Bunch of bitflags, iscorticalborer() check and evolution defines +code/__DEFINES/~monkestation/role_preferences.dm -- Role preference for borers +code/_globalvars/lists/poll_ignore.dm -- Somethin to ignore any future votes to become a borer +code/datums/mutations/_mutations.dm -- Borers automatically will prevent you from getting anymore genetic mutations +code/modules/admin/sql_ban_system.dm -- Ban system was simply needed for borers +code/modules/antagonists/changeling/powers/panacea.dm -- If you are a changeling, panacea will take the pest off of you ### Included files that are not contained in this module: - -code\__DEFINES\~monkestation\actionspeed_modification.dm -code\__DEFINES\~monkestation\antagonists.dm -code\__DEFINES\~monkestation\is_helpers.dm -code\__DEFINES\~monkestation\role_preferences.dm - -tgui\packages\tgui\interfaces\BorerChem.jsx -tgui\packages\tgui\interfaces\BorerEvolution.tsx +code/__DEFINES/~monkestation/actionspeed_modification.dm -- Added the actionspeed modifier ID for the borers here... maybe should move it +code/__DEFINES/~monkestation/antagonists.dm -- Bunch of bitflags, iscorticalborer() check and evolution defines +code/__DEFINES/~monkestation/role_preferences.dm -- Role preference for borers +monkestation/code/modules/uplink/uplink_items/misc.dm -- Uplink entry for spawning neutered borers in + +tgui/packages/tgui/interfaces/AntagInfoBorer.tsx -- TGUI window explaining what the borers objectives are, and how to use abilities +tgui/packages/tgui/interfaces/BorerChem.js -- Allows the borers to inject chemicals, very sensitive +tgui/packages/tgui/interfaces/BorerEvolution.tsx -- Allows you to evolve abilities ### Credits: From a1e15c639459d635e9b84260c0808d939c8f1730 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 11 Feb 2024 02:32:31 +0100 Subject: [PATCH 43/67] fixes the borer cage's animation --- .../code/modules/antagonists/borers/code/items/borer_spawner.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 914330021632..148d53e77981 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -44,6 +44,7 @@ if(delayed) sleep(delayed) INVOKE_ASYNC(src, PROC_REF(do_wriggler_messages)) // give them something to look at whilst we poll the ghosts + update_appearance() var/list/mob/dead/observer/candidates = poll_ghost_candidates( "Do you want to play as a neutered cortical borer?", ROLE_BORER, @@ -53,6 +54,7 @@ opened = FALSE to_chat(user, "Yet the borer after looking at you quickly retreats back into their cage, visibly scared. Perhaps try later?") playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + update_appearance() var/mob/dead/observer/picked_candidate = pick(candidates) From f0b6ea7a4da5ec4b1edb08f65e828da789813047 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 11 Feb 2024 08:59:28 +0100 Subject: [PATCH 44/67] bit more TGUI work --- .../borers/code/cortical_borer_chems.dm | 22 +-- .../tgui/interfaces/AntagInfoBorer.tsx | 181 +++++++++++++++++- 2 files changed, 191 insertions(+), 12 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm index 2ad142cc7579..63a1cbdbb61d 100644 --- a/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm +++ b/monkestation/code/modules/antagonists/borers/code/cortical_borer_chems.dm @@ -3,19 +3,19 @@ name = "Unknown Methamphetamine Isomer" overdose_threshold = 40 -/datum/reagent/drug/methamphetamine/borer_version/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/drug/methamphetamine/borer_version/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.") if(SPT_PROB(2.5, seconds_per_tick)) - to_chat(M, span_notice("[high_message]")) - M.add_mood_event("tweaking", /datum/mood_event/stimulant_medium, name) - M.AdjustStun(-40 * REM * seconds_per_tick) - M.AdjustKnockdown(-40 * REM * seconds_per_tick) - M.AdjustUnconscious(-40 * REM * seconds_per_tick) - M.AdjustParalyzed(-40 * REM * seconds_per_tick) - M.AdjustImmobilized(-40 * REM * seconds_per_tick) - M.stamina.adjust(2 * REM * seconds_per_tick, 0) - M.set_jitter_if_lower(5 SECONDS) + to_chat(affected_mob, span_notice("[high_message]")) + affected_mob.add_mood_event("tweaking", /datum/mood_event/stimulant_medium, name) + affected_mob.AdjustStun(-40 * REM * seconds_per_tick) + affected_mob.AdjustKnockdown(-40 * REM * seconds_per_tick) + affected_mob.AdjustUnconscious(-40 * REM * seconds_per_tick) + affected_mob.AdjustParalyzed(-40 * REM * seconds_per_tick) + affected_mob.AdjustImmobilized(-40 * REM * seconds_per_tick) + affected_mob.stamina.adjust(2 * REM * seconds_per_tick, TRUE) + affected_mob.set_jitter_if_lower(4 SECONDS * REM * seconds_per_tick) if(SPT_PROB(2.5, seconds_per_tick)) - M.emote(pick("twitch", "shiver")) + affected_mob.emote(pick("twitch", "shiver")) ..() . = TRUE diff --git a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx index 2ce27e532d26..9c3d550b8ee5 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx @@ -67,9 +67,25 @@ export const AntagInfoBorer = (props: any, context: any) => { onClick={() => setTab(2)}> Ability explanations + setTab(3)}> + Borer side-effects + + setTab(4)}> + Basic chemical information + {tab === 1 && } {tab === 2 && } + {tab === 3 && } + {tab === 4 && } ); @@ -156,7 +172,7 @@ const BorerAbilities = (props: any, context: any) => { const { act, data } = useBackend(context); return ( - + @@ -222,3 +238,166 @@ const AbilitySection = (props: any, context: any) => {
); }; + +const DisadvantageInfo = () => { + return ( + + +
+ + + + Whilst in a host you can provide many benefits, but also + dangerous side-effects due to your sensitive brain manipulation. + Here's how to prevent them + +
+
+ + 1. Whilst inside of a host we will passivelly make their health + unable to be read due to our body obstructing the somatosensory + cortex signals + +
+ + Prevention method - observe the hosts health carefully using + "Check Blood", heal any injuries and inform the host + about any major wounds + +
+
+ + 2. Whilst inside of a host we will slowly deal toxin damage + over-time up to 80 in total. This can be deadly when combined + with any amount of brute/burn damage + +
+ + Prevention method - observe the hosts health carefully using + "Check Blood", inject toxin damage restoring chemicals + +
+
+ + 3. Whilst inside of a host most of our actions will deal brain + damage including generating evolution and chemical evolution + points, due to eighter sensetivelly manipulating the host's + neurons or needing to "aquire" more space for growth + +
+ + Prevention method - observe the hosts health carefully using + "Check Blood", inject mannitol to cure brain damage, + inject neurine for any brain traumas that might have been a + result of our expansion + +
+
+
+
+
+ ); +}; + +const BasicChemistry = () => { + return ( + + +
+ + + + Secreting chemicals has proven difficult for many borers, yet + you have prepared carefully for your first expendition into the + hosts body. Lets not mess it up by killing them. + +
+ + This is only the bare minimum of what we should get knowledgable + about + +
+
+ Unknown Methamphetamine Isomer +
+ + A specially advanced version of what our hosts call + "meth". It has all the benefits of meth without + causing any brain damage to the host and has a higher overdose + +
+ Overdose: 40 units +
+
+ Spaceacillin +
+ + Helps our hosts immune system, making it quickly gain resistance + to any pathogens inside of the host. + +
+ + While being effective it will most likelly not be enough to + fully cure our host + +
+
+ Convermol +
+ + Quickly restores our hosts + Oxygen damage at the cost + of causing 1:5th the toxin damage to our host + +
+ Overdose: 35 units +
+
+ Lenturi +
+ + Quickly restores our hosts + Burn damage at the cost + of causing slight stomach damage and slowing down our host as + long as its in their system + +
+
+ Libital +
+ + Quickly restores our hosts + Brute damage at the cost + of causing slight liver damage. + +
+
+ multiver +
+ + Purges toxins and medicines inside of our host while healing + Toxin damage, at the + cost of slight lung damage. + +
+ + The more unique medicines the host has in their system, the more + this chemical heals. + +
+ At 2 unique medicines it no longer purges medicines +
+
+ Seiver +
+ + Heals Toxin damage at the + slight cost of heart damage + +
+
+
+
+
+ ); +}; From 903c9baa50faf87daad4844a16e16dec1e7cc5e7 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 12 Feb 2024 00:53:43 +0100 Subject: [PATCH 45/67] misc fixes --- .../antagonists/borers/code/abilities/enter_host.dm | 9 +++++++-- tgui/packages/tgui/interfaces/AntagInfoBorer.tsx | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index 8f6bda2c5fe1..acf20e64e1d9 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -24,19 +24,24 @@ if(cortical_owner.host_sugar()) owner.balloon_alert(owner, "cannot function with sugar in host") return + owner.balloon_alert(owner, "detached from host") 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.organs + //log the interaction var/turf/human_turfone = get_turf(cortical_owner.human_host) var/logging_text = "[key_name(cortical_owner)] left [key_name(cortical_owner.human_host)] at [loc_name(human_turfone)]" cortical_owner.log_message(logging_text, LOG_GAME) cortical_owner.human_host.log_message(logging_text, LOG_GAME) + + var/obj/item/organ/internal/borer_body/borer_organ = locate() in cortical_owner.human_host.organs if(borer_organ) borer_organ.Remove(cortical_owner.human_host) + cortical_owner.forceMove(human_turfone) cortical_owner.human_host = null + StartCooldown() return @@ -55,7 +60,7 @@ if(!(listed_human.dna.species.inherent_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) continue - // hosts need to be organic + // hosts NEED to be organic if(!(listed_human.mob_biotypes & MOB_ORGANIC) && cortical_owner.organic_restricted) to_chat(cortical_owner, span_warning("[listed_human] has incompatible biology with us!")) continue diff --git a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx index 9c3d550b8ee5..c53959dbfda9 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx @@ -281,7 +281,7 @@ const DisadvantageInfo = () => { 3. Whilst inside of a host most of our actions will deal brain damage including generating evolution and chemical evolution - points, due to eighter sensetivelly manipulating the host's + points, due to either sensetivelly manipulating the host's neurons or needing to "aquire" more space for growth
From 5f76b912e737ef2c3817017c928b9f0d6c1b6b7e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 12 Feb 2024 06:45:08 +0100 Subject: [PATCH 46/67] the grand borer warfare DLC --- code/modules/assembly/mousetrap.dm | 7 +++++++ monkestation/code/modules/antagonists/borers/readme.md | 2 ++ monkestation/code/modules/cargo/crates/security.dm | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 4ab9cb938205..d7d9e5b8d831 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -147,6 +147,13 @@ else if(isregalrat(target)) visible_message(span_boldannounce("Skreeeee!")) //He's simply too large to be affected by a tiny mouse trap. + // MONKESTATION ADDITION START -- ID:CORTICAL_BORERS + else if(iscorticalborer(target)) + var/mob/living/basic/cortical_borer/pest = target + visible_message(span_boldannounce("SPLAT!")) + pest.adjust_health(50) + // MONKESTATION ADDITION END + playsound(src, 'sound/effects/snap.ogg', 50, TRUE) pulse() diff --git a/monkestation/code/modules/antagonists/borers/readme.md b/monkestation/code/modules/antagonists/borers/readme.md index c2d9f0835f9d..57eeb99a700d 100644 --- a/monkestation/code/modules/antagonists/borers/readme.md +++ b/monkestation/code/modules/antagonists/borers/readme.md @@ -25,7 +25,9 @@ code/modules/antagonists/changeling/powers/panacea.dm -- If you are a changeling code/__DEFINES/~monkestation/actionspeed_modification.dm -- Added the actionspeed modifier ID for the borers here... maybe should move it code/__DEFINES/~monkestation/antagonists.dm -- Bunch of bitflags, iscorticalborer() check and evolution defines code/__DEFINES/~monkestation/role_preferences.dm -- Role preference for borers + monkestation/code/modules/uplink/uplink_items/misc.dm -- Uplink entry for spawning neutered borers in +monkestation/code/modules/cargo/crates/security.dm -- Contains the cargo crate for getting borer cages out of tgui/packages/tgui/interfaces/AntagInfoBorer.tsx -- TGUI window explaining what the borers objectives are, and how to use abilities tgui/packages/tgui/interfaces/BorerChem.js -- Allows the borers to inject chemicals, very sensitive diff --git a/monkestation/code/modules/cargo/crates/security.dm b/monkestation/code/modules/cargo/crates/security.dm index 6b826895e7af..d21fc2a5f3df 100644 --- a/monkestation/code/modules/cargo/crates/security.dm +++ b/monkestation/code/modules/cargo/crates/security.dm @@ -38,3 +38,11 @@ /obj/item/ammo_box/c35/rubber = 1, ) crate_name = ".35 Auto Ammo crate" + +/datum/supply_pack/security/borer_cage + name = "Borer cage" + desc = "Ever needed capture those pesky illegal borers to put them on a trial? Well this crate if for you!" + cost = CARGO_CRATE_VALUE * 10 + contraband = TRUE + contains = list(/obj/item/cortical_cage) + crate_name = "anti-borer crate" From 9e4a44d7e1e33cb961949509f564f10f604f3b88 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 12 Feb 2024 06:52:39 +0100 Subject: [PATCH 47/67] switch around the chemicals we know about --- .../tgui/interfaces/AntagInfoBorer.tsx | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx index c53959dbfda9..e54bf1e61e76 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBorer.tsx @@ -318,27 +318,30 @@ const BasicChemistry = () => {

- Unknown Methamphetamine Isomer + Libital
- A specially advanced version of what our hosts call - "meth". It has all the benefits of meth without - causing any brain damage to the host and has a higher overdose + Quickly restores our hosts + Brute damage at the cost + of causing slight liver damage.
- Overdose: 40 units -

- Spaceacillin + Lenturi
- Helps our hosts immune system, making it quickly gain resistance - to any pathogens inside of the host. + Quickly restores our hosts + Burn damage at the cost + of causing slight stomach damage and slowing down our host as + long as its in their system
+
+ Seiver +
- While being effective it will most likelly not be enough to - fully cure our host + Heals Toxin damage at the + slight cost of heart damage

@@ -353,22 +356,27 @@ const BasicChemistry = () => { Overdose: 35 units

- Lenturi + Unknown Methamphetamine Isomer
- Quickly restores our hosts - Burn damage at the cost - of causing slight stomach damage and slowing down our host as - long as its in their system + A specially advanced version of what our hosts call + "meth". It has all the benefits of meth without + causing any brain damage to the host and has a higher overdose
+ Overdose: 40 units +

- Libital + Spaceacillin
- Quickly restores our hosts - Brute damage at the cost - of causing slight liver damage. + Helps our hosts immune system, making it quickly gain resistance + to any pathogens inside of the host. + +
+ + While being effective it will most likelly not be enough to + fully cure our host

@@ -386,14 +394,6 @@ const BasicChemistry = () => {
At 2 unique medicines it no longer purges medicines -
-
- Seiver -
- - Heals Toxin damage at the - slight cost of heart damage - From c125284cfad1cb33c125d674a31e9b797cb92d50 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 12 Feb 2024 08:05:36 +0100 Subject: [PATCH 48/67] quite a few fixes --- .../borers/code/abilities/spawn_offspring.dm | 2 +- .../code/modules/antagonists/borers/code/items/egg.dm | 10 ++++++---- .../antagonists/borers/code/items/empowered_egg.dm | 4 ++-- .../antagonists/borers/code/mobs/cortical_borer.dm | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index a2ceadfb3dbb..231a5f000613 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -67,7 +67,7 @@ /datum/action/cooldown/borer/produce_offspring/proc/produce_egg() var/mob/living/basic/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) + var/obj/effect/mob_spawn/ghost_role/borer_egg/spawned_egg = new(borer_turf) spawned_egg.generation = (cortical_owner.generation + 1) cortical_owner.children_produced++ if(cortical_owner.children_produced == GLOB.objective_egg_egg_number) diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index 2521b1da6aed..96ab5df27667 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -39,18 +39,20 @@ /obj/effect/mob_spawn/ghost_role/borer_egg/special(mob/living/spawned_mob, mob/mob_possessor) . = ..() - spawned_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) + var/mob/living/basic/cortical_borer/cortical_mob = spawned_mob + cortical_mob.generation = generation + cortical_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) if(generation == 0) //The first ever borer gets a special name - spawned_mob.name = "The hivequeen cortical borer" + cortical_mob.name = "The hivequeen cortical borer" else //so their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 - spawned_mob.name = "cortical borer ([generation]-[rand(100,999)])" + cortical_mob.name = "cortical borer ([generation]-[rand(100,999)])" QDEL_NULL(host_egg) /obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team) . = ..() - host_egg = new host_egg(get_turf(src)) + host_egg = new(get_turf(src)) host_egg.host_spawner = src forceMove(host_egg) var/area/src_area = get_area(src) diff --git a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm index 99b0903591b0..3d82bf07a651 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm @@ -18,7 +18,7 @@ /// How long it takes to burst from a corpse var/burst_time = 3 MINUTES /// What generation the egg will be - var/generation = 1 + var/generation = 0 /obj/item/organ/internal/empowered_borer_egg/on_find(mob/living/finder) ..() @@ -61,4 +61,4 @@ owner.visible_message(span_danger("[spawned_cb] explodes out of [owner]'s chest, sending gore flying everywhere!"), span_danger("[spawned_cb] explodes out of your chest, giblets flying everywhere!")) spawned_cb.generation = generation spawned_cb.ckey = new_borer.ckey - spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer) + spawned_cb.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 91128fc3a901..8a2b07310648 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -263,6 +263,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) if(mind) if(!mind.has_antag_datum(antagonist_datum)) + mind.name = name mind.add_antag_datum(antagonist_datum) for(var/focus_path in subtypesof(/datum/borer_focus)) From b05f1acce241f54f929ec61254e9d73ba8ef4fca Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 13 Feb 2024 22:51:41 +0100 Subject: [PATCH 49/67] cortical names, mainly for admin reports --- .../borers/code/first_borer_names.txt | 30 +++++++ .../antagonists/borers/code/items/egg.dm | 7 +- .../borers/code/mobs/cortical_borer.dm | 79 +++++++++++-------- .../borers/code/mobs/neutered_borer.dm | 5 +- .../borers/code/second_borer_names.txt | 29 +++++++ 5 files changed, 108 insertions(+), 42 deletions(-) create mode 100644 monkestation/code/modules/antagonists/borers/code/first_borer_names.txt create mode 100644 monkestation/code/modules/antagonists/borers/code/second_borer_names.txt diff --git a/monkestation/code/modules/antagonists/borers/code/first_borer_names.txt b/monkestation/code/modules/antagonists/borers/code/first_borer_names.txt new file mode 100644 index 000000000000..ad17333e9653 --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/first_borer_names.txt @@ -0,0 +1,30 @@ +Whispering Willy +Creepy Carl +Slinking Sam +Tunneling Tim +Sibilant Sally +Sly Sid +Murmuring Maggie +Hushed Hank +Drifter Dave +Murky Molly +Mysterious Mike +Hush-Hush Harry +Whispering Wendy +Slithering Steve +Eerie Emily +Silent Stan +Covert Connie +Stealthy Sarah +Wriggling Walter +Murmur Max +Slinking Sophie +Whispering Wayne +Sneaky Sue +Wily Walter +Serpentine Sally +Quiet Quincy +Shhh-Shhh Sharon +Rustling Rupert +Sly Silvia +Lurking Larry diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index 96ab5df27667..c64d63cdf109 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -42,12 +42,7 @@ var/mob/living/basic/cortical_borer/cortical_mob = spawned_mob cortical_mob.generation = generation cortical_mob.mind.add_antag_datum(/datum/antagonist/cortical_borer/hivemind) - if(generation == 0) - //The first ever borer gets a special name - cortical_mob.name = "The hivequeen cortical borer" - else - //so their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 - cortical_mob.name = "cortical borer ([generation]-[rand(100,999)])" + cortical_mob.create_name() QDEL_NULL(host_egg) /obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 8a2b07310648..11c463470f2b 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -7,6 +7,9 @@ GLOBAL_LIST_EMPTY(willing_hosts) GLOBAL_LIST_EMPTY(cortical_borers) +GLOBAL_LIST_INIT(borer_first_name, world.file2list("monkestation/code/modules/antagonists/borers/code/first_borer_names.txt")) +GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/antagonists/borers/code/second_borer_names.txt")) + /// This divisor controls how fast body temperature changes to match the environment #define BODYTEMP_DIVISOR 16 @@ -86,19 +89,19 @@ GLOBAL_LIST_EMPTY(cortical_borers) icon_dead = "brainslug_dead" maxHealth = 25 health = 25 - //they need to be able to pass tables and mobs + // They need to be able to pass tables and mobs pass_flags = PASSTABLE | PASSMOB density = FALSE - //they are below mobs, or below tables + // They are below mobs, or below tables layer = BELOW_MOB_LAYER - //corticals are tiny + // Corticals are tiny mob_size = MOB_SIZE_TINY mob_biotypes = MOB_ORGANIC|MOB_BUG - //because they are small, why can't they be held? + // Because they are small, why can't they be held? can_be_held = TRUE - ///what chemicals borers know, starting with none + /// What chemicals borers know, starting with none var/list/known_chemicals = list() - ///what chemicals the borer can learn + /// What chemicals the borer can learn var/list/potential_chemicals = list( /datum/reagent/drug/methamphetamine/borer_version, @@ -129,26 +132,28 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/reagent/toxin/heparin, /datum/reagent/toxin/mindbreaker, ) - ///blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these + /// Blacklisted chemicals - separate from chemicals that cannot be synthesized, borers specifically cannot learn these var/list/blacklisted_chemicals = list() - ///how old the borer is, starting from zero. Goes up only when inside a host + + /// How old the borer is, starting from zero. Goes up only when inside a host var/maturity_age = 0 - //just a little "timer" to compare to world.time + /// Just a little "timer" to compare to world.time var/timed_maturity = 0 + /// How many times you've levelled up over all var/level = 0 - ///the amount of "evolution" points a borer has for chemicals. Start with one + /// The amount of "evolution" points a borer has for chemicals. Start with one var/chemical_evolution = 1 - ///the amount of "evolution" points a borer has for stats + /// The amount of "evolution" points a borer has for stats var/stat_evolution = 0 - ///how many chemical points the borer can have. Can be upgraded + /// How many chemical points the borer can have. Can be upgraded var/max_chemical_storage = 50 - ///how many chemical points the borer has + /// How many chemical points the borer has var/chemical_storage = 50 - ///how fast chemicals are gained. Goes up only when inside a host + /// How fast chemicals are gained. Goes up only when inside a host var/chemical_regen = 1 /// How much health you gain per level @@ -161,7 +166,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// Chemical regen you gain per level var/chem_regen_per_level = 1 - ///the list of actions that the borer has + /// The list of actions that the borer has var/list/datum/action/cooldown/borer/known_abilities = list( /datum/action/cooldown/borer/toggle_hiding, /datum/action/cooldown/borer/choosing_host, @@ -175,32 +180,32 @@ GLOBAL_LIST_EMPTY(cortical_borers) /datum/action/cooldown/borer/check_blood, ) - ///the host + /// The host var/mob/living/carbon/human/human_host - //what the host gains or loses with the borer + /// What the host gains or loses with the borer var/list/hosts_abilities = list() - ///multiplies the current health up to the max health + /// Multiplies the current health up to the max health var/health_regen = 1.02 - //holds the chems right before injection + /// Holds the chems right before injection var/obj/item/reagent_containers/reagent_holder - //just a flavor kind of thing + /// Lust a flavor kind of thing var/generation = 0 /// List of focus datums var/list/possible_focuses = list() /// What focuses the borer has unlocked var/list/body_focuses = list() - ///how many children the borer has produced + /// How many children the borer has produced var/children_produced = 0 - ///how many blood chems have been learned through the blood + /// How many blood chems have been learned through the blood var/blood_chems_learned = 0 - ///we dont want to spam the chat + /// We dont want to spam the chat var/deathgasp_once = FALSE - //the limit to the chemical and stat evolution + // The limit to the chemical and stat evolution var/limited_borer = 10 - ///borers can only enter biologicals if true + /// Borers can only enter biologicals if true var/organic_restricted = TRUE - ///borers are unable to enter changelings if true + /// Borers are unable to enter changelings if true var/changeling_restricted = TRUE /// Assoc list of chemical injection rates that the borer can have var/static/list/injection_rates = list( @@ -231,6 +236,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) /// Used to give the borer the antagonist datum var/antagonist_datum = /datum/antagonist/cortical_borer/hivemind + /// Skips unique borer status tab text, used for unique borer subtypes with their own status tabs var/skip_status_tab = FALSE /mob/living/basic/cortical_borer/Initialize(mapload) @@ -247,12 +253,7 @@ GLOBAL_LIST_EMPTY(cortical_borers) borer_matrix.Scale(0.5, 0.5) transform = borer_matrix - if(generation == 0) - //The first ever borer gets a special name - name = "The hivequeen [initial(name)]" - else - //so their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 - name = "[initial(name)] ([generation]-[rand(100,999)])" + create_name() GLOB.cortical_borers += src reagent_holder = new /obj/item/reagent_containers/borer(src) @@ -263,7 +264,6 @@ GLOBAL_LIST_EMPTY(cortical_borers) if(mind) if(!mind.has_antag_datum(antagonist_datum)) - mind.name = name mind.add_antag_datum(antagonist_datum) for(var/focus_path in subtypesof(/datum/borer_focus)) @@ -359,6 +359,19 @@ GLOBAL_LIST_EMPTY(cortical_borers) if(mind) mind.add_antag_datum(antagonist_datum) +/mob/living/basic/cortical_borer/proc/create_name() + var/picked_first_name = pick(GLOB.borer_first_name) + var/picked_second_name = pick(GLOB.borer_second_name) + // So their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 + // Additionally we add in a random title, + // mainly so people can ahelp borers quicker and admins dont have to look through the logs of the 5 borers that were inside you + name = "[initial(name)] ([picked_first_name]: [picked_second_name]) ([generation]-[rand(100,999)])" + + if(istype(/mob/living/basic/cortical_borer/empowered, src)) // lets also distinguish empowered borers from normal ones + name = "larger [name]" + + if(generation == 0) //The first ever borer gets a special name + name = "The hivequeen [initial(name)]" //check if we are inside a human /mob/living/basic/cortical_borer/proc/inside_human() diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm index 1e47813ba02e..4a96ece1ceca 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/neutered_borer.dm @@ -3,10 +3,10 @@ */ /mob/living/basic/cortical_borer/neutered - neutered = TRUE antagonist_datum = /datum/antagonist/cortical_borer - generation = 1 + neutered = TRUE skip_status_tab = TRUE + generation = 1 /mob/living/basic/cortical_borer/neutered/get_status_tab_items() . = ..() @@ -16,4 +16,3 @@ . += "" if(host_sugar()) . += "Sugar detected! Unable to generate resources!" - . += "" diff --git a/monkestation/code/modules/antagonists/borers/code/second_borer_names.txt b/monkestation/code/modules/antagonists/borers/code/second_borer_names.txt new file mode 100644 index 000000000000..d60b1fe9849b --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/second_borer_names.txt @@ -0,0 +1,29 @@ +The Ear Intruder +Master of the Ear Canal +Whisperer of Secrets +Ear Explorer Extraordinaire +Whisperer in the Dark +Eardrum Trespasser +Ear Conqueror +The Inner Ear Invader +Whispering Wanderer of Ears +Mistress of Ear Infiltration +The Silent Traveler +Ear Canal Navigator +Master of Ear Intrusion +Enchanter of Auditory Passages +Ear Passage Pioneer +Whisperer of Inner Depths +Eardrum Sleuth +Ear Whisperer +Maestro of the Ear +Stealthy Ear Invader +Ear Canal Conqueror +Master of Ear Infiltration +Whispering Intruder +Siren of the Ear +Eardrum Explorer +Secretive Ear Seeker +Eardrum Navigator +Slinker of Ears +Laird of the Ear Canal From 487c186808330b741631e54c55d3eeaa91968253 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 14 Feb 2024 02:05:01 +0100 Subject: [PATCH 50/67] name fixes --- .../borers/code/first_borer_names.txt | 30 ---------- .../borers/code/mobs/cortical_borer.dm | 4 +- .../borers/code/mobs/name_lists.dm | 56 +++++++++++++++++++ .../borers/code/second_borer_names.txt | 29 ---------- tgstation.dme | 1 + 5 files changed, 58 insertions(+), 62 deletions(-) delete mode 100644 monkestation/code/modules/antagonists/borers/code/first_borer_names.txt create mode 100644 monkestation/code/modules/antagonists/borers/code/mobs/name_lists.dm delete mode 100644 monkestation/code/modules/antagonists/borers/code/second_borer_names.txt diff --git a/monkestation/code/modules/antagonists/borers/code/first_borer_names.txt b/monkestation/code/modules/antagonists/borers/code/first_borer_names.txt deleted file mode 100644 index ad17333e9653..000000000000 --- a/monkestation/code/modules/antagonists/borers/code/first_borer_names.txt +++ /dev/null @@ -1,30 +0,0 @@ -Whispering Willy -Creepy Carl -Slinking Sam -Tunneling Tim -Sibilant Sally -Sly Sid -Murmuring Maggie -Hushed Hank -Drifter Dave -Murky Molly -Mysterious Mike -Hush-Hush Harry -Whispering Wendy -Slithering Steve -Eerie Emily -Silent Stan -Covert Connie -Stealthy Sarah -Wriggling Walter -Murmur Max -Slinking Sophie -Whispering Wayne -Sneaky Sue -Wily Walter -Serpentine Sally -Quiet Quincy -Shhh-Shhh Sharon -Rustling Rupert -Sly Silvia -Lurking Larry diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 11c463470f2b..7e640654f6af 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -360,12 +360,10 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a mind.add_antag_datum(antagonist_datum) /mob/living/basic/cortical_borer/proc/create_name() - var/picked_first_name = pick(GLOB.borer_first_name) - var/picked_second_name = pick(GLOB.borer_second_name) // So their gen and a random. ex 1-288 is first gen named 288, 4-483 is fourth gen named 483 // Additionally we add in a random title, // mainly so people can ahelp borers quicker and admins dont have to look through the logs of the 5 borers that were inside you - name = "[initial(name)] ([picked_first_name]: [picked_second_name]) ([generation]-[rand(100,999)])" + name = "[initial(name)] ([pick(borer_first_names)]: [pick(borer_second_names)]) ([generation]-[rand(100,999)])" if(istype(/mob/living/basic/cortical_borer/empowered, src)) // lets also distinguish empowered borers from normal ones name = "larger [name]" diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/name_lists.dm b/monkestation/code/modules/antagonists/borers/code/mobs/name_lists.dm new file mode 100644 index 000000000000..e902a07c552f --- /dev/null +++ b/monkestation/code/modules/antagonists/borers/code/mobs/name_lists.dm @@ -0,0 +1,56 @@ +/mob/living/basic/cortical_borer + var/list/borer_first_names = list( + "Whispering Willy", + "Creepy Carl", + "Slinking Sam", + "Tunneling Tim", + "Sly Sid", + "Murmuring Maggie", + "Hushed Hank", + "Drifter Dave", + "Murky Molly", + "Mysterious Mike", + "Hush-Hush Harry", + "Slithering Steve", + "Eerie Emily", + "Silent Stan", + "Covert Connie", + "Stealthy Sarah", + "Wriggling Walter", + "Sneaky Sue", + "Serpentine Sally", + "Quiet Quincy", + "Shhh-Shhh Sharon", + "Rustling Rupert", + "Lurking Larry", + ) + var/list/borer_second_names = list( + "The Ear Intruder", + "Master of the Ear Canal", + "Whisperer of Secrets", + "Ear Explorer Extraordinaire", + "Whisperer in the Dark", + "Eardrum Trespasser", + "Ear Conqueror", + "The Inner Ear Invader", + "Whispering Wanderer of Ears", + "Mistress of Ear Infiltration", + "The Silent Traveler", + "Ear Canal Navigator", + "Master of Ear Intrusion", + "Enchanter of Auditory Passages", + "Ear Passage Pioneer", + "Whisperer of Inner Depths", + "Eardrum Sleuth", + "Ear Whisperer", + "Maestro of the Ear", + "Stealthy Ear Invader", + "Master of Ear Infiltration", + "Whispering Intruder", + "Siren of the Ear", + "Eardrum Explorer", + "Secretive Ear Seeker", + "Eardrum Navigator", + "Slinker of Ears", + "Laird of the Ear Canal", + ) diff --git a/monkestation/code/modules/antagonists/borers/code/second_borer_names.txt b/monkestation/code/modules/antagonists/borers/code/second_borer_names.txt deleted file mode 100644 index d60b1fe9849b..000000000000 --- a/monkestation/code/modules/antagonists/borers/code/second_borer_names.txt +++ /dev/null @@ -1,29 +0,0 @@ -The Ear Intruder -Master of the Ear Canal -Whisperer of Secrets -Ear Explorer Extraordinaire -Whisperer in the Dark -Eardrum Trespasser -Ear Conqueror -The Inner Ear Invader -Whispering Wanderer of Ears -Mistress of Ear Infiltration -The Silent Traveler -Ear Canal Navigator -Master of Ear Intrusion -Enchanter of Auditory Passages -Ear Passage Pioneer -Whisperer of Inner Depths -Eardrum Sleuth -Ear Whisperer -Maestro of the Ear -Stealthy Ear Invader -Ear Canal Conqueror -Master of Ear Infiltration -Whispering Intruder -Siren of the Ear -Eardrum Explorer -Secretive Ear Seeker -Eardrum Navigator -Slinker of Ears -Laird of the Ear Canal diff --git a/tgstation.dme b/tgstation.dme index 4f341ec5fb1b..50bb8bb02d6a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5778,6 +5778,7 @@ #include "monkestation\code\modules\antagonists\borers\code\items\imprisonment_cage.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\cortical_borer.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\empowered_borer.dm" +#include "monkestation\code\modules\antagonists\borers\code\mobs\name_lists.dm" #include "monkestation\code\modules\antagonists\borers\code\mobs\neutered_borer.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing.dm" #include "monkestation\code\modules\antagonists\brainwashing\brainwashing_alert.dm" From fc4ab8e698279809af5ad52b909d2a4e12dd2ade Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 21 Feb 2024 02:05:02 +0100 Subject: [PATCH 51/67] adds the OH_GOD_WE_FUCKED_UP() proc --- .../borers/code/abilities/spawn_offspring.dm | 4 ++++ .../borers/code/mobs/cortical_borer.dm | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index 231a5f000613..eb579661f093 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -38,12 +38,16 @@ switch(eggroll) if(1 to 34) cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_BASIC) + owner.balloon_alert(owner, "Cerebrum damaged!") if(35 to 60) cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY) + owner.balloon_alert(owner, "Cerebellum damaged!") if(61 to 71) cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_SURGERY) + owner.balloon_alert(owner, "Brainstem damaged!") if(72 to 75) cortical_owner.human_host.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY) + owner.balloon_alert(owner, "Brainstem severelly damaged!") 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) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 7e640654f6af..f4c36fea84b4 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -270,6 +270,7 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a possible_focuses += new focus_path do_evolution(/datum/borer_evolution/base) + INVOKE_ASYNC(src, PROC_REF(resolve_misc_issues)) // if things can fail, they will /mob/living/basic/cortical_borer/Destroy() human_host = null @@ -371,6 +372,27 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a if(generation == 0) //The first ever borer gets a special name name = "The hivequeen [initial(name)]" +// if things can go wrong, they will. So this proc is an emergency measure meant to resolve them +/mob/living/basic/cortical_borer/proc/resolve_misc_issues() + sleep(5 SECONDS) // give everything some time to resolve itself, if it fails then we come in + if(name == initial(name)) + message_admins("[src] had its name initialization fail, this should never happen! Automatically gave a backup name.") + create_name() + + if(mind) // can actually happen if admins turn someone into a borer in a weird enough way + if(!mind.has_antag_datum(antagonist_datum)) + message_admins("[src] had its antag datum initialization fail, this should never happen! Automatically gave the mob antag datum [antagonist_datum]") + mind.add_antag_datum(antagonist_datum) + + else // apparently can happen with the neutered borer spawner, not a damn clue what causes it + message_admins("[src] spawned despite having no ghost, automatically informed ghosts!") + notify_ghosts( + "[src] needs to obtain a ghost, click on it to submit yourself!", + source = src, + action = NOTIFY_ORBIT, + header = "The code did not give it one" + ) + //check if we are inside a human /mob/living/basic/cortical_borer/proc/inside_human() if(!ishuman(loc)) From 2606b2332b233a66bacb0ed2c193e7ea6adc2b6c Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 21 Feb 2024 06:21:36 +0100 Subject: [PATCH 52/67] fixes --- .../modules/antagonists/borers/code/items/borer_spawner.dm | 1 + .../modules/antagonists/borers/code/mobs/cortical_borer.dm | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 148d53e77981..3ba03ed51b11 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -70,6 +70,7 @@ protect_objective.update_explanation_text() listen_objective.explanation_text = "Listen to any commands given by [user.name]" + listen_objective.completed = TRUE // its just an objective for flavor less-so than for greentext borer_antagonist_datum.objectives += protect_objective borer_antagonist_datum.objectives += listen_objective diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index f4c36fea84b4..8eba5fd899db 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -376,16 +376,16 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a /mob/living/basic/cortical_borer/proc/resolve_misc_issues() sleep(5 SECONDS) // give everything some time to resolve itself, if it fails then we come in if(name == initial(name)) - message_admins("[src] had its name initialization fail, this should never happen! Automatically gave a backup name.") + message_admins("[ADMIN_LOOKUPFLW(src)] had its name initialization fail, this should never happen! Automatically gave a backup name.") create_name() if(mind) // can actually happen if admins turn someone into a borer in a weird enough way if(!mind.has_antag_datum(antagonist_datum)) - message_admins("[src] had its antag datum initialization fail, this should never happen! Automatically gave the mob antag datum [antagonist_datum]") + message_admins("[ADMIN_LOOKUPFLW(src)] had its antag datum initialization fail, this should never happen! Automatically gave the mob antag datum [antagonist_datum]") mind.add_antag_datum(antagonist_datum) else // apparently can happen with the neutered borer spawner, not a damn clue what causes it - message_admins("[src] spawned despite having no ghost, automatically informed ghosts!") + message_admins("[ADMIN_LOOKUPFLW(src)] spawned despite having no ghost, automatically informed ghosts!") notify_ghosts( "[src] needs to obtain a ghost, click on it to submit yourself!", source = src, From ef6cd1573d3861f851ce40a142f1455bab106fe7 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 22 Feb 2024 19:17:42 +0100 Subject: [PATCH 53/67] initial suggested changes --- .../borers/code/abilities/force_speech.dm | 2 +- .../borers/code/abilities/spawn_offspring.dm | 3 +- .../antagonists/borers/code/focus_datum.dm | 37 ++++++++++--------- .../borers/code/items/borer_spawner.dm | 5 ++- .../antagonists/borers/code/items/egg.dm | 6 +-- .../borers/code/items/empowered_egg.dm | 11 ++---- .../borers/code/items/imprisonment_cage.dm | 10 ++--- .../borers/code/mobs/cortical_borer.dm | 2 +- 8 files changed, 37 insertions(+), 39 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm index 418b922b4a2e..531220c4392f 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/force_speech.dm @@ -23,7 +23,7 @@ var/obj/item/organ/internal/brain/victim_brain = cortical_owner.human_host.get_organ_slot(ORGAN_SLOT_BRAIN) if(victim_brain) cortical_owner.human_host.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * cortical_owner.host_harm_multiplier) - cortical_host.say(message = borer_message, forced = TRUE) + cortical_host.say(message = borer_message, forced = "borer ([key_name(cortical_owner)])") 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)]" cortical_owner.log_message(logging_text, LOG_GAME) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm index eb579661f093..87b137f78851 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/spawn_offspring.dm @@ -70,8 +70,7 @@ /datum/action/cooldown/borer/produce_offspring/proc/produce_egg() var/mob/living/basic/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(borer_turf) + var/obj/effect/mob_spawn/ghost_role/borer_egg/spawned_egg = new(cortical_owner.drop_location()) spawned_egg.generation = (cortical_owner.generation + 1) cortical_owner.children_produced++ if(cortical_owner.children_produced == GLOB.objective_egg_egg_number) diff --git a/monkestation/code/modules/antagonists/borers/code/focus_datum.dm b/monkestation/code/modules/antagonists/borers/code/focus_datum.dm index b04a0f1a0ec7..61f2bf648bb9 100644 --- a/monkestation/code/modules/antagonists/borers/code/focus_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/focus_datum.dm @@ -5,73 +5,74 @@ var/cost = 5 /// Traits to add/remove var/list/traits = list() + /// Text that we send to the host when we give them a focus, if set + var/gain_text = FALSE + /// Text that we send to the host when the host loses a focus, if set + var/lose_text = FALSE /// Effects to take when the focus is added /datum/borer_focus/proc/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) SHOULD_CALL_PARENT(TRUE) + if(gain_text) + to_chat(host, span_notice("[gain_text]")) for(var/trait in traits) - if(HAS_TRAIT(host, trait)) - continue ADD_TRAIT(host, trait, REF(borer)) /// Effects to take when the focus is removed /datum/borer_focus/proc/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) SHOULD_CALL_PARENT(TRUE) - for(var/trait in traits) - if(!HAS_TRAIT_FROM(host, trait, REF(borer))) - continue - REMOVE_TRAIT(host, trait, REF(borer)) + if(lose_text) + to_chat(host, span_notice("[lose_text]")) + REMOVE_TRAITS_IN(host, REF(borer)) /datum/borer_focus/head name = "head focus" traits = list(TRAIT_NOFLASH, TRAIT_TRUE_NIGHT_VISION, TRAIT_KNOW_ENGI_WIRES) + gain_text = "Your eyes begin to feel strange..." + lose_text = "Your eyes begin to return to normal..." /datum/borer_focus/head/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("Your eyes begin to feel strange...")) + host.update_sight() return ..() /datum/borer_focus/head/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("Your eyes begin to return to normal...")) host.update_sight() return ..() /datum/borer_focus/chest name = "chest focus" traits = list(TRAIT_NOBREATH, TRAIT_NOHUNGER, TRAIT_STABLEHEART) + gain_text = "Your chest begins to slow down..." + lose_text = "Your chest begins to heave again..." /datum/borer_focus/chest/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("Your chest begins to slow down...")) - host.nutrition = NUTRITION_LEVEL_WELL_FED - return ..() - -/datum/borer_focus/chest/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("Your chest begins to heave again...")) + host.set_safe_hunger_level() return ..() /datum/borer_focus/arms name = "arm focus" traits = list(TRAIT_QUICKER_CARRY, TRAIT_QUICK_BUILD, TRAIT_SHOCKIMMUNE) + gain_text = "Your arms start to feel funny..." + lose_text = "Your arms start to feel normal again..." /datum/borer_focus/arms/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("Your arms start to feel funny...")) 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/basic/cortical_borer/borer) - to_chat(host, span_notice("Your arms start to feel normal again...")) borer.human_host.remove_actionspeed_modifier(ACTIONSPEED_ID_BORER) return ..() /datum/borer_focus/legs name = "leg focus" traits = list(TRAIT_LIGHT_STEP, TRAIT_FREERUNNING, TRAIT_SILENT_FOOTSTEPS) + gain_text = "You feel faster..." + lose_text = "You feel slower..." /datum/borer_focus/legs/on_add(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("You feel faster...")) host.add_movespeed_modifier(/datum/movespeed_modifier/focus_speed) return ..() /datum/borer_focus/legs/on_remove(mob/living/carbon/human/host, mob/living/basic/cortical_borer/borer) - to_chat(host, span_notice("You feel slower...")) host.remove_movespeed_modifier(/datum/movespeed_modifier/focus_speed) return ..() diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 3ba03ed51b11..a4132e9517cd 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -55,6 +55,7 @@ to_chat(user, "Yet the borer after looking at you quickly retreats back into their cage, visibly scared. Perhaps try later?") playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) update_appearance() + return var/mob/dead/observer/picked_candidate = pick(candidates) @@ -87,5 +88,5 @@ log_game("[key_name(new_mob)] was spawned as a borer by [key_name(user)]") visible_message("A borer wriggles out of the [src]!") - new /obj/item/cortical_cage(get_turf(src)) - QDEL_NULL(src) + new /obj/item/cortical_cage(drop_location()) + qdel(src) diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index c64d63cdf109..0fdb29aa578b 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -17,7 +17,7 @@ mob_name = "cortical borer" ///Type of mob that will be spawned mob_type = /mob/living/basic/cortical_borer - role_ban = ROLE_ALIEN + role_ban = ROLE_BORER show_flavor = TRUE prompt_name = "cortical borer" you_are_text = "You are a Cortical Borer." @@ -47,7 +47,7 @@ /obj/effect/mob_spawn/ghost_role/borer_egg/Initialize(mapload, datum/team/cortical_borers/borer_team) . = ..() - host_egg = new(get_turf(src)) + host_egg = new(drop_location()) host_egg.host_spawner = src forceMove(host_egg) var/area/src_area = get_area(src) @@ -68,7 +68,7 @@ /obj/item/borer_egg/attack_self(mob/user, modifiers) to_chat(user, span_notice("You crush [src] within your grasp.")) - new /obj/effect/decal/cleanable/food/egg_smudge(get_turf(user)) + new /obj/effect/decal/cleanable/food/egg_smudge(user.drop_location()) if(host_spawner) QDEL_NULL(host_spawner) qdel(src) diff --git a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm index 3d82bf07a651..bf90f9f5df89 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm @@ -36,26 +36,23 @@ /obj/item/organ/internal/empowered_borer_egg/Remove(mob/living/carbon/M, special = FALSE) . = ..() visible_message(span_warning("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)) + new /obj/effect/decal/cleanable/food/egg_smudge(drop_location()) qdel(src) /obj/item/organ/internal/empowered_borer_egg/proc/try_burst() - if(!owner) - qdel(src) - return - if(owner.stat != DEAD) + if(QDELETED(owner) || owner.stat != DEAD) qdel(src) return var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", 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)) + var/obj/effect/mob_spawn/ghost_role/borer_egg/empowered/borer_egg = new(owner.drop_location()) borer_egg.generation = generation var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST) chest.dismember() owner.visible_message(span_danger("An egg explodes out of [owner]'s chest, sending gore flying everywhere!"), span_danger("An egg explodes out of your chest, giblets flying everywhere!")) return var/mob/dead/observer/new_borer = pick(candidates) - var/mob/living/basic/cortical_borer/empowered/spawned_cb = new(get_turf(owner)) + var/mob/living/basic/cortical_borer/empowered/spawned_cb = new(owner.drop_location()) var/obj/item/bodypart/chest/chest = owner.get_bodypart(BODY_ZONE_CHEST) chest.dismember() owner.visible_message(span_danger("[spawned_cb] explodes out of [owner]'s chest, sending gore flying everywhere!"), span_danger("[spawned_cb] explodes out of your chest, giblets flying everywhere!")) diff --git a/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm b/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm index 30bb0efdbfdf..a49f67b4235d 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm @@ -51,7 +51,7 @@ /obj/item/cortical_cage/crowbar_act(mob/living/user, obj/item/tool) . = ..() if(internal_radio) - internal_radio.forceMove(get_turf(src)) + internal_radio.forceMove(drop_location()) user.visible_message("[internal_radio] pops off [src].", "You pop off [internal_radio] from [src].", "You hear a clicking sound then a loud metallic thunk.") internal_radio = null update_appearance() @@ -74,14 +74,14 @@ /obj/item/cortical_cage/relaymove(mob/living/user, direction) if(!iscorticalborer(user)) - user.forceMove(get_turf(src)) + user.forceMove(drop_location()) update_appearance() return if(opened) loc.visible_message(span_notice("[user] climbs out of [src]!"), \ span_warning("[user] jumps out of [src]!")) opened = FALSE - trapped_borer.forceMove(get_turf(src)) + trapped_borer.forceMove(drop_location()) trapped_borer = null update_appearance() return @@ -95,9 +95,9 @@ to_chat(loc, span_warning("You see [user] begin trying to squeeze through the bars!")) if(!do_after(user, rand(30 SECONDS, 40 SECONDS), target = user) || opened || !(user in contents)) return - loc.visible_message(span_warning("[user] squeezes through [src]'s handles!"), null, null, null, user) + loc.visible_message(span_warning("[user] squeezes through [src]'s handles!"), ignored_mobs = user) to_chat(user, span_boldannounce("Bingo, you squeeze through!")) opened = FALSE - trapped_borer.forceMove(get_turf(src)) + trapped_borer.forceMove(drop_location()) trapped_borer = null update_appearance() diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 8eba5fd899db..f0bf2580247a 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -434,7 +434,7 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a if(borer_organ) borer_organ.Remove(human_host) var/turf/human_turf = get_turf(human_host) - forceMove(human_turf) + forceMove(human_turf.drop_location()) human_host = null //borers shouldnt be able to whisper... From 32c49b3f0de91eb5d258bf41f4c6e06754fb4874 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 22 Feb 2024 20:35:20 +0100 Subject: [PATCH 54/67] misc fixes, an evolution var for added actions --- .../borers/code/evolution/evolution_datum.dm | 17 +++++++++++-- .../code/evolution/evolution_diveworm.dm | 9 ++----- .../code/evolution/evolution_hivelord.dm | 24 ++++--------------- .../code/evolution/evolution_symbiote.dm | 12 ++-------- .../borers/code/items/borer_spawner.dm | 2 +- .../borers/code/items/imprisonment_cage.dm | 2 +- .../borers/code/mobs/cortical_borer.dm | 2 +- 7 files changed, 27 insertions(+), 41 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm index f71d95a3302b..ad9c32d1492f 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_datum.dm @@ -11,11 +11,16 @@ 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 evolutions this one unlocks + var/list/unlocked_evolutions = list() + /// What action does this evolution unlock + var/added_action = FALSE + /// If TRUE neutered borers wont be able to get an action button from this, but will still be able to progress through the evolution tree + var/restricted_for_neutered = FALSE + /// What happens when a borer gets this evolution /datum/borer_evolution/proc/on_evolve(mob/living/basic/cortical_borer/cortical_owner) SHOULD_CALL_PARENT(TRUE) @@ -24,6 +29,14 @@ if(gain_text) to_chat(cortical_owner, span_notice("[gain_text]")) + if(restricted_for_neutered) + if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) + to_chat(cortical_owner, span_danger("You didnt manage to properly evolve, you feel a strange sensation.")) + return + if(added_action) + var/datum/action/cooldown/borer/new_action = new added_action(cortical_owner) + new_action.Grant(cortical_owner) + /datum/borer_evolution/base name = "The Beginning" desc = "The start of a great age." diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm index 01eb0ea2a9b4..e5347cedf9e6 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_diveworm.dm @@ -103,10 +103,5 @@ /datum/borer_evolution/synthetic_borer, /datum/borer_evolution/synthetic_chems_negative, ) - -/datum/borer_evolution/diveworm/empowered_offspring/on_evolve(mob/living/basic/cortical_borer/cortical_owner) - . = ..() - if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) - return - var/datum/action/cooldown/borer/empowered_offspring/attack_action = new(cortical_owner) - attack_action.Grant(cortical_owner) + added_action = /datum/action/cooldown/borer/empowered_offspring + restricted_for_neutered = TRUE diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm index 65cfc05e3c1a..c4b729eaf6a7 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_hivelord.dm @@ -9,13 +9,8 @@ tier = 1 evo_cost = 1 unlocked_evolutions = list(/datum/borer_evolution/hivelord/blood_chemical) - -/datum/borer_evolution/hivelord/produce_offspring/on_evolve(mob/living/basic/cortical_borer/cortical_owner) - . = ..() - if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) - return - var/datum/action/cooldown/borer/produce_offspring/attack_action = new(cortical_owner) - attack_action.Grant(cortical_owner) + added_action = /datum/action/cooldown/borer/produce_offspring + restricted_for_neutered = TRUE // T2 /datum/borer_evolution/hivelord/blood_chemical @@ -24,11 +19,7 @@ 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/basic/cortical_borer/cortical_owner) - . = ..() - var/datum/action/cooldown/borer/learn_bloodchemical/attack_action = new(cortical_owner) - attack_action.Grant(cortical_owner) + added_action = /datum/action/cooldown/borer/learn_bloodchemical // T3 /datum/borer_evolution/hivelord/movespeed @@ -50,11 +41,7 @@ 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/basic/cortical_borer/cortical_owner) - . = ..() - var/datum/action/cooldown/borer/stealth_mode/attack_action = new(cortical_owner) - attack_action.Grant(cortical_owner) + added_action = /datum/action/cooldown/borer/stealth_mode // T5 /datum/borer_evolution/hivelord/produce_offspring_alone @@ -69,9 +56,8 @@ /datum/borer_evolution/synthetic_chems_positive, /datum/borer_evolution/synthetic_chems_negative, ) + restricted_for_neutered = TRUE // we set this to TRUE purelly for the message, they dont have the reproduction action anyway /datum/borer_evolution/hivelord/produce_offspring_alone/on_evolve(mob/living/basic/cortical_borer/cortical_owner) . = ..() - if(istype(cortical_owner, /mob/living/basic/cortical_borer/neutered)) - return cortical_owner.upgrade_flags |= BORER_ALONE_PRODUCTION diff --git a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm index 2ff58a125cd4..a5807b8d0060 100644 --- a/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm +++ b/monkestation/code/modules/antagonists/borers/code/evolution/evolution_symbiote.dm @@ -9,11 +9,7 @@ tier = 1 unlocked_evolutions = list(/datum/borer_evolution/symbiote/chem_per_level) evo_cost = 1 - -/datum/borer_evolution/symbiote/willing_host/on_evolve(mob/living/basic/cortical_borer/cortical_owner) - . = ..() - var/datum/action/cooldown/borer/willing_host/attack_action = new(cortical_owner) - attack_action.Grant(cortical_owner) + added_action = /datum/action/cooldown/borer/willing_host // T2 /datum/borer_evolution/symbiote/chem_per_level @@ -104,8 +100,4 @@ /datum/borer_evolution/synthetic_borer, /datum/borer_evolution/synthetic_chems_positive, ) - -/datum/borer_evolution/symbiote/revive_host/on_evolve(mob/living/basic/cortical_borer/cortical_owner) - . = ..() - var/datum/action/cooldown/borer/revive_host/attack_action = new(cortical_owner) - attack_action.Grant(cortical_owner) + added_action = /datum/action/cooldown/borer/revive_host diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index a4132e9517cd..8e018016d1fd 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -59,7 +59,7 @@ var/mob/dead/observer/picked_candidate = pick(candidates) - var/mob/living/basic/cortical_borer/neutered/new_mob = new(get_turf(src)) + var/mob/living/basic/cortical_borer/neutered/new_mob = new(drop_location()) picked_candidate.mind.transfer_to(new_mob, TRUE) var/datum/antagonist/cortical_borer/borer_antagonist_datum = new diff --git a/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm b/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm index a49f67b4235d..b1711f8efded 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/imprisonment_cage.dm @@ -90,7 +90,7 @@ /obj/item/cortical_cage/container_resist_act(mob/living/user) user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT + COOLDOWN_START(user, last_special, CLICK_CD_BREAKOUT) to_chat(user, span_notice("You begin squeezing through the bars in an attempt to escape! (This will take time.)")) to_chat(loc, span_warning("You see [user] begin trying to squeeze through the bars!")) if(!do_after(user, rand(30 SECONDS, 40 SECONDS), target = user) || opened || !(user in contents)) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index f0bf2580247a..975a43253ee6 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -36,7 +36,7 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a if(iscorticalborer(movable_atom) && density) if(!do_after(movable_atom, 5 SECONDS, src)) return ..() - movable_atom.forceMove(get_turf(src)) + movable_atom.forceMove(drop_location()) to_chat(movable_atom, span_notice("You squeeze through [src].")) return return ..() From 305291a5fe5d1cbf56a3b3e955383590c6b4e19e Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Thu, 22 Feb 2024 21:13:41 +0100 Subject: [PATCH 55/67] no more infinitelly trapped borers in dead people --- .../antagonists/borers/code/abilities/_ability.dm | 4 ++-- .../antagonists/borers/code/abilities/enter_host.dm | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm index 9a8583ba24fc..51b011956cf6 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/_ability.dm @@ -45,10 +45,10 @@ if(requires_host == TRUE && !cortical_owner.inside_human()) owner.balloon_alert(owner, "host required") return FALSE - if(needs_living_host == TRUE && owner.stat == DEAD) + if(needs_living_host == TRUE && cortical_owner.human_host.stat == DEAD) owner.balloon_alert(owner, "Alive host required") return FALSE - if(needs_dead_host == TRUE && !owner.stat == DEAD) + if(needs_dead_host == TRUE && cortical_owner.human_host.stat != DEAD) owner.balloon_alert(owner, "Dead host required") return FALSE if(sugar_restricted == TRUE && cortical_owner.host_sugar()) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index acf20e64e1d9..5090d31686c3 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -19,11 +19,17 @@ return FALSE var/mob/living/basic/cortical_borer/cortical_owner = owner - //having a host means we need to leave them then + //having a host means we need to leave them if(cortical_owner.human_host) if(cortical_owner.host_sugar()) - owner.balloon_alert(owner, "cannot function with sugar in host") - return + if(cortical_owner.human_host.stat != DEAD) + owner.balloon_alert(owner, "cannot function with sugar in host") + return + // we have a host with sugar and our host is dead. Amazing fuckup + owner.balloon_alert(owner, "Struggling to leave") + to_chat(cortical_owner, span_userdanger("We struggle to leave our host, barelly able to due to the sugar in their blood no longer moving, this will take time...")) + StartCooldown(30 SECONDS) // stay in place now + sleep(30 SECONDS) owner.balloon_alert(owner, "detached from host") if(!(cortical_owner.upgrade_flags & BORER_STEALTH_MODE)) From 0a3f2c1e0688bb4acd2eb2048714ab69eba9e54c Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Mon, 26 Feb 2024 07:27:52 +0100 Subject: [PATCH 56/67] Create screenshot_antag_icons_borer.png --- .../screenshots/screenshot_antag_icons_borer.png | Bin 0 -> 357 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/modules/unit_tests/screenshots/screenshot_antag_icons_borer.png diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_borer.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_borer.png new file mode 100644 index 0000000000000000000000000000000000000000..35899cffa63171ae80c02eaf6221a3c26c8f4010 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoSydqsB`&GO$wiq3C7Jno3=9=> zg2M`mO22;zF8KKMiI%sn*10q1gExd4Tr__0Nawtd=E;B!p&LvdKRV-a*5|xNV?md< zkav)1j_8yrJ1l~Yy1Rf(o}Ct#yM&5^6?0Nq!|lac#pC_;80MXnkoPHJ@BrGn&C|s( zq+-t7tA>1zjsgq;Q@B(ESC{U;WZf{ofUC1wFkVqBYx{&3E~^7pt6UaP+9-W*b(vAL zkI~GTQM^Fy_&|evh=1$>>tmDeef#&WWcKtK*7Mh`mC%3I{&4%NUoOg}jQ{_jMKS;k3NZEIeTbo65AiTwU4AHEuoKynp?zHT}CKo^P4t a Date: Tue, 19 Mar 2024 22:43:58 +0100 Subject: [PATCH 57/67] le updates to polling --- code/__DEFINES/role_preferences.dm | 1 + .../__DEFINES/~monkestation/role_preferences.dm | 1 - code/modules/admin/sql_ban_system.dm | 2 +- .../client/preferences/middleware/antags.dm | 1 + .../code/antagonist_stuff/antagonist_datum.dm | 2 +- .../code/antagonist_stuff/midround_event.dm | 11 ++++++++--- .../borers/code/items/borer_spawner.dm | 12 ++++++++---- .../antagonists/borers/code/items/egg.dm | 2 +- .../borers/code/items/empowered_egg.dm | 8 +++++++- tgstation.dme | 1 - .../antagonists/antagonists/corticalborer.ts | 17 +++++++++++++++++ 11 files changed, 45 insertions(+), 13 deletions(-) delete mode 100644 code/__DEFINES/~monkestation/role_preferences.dm create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/corticalborer.ts diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 446660495299..56480c1a9432 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -40,6 +40,7 @@ #define ROLE_SPIDER "Spider" #define ROLE_WIZARD_MIDROUND "Wizard (Midround)" // monke midrounds +#define ROLE_CORTICAL_BORER "Cortical Borer" #define ROLE_DRIFTING_CONTRACTOR "Drifting Contractor" #define ROLE_FLORIDA_MAN "Florida Man" #define ROLE_SLASHER "Slasher" diff --git a/code/__DEFINES/~monkestation/role_preferences.dm b/code/__DEFINES/~monkestation/role_preferences.dm deleted file mode 100644 index d2a7dd7dec21..000000000000 --- a/code/__DEFINES/~monkestation/role_preferences.dm +++ /dev/null @@ -1 +0,0 @@ -#define ROLE_BORER "Borer" diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 3c7e8b8e1e8d..9dc31be8498f 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -348,7 +348,7 @@ ROLE_BROTHER, ROLE_BLOODSUCKER, ROLE_BLOODSUCKERBREAKOUT, - ROLE_BORER, // MONKESTATION ADDITION -- CORTICAL_BORERS + ROLE_CORTICAL_BORER, // MONKESTATION ADDITION -- CORTICAL_BORERS ROLE_CHANGELING, ROLE_CLOCK_CULTIST, ROLE_CULTIST, diff --git a/code/modules/client/preferences/middleware/antags.dm b/code/modules/client/preferences/middleware/antags.dm index 4e5d66e3b97d..5239fa9a9953 100644 --- a/code/modules/client/preferences/middleware/antags.dm +++ b/code/modules/client/preferences/middleware/antags.dm @@ -120,6 +120,7 @@ ROLE_LONE_OPERATIVE = /datum/antagonist/nukeop/lone, ROLE_SENTIENCE = /datum/antagonist/sentient_creature, //monkestation antags + ROLE_CORTICAL_BORER = /datum/antagonist/cortical_borer, ROLE_DRIFTING_CONTRACTOR = /datum/antagonist/traitor/contractor, ROLE_SLASHER = /datum/antagonist/slasher, ROLE_FLORIDA_MAN = /datum/antagonist/florida_man diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm index fbd48166dcd1..12c73ac0f708 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm @@ -1,6 +1,6 @@ /datum/antagonist/cortical_borer name = "Cortical Borer" - job_rank = ROLE_BORER + job_rank = ROLE_CORTICAL_BORER roundend_category = "enslaved cortical borers" // may look a bit confusing, but these borers are not a part of a hivemind. So they are probably enslaved antagpanel_category = "Cortical Borers" ui_name = "AntagInfoBorer" diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index 1120dfa0e1f9..2e259ea0eecd 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -5,7 +5,7 @@ name = "Cortical Borer Infestation" tags = list(TAG_TEAM_ANTAG, TAG_EXTERNAL, TAG_ALIEN) typepath = /datum/round_event/ghost_role/cortical_borer - antag_flag = ROLE_BORER + antag_flag = ROLE_CORTICAL_BORER track = EVENT_TRACK_MAJOR enemy_roles = list( JOB_CAPTAIN, @@ -53,7 +53,12 @@ message_admins("An event attempted to spawn a borer but no suitable vents were found. Shutting down.") return MAP_ERROR - var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER) + var/list/candidates = SSpolling.poll_ghost_candidates( + role = ROLE_CORTICAL_BORER, + check_jobban = ROLE_CORTICAL_BORER, + ignore_category = POLL_IGNORE_CORTICAL_BORER, + pic_source = /mob/living/basic/cortical_borer, + ) if(!length(candidates)) return NOT_ENOUGH_PLAYERS @@ -77,7 +82,7 @@ name = "Cortical Borer Infestation" antag_datum = /datum/antagonist/cortical_borer midround_ruleset_style = MIDROUND_RULESET_STYLE_HEAVY - antag_flag = ROLE_BORER + antag_flag = ROLE_CORTICAL_BORER enemy_roles = list( JOB_CAPTAIN, JOB_DETECTIVE, diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 8e018016d1fd..3b06a0194899 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -28,6 +28,8 @@ return sleep(polling_time * 0.2) visible_message(span_notice("The borer seems to have woken up")) + if(!opened) // one more check to be sure + return sleep(polling_time * 0.2) visible_message(span_notice("The borer has perked up their head, finally noticing the opened cage...")) sleep(polling_time * 0.2) @@ -45,10 +47,12 @@ sleep(delayed) INVOKE_ASYNC(src, PROC_REF(do_wriggler_messages)) // give them something to look at whilst we poll the ghosts update_appearance() - var/list/mob/dead/observer/candidates = poll_ghost_candidates( - "Do you want to play as a neutered cortical borer?", - ROLE_BORER, - poll_time = polling_time + var/list/candidates = SSpolling.poll_ghost_candidates( + role = ROLE_CORTICAL_BORER, + check_jobban = ROLE_CORTICAL_BORER, + poll_time = polling_time, + ignore_category = POLL_IGNORE_CORTICAL_BORER, + pic_source = /mob/living/basic/cortical_borer/neutered, ) if(!LAZYLEN(candidates)) opened = FALSE diff --git a/monkestation/code/modules/antagonists/borers/code/items/egg.dm b/monkestation/code/modules/antagonists/borers/code/items/egg.dm index 0fdb29aa578b..d7b3d5417adc 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/egg.dm @@ -17,7 +17,7 @@ mob_name = "cortical borer" ///Type of mob that will be spawned mob_type = /mob/living/basic/cortical_borer - role_ban = ROLE_BORER + role_ban = ROLE_CORTICAL_BORER show_flavor = TRUE prompt_name = "cortical borer" you_are_text = "You are a Cortical Borer." diff --git a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm index bf90f9f5df89..a5a865083356 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm @@ -43,7 +43,13 @@ if(QDELETED(owner) || owner.stat != DEAD) qdel(src) return - var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to spawn as a cortical borer?", ROLE_PAI, FALSE, 10 SECONDS, POLL_IGNORE_CORTICAL_BORER) + var/list/candidates = SSpolling.poll_ghost_candidates( + role = ROLE_CORTICAL_BORER, + check_jobban = ROLE_CORTICAL_BORER, + poll_time = 10 SECONDS, + ignore_category = POLL_IGNORE_CORTICAL_BORER, + pic_source = /mob/living/basic/cortical_borer/empowered, + ) if(!length(candidates)) var/obj/effect/mob_spawn/ghost_role/borer_egg/empowered/borer_egg = new(owner.drop_location()) borer_egg.generation = generation diff --git a/tgstation.dme b/tgstation.dme index f9a5e2849de6..925d77a72b5d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -412,7 +412,6 @@ #include "code\__DEFINES\~monkestation\power.dm" #include "code\__DEFINES\~monkestation\projectiles.dm" #include "code\__DEFINES\~monkestation\robots.dm" -#include "code\__DEFINES\~monkestation\role_preferences.dm" #include "code\__DEFINES\~monkestation\smoothing.dm" #include "code\__DEFINES\~monkestation\span.dm" #include "code\__DEFINES\~monkestation\status_effects.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/corticalborer.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/corticalborer.ts new file mode 100644 index 000000000000..4b87325a3990 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/corticalborer.ts @@ -0,0 +1,17 @@ +import { Antagonist, Category } from '../base'; +import { multiline } from 'common/string'; + +const CorticalBorer: Antagonist = { + key: 'corticalborer', + name: 'Cortical Borer', + description: [ + multiline` + You are a slug that crawls into peoples ears and + then manipulates them in various ways + to make sure your species survives and thrives + `, + ], + category: Category.Midround, +}; + +export default CorticalBorer; From 590c1ea20830ddc1a5bee1651d460b38c691f681 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:53:16 +0100 Subject: [PATCH 58/67] opendream lints got mad --- .../antagonists/borers/code/abilities/learn_chemicals.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm index 3d2be9a73b12..74fcc3380f84 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/learn_chemicals.dm @@ -59,7 +59,7 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) cortical_owner.chemical_evolution -= chemical_evo_points cortical_owner.potential_chemicals -= learned_reagent - owner.balloon_alert(owner, "[initial(reagent_choice)] learned") + owner.balloon_alert(owner, "[reagent_choice] learned") if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(learned_reagent.taste_description)]!")) @@ -122,7 +122,7 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) owner.balloon_alert(owner, "chemical blacklisted") return if(!(learned_reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) - owner.balloon_alert(owner, "cannot learn [initial(reagent_choice)]") + owner.balloon_alert(owner, "cannot learn [reagent_choice]") return cortical_owner.chemical_evolution -= chemical_evo_points @@ -136,7 +136,7 @@ GLOBAL_VAR_INIT(objective_blood_borer, 3) if(cortical_owner.blood_chems_learned == BLOOD_CHEM_OBJECTIVE) GLOB.successful_blood_chem += 1 - owner.balloon_alert(owner, "[initial(reagent_choice)] learned") + owner.balloon_alert(owner, "[reagent_choice] learned") if(!HAS_TRAIT(cortical_owner.human_host, TRAIT_AGEUSIA)) to_chat(cortical_owner.human_host, span_notice("You get a strange aftertaste of [initial(learned_reagent.taste_description)]!")) From 702463d689f241b441f2b9865383eec5d3bb903d Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:50:59 +0100 Subject: [PATCH 59/67] screenshot tests --- ...png => screenshot_antag_icons_corticalborer.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename code/modules/unit_tests/screenshots/{screenshot_antag_icons_borer.png => screenshot_antag_icons_corticalborer.png} (100%) diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_borer.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_corticalborer.png similarity index 100% rename from code/modules/unit_tests/screenshots/screenshot_antag_icons_borer.png rename to code/modules/unit_tests/screenshots/screenshot_antag_icons_corticalborer.png From b6889d43f56cb06c4f4e0c2710caf8e2058726e7 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Wed, 20 Mar 2024 01:05:41 +0100 Subject: [PATCH 60/67] in this part, absolucy fixes everything by changing 1 line of code --- code/__DEFINES/role_preferences.dm | 2 +- .../antagonists/borers/code/antagonist_stuff/midround_event.dm | 1 - .../modules/antagonists/borers/code/items/borer_spawner.dm | 3 +-- .../modules/antagonists/borers/code/items/empowered_egg.dm | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 56480c1a9432..d84038f139f3 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -153,7 +153,7 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_SPIDER = 0, ROLE_WIZARD_MIDROUND = 14, //monkestation edit start - ROLE_BORER = 0, // Module ID: CORTICAL_BORERS + ROLE_CORTICAL_BORER = 0, // Module ID: CORTICAL_BORERS ROLE_DRIFTING_CONTRACTOR = 0, ROLE_VAMPIRICACCIDENT = 0, ROLE_MONSTERHUNTER = 0, diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm index 2e259ea0eecd..a31808ed8eee 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/midround_event.dm @@ -55,7 +55,6 @@ var/list/candidates = SSpolling.poll_ghost_candidates( role = ROLE_CORTICAL_BORER, - check_jobban = ROLE_CORTICAL_BORER, ignore_category = POLL_IGNORE_CORTICAL_BORER, pic_source = /mob/living/basic/cortical_borer, ) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index 3b06a0194899..d3d24021093e 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -7,7 +7,7 @@ /// Used to animate the cage opening when you use the borer spawner, and closing if it fails to spawn a borer. Also midly against spam var/opened = FALSE /// Toggles if the borer spawner should be delayed or not, if this gets a value if will use that value to delay (for example: 5 SECONDS) - var/delayed = FALSE + var/delayed = 2 SECONDS /// Dictates the poll time var/polling_time = 10 SECONDS @@ -49,7 +49,6 @@ update_appearance() var/list/candidates = SSpolling.poll_ghost_candidates( role = ROLE_CORTICAL_BORER, - check_jobban = ROLE_CORTICAL_BORER, poll_time = polling_time, ignore_category = POLL_IGNORE_CORTICAL_BORER, pic_source = /mob/living/basic/cortical_borer/neutered, diff --git a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm index a5a865083356..8483c2e0ecd6 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/empowered_egg.dm @@ -45,7 +45,6 @@ return var/list/candidates = SSpolling.poll_ghost_candidates( role = ROLE_CORTICAL_BORER, - check_jobban = ROLE_CORTICAL_BORER, poll_time = 10 SECONDS, ignore_category = POLL_IGNORE_CORTICAL_BORER, pic_source = /mob/living/basic/cortical_borer/empowered, From d84ac69cc11f147dccc8334dcd3d1135e46a91bf Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 29 Mar 2024 02:20:12 +0100 Subject: [PATCH 61/67] some minor stuff --- .../borers/code/abilities/enter_host.dm | 3 +++ .../borers/code/mobs/cortical_borer.dm | 15 +++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index 5090d31686c3..248f7a4842e5 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -112,10 +112,13 @@ cortical_owner.forceMove(cortical_owner.human_host) 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 borer_organ.Insert(cortical_owner.human_host) + var/turf/human_turftwo = get_turf(cortical_owner.human_host) var/logging_text = "[key_name(cortical_owner)] went into [key_name(cortical_owner.human_host)] at [loc_name(human_turftwo)]" cortical_owner.log_message(logging_text, LOG_GAME) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 975a43253ee6..7dad57c11a56 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -488,14 +488,21 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a timed_maturity = world.time + 1 SECONDS maturity_age++ + /** + * The point values are double what they seem + * So in the beginning you start out with the following generation: + * Evolution point per 1 minute and 20 seconds + * Chemical point per 40 seconds + */ + //20:40, 15:30, 10:20, 5:10 - var/maturity_threshold = 20 + var/maturity_threshold = 2 SECONDS if(GLOB.successful_egg_number >= GLOB.objective_egg_borer_number) - maturity_threshold -= 2 + maturity_threshold -= 0.2 SECONDS if(length(GLOB.willing_hosts) >= GLOB.objective_willing_hosts) - maturity_threshold -= 10 + maturity_threshold -= 1 SECOND if(GLOB.successful_blood_chem >= GLOB.objective_blood_borer) - maturity_threshold -= 3 + maturity_threshold -= 0.3 SECONDS if(maturity_age == maturity_threshold) if(chemical_evolution < limited_borer) //you can only have a default of 10 at a time From 4f61d38b1755e05e6ea1163a01b778bd9e8efc84 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 29 Mar 2024 02:26:22 +0100 Subject: [PATCH 62/67] yoinks https://github.com/Skyrat-SS13/Skyrat-tg/pull/26693 --- .../modules/antagonists/borers/code/abilities/enter_host.dm | 3 +++ .../modules/antagonists/borers/code/mobs/cortical_borer.dm | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm index 248f7a4842e5..2b96a3be3da8 100644 --- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm +++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm @@ -47,6 +47,7 @@ cortical_owner.forceMove(human_turfone) cortical_owner.human_host = null + REMOVE_TRAIT(cortical_owner, TRAIT_WEATHER_IMMUNE, "borer_in_host") StartCooldown() return @@ -123,6 +124,8 @@ var/logging_text = "[key_name(cortical_owner)] went into [key_name(cortical_owner.human_host)] at [loc_name(human_turftwo)]" cortical_owner.log_message(logging_text, LOG_GAME) cortical_owner.human_host.log_message(logging_text, LOG_GAME) + + ADD_TRAIT(cortical_owner, TRAIT_WEATHER_IMMUNE, "borer_in_host") StartCooldown() /// Checks if the target's head is bio protected, returns true if this is the case diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index 7dad57c11a56..feeb9ca748f0 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -288,7 +288,8 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a deathgasp_once = TRUE for(var/borers in GLOB.cortical_borers) to_chat(borers, span_boldwarning("[src] has left the hivemind forcibly!")) - QDEL_NULL(reagent_holder) + if(gibbed) + QDEL_NULL(reagent_holder) return ..() //so we can add some stuff to status, making it easier to read... maybe some hud some day From a62890d7eb0e24fc78b7e297dde7b65427def2ca Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 29 Mar 2024 18:34:59 +0100 Subject: [PATCH 63/67] fixes --- .../modules/antagonists/borers/code/items/borer_spawner.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm index d3d24021093e..808ff189bd0c 100644 --- a/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm +++ b/monkestation/code/modules/antagonists/borers/code/items/borer_spawner.dm @@ -7,7 +7,7 @@ /// Used to animate the cage opening when you use the borer spawner, and closing if it fails to spawn a borer. Also midly against spam var/opened = FALSE /// Toggles if the borer spawner should be delayed or not, if this gets a value if will use that value to delay (for example: 5 SECONDS) - var/delayed = 2 SECONDS + var/delayed = FALSE /// Dictates the poll time var/polling_time = 10 SECONDS @@ -63,7 +63,7 @@ var/mob/dead/observer/picked_candidate = pick(candidates) var/mob/living/basic/cortical_borer/neutered/new_mob = new(drop_location()) - picked_candidate.mind.transfer_to(new_mob, TRUE) + new_mob.ckey = picked_candidate.ckey var/datum/antagonist/cortical_borer/borer_antagonist_datum = new From 752d46b9cfcd68e73dc5c6bd9aea5d7497f5c6da Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sat, 30 Mar 2024 18:19:20 +0100 Subject: [PATCH 64/67] long --- .../code/modules/ghost_players/job_helpers/organ_printer.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkestation/code/modules/ghost_players/job_helpers/organ_printer.dm b/monkestation/code/modules/ghost_players/job_helpers/organ_printer.dm index 4fa2b21fc917..04f1363e1e38 100644 --- a/monkestation/code/modules/ghost_players/job_helpers/organ_printer.dm +++ b/monkestation/code/modules/ghost_players/job_helpers/organ_printer.dm @@ -13,7 +13,7 @@ /obj/structure/organ_creator/attack_hand(mob/living/user, list/modifiers) . = ..() - var/list/all_internals = subtypesof(/obj/item/organ/internal) - typesof(/obj/item/organ/internal/zombie_infection) - typesof(/obj/item/organ/internal/alien) - typesof(/obj/item/organ/internal/body_egg) - typesof(/obj/item/organ/internal/heart/gland) - /obj/item/organ/internal/butt/atomic - typesof(/obj/item/organ/internal/alien) + var/list/all_internals = subtypesof(/obj/item/organ/internal) - typesof(/obj/item/organ/internal/zombie_infection) - typesof(/obj/item/organ/internal/alien) - typesof(/obj/item/organ/internal/body_egg) - typesof(/obj/item/organ/internal/heart/gland) - /obj/item/organ/internal/butt/atomic - typesof(/obj/item/organ/internal/alien) - /obj/item/organ/internal/borer_body - /obj/item/organ/internal/empowered_borer_egg // bit long aint it var/list/all_externals = subtypesof(/obj/item/organ/external) var/list/all_bodyparts = subtypesof(/obj/item/bodypart) From 49a96df4ec3e8aae4c43d3ccc2d934da8c0994e4 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Sun, 31 Mar 2024 03:06:24 +0200 Subject: [PATCH 65/67] co-existance --- .../antagonists/borers/code/antagonist_stuff/antagonist_datum.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm index 12c73ac0f708..06df30a9ef2c 100644 --- a/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm +++ b/monkestation/code/modules/antagonists/borers/code/antagonist_stuff/antagonist_datum.dm @@ -4,6 +4,7 @@ roundend_category = "enslaved cortical borers" // may look a bit confusing, but these borers are not a part of a hivemind. So they are probably enslaved antagpanel_category = "Cortical Borers" ui_name = "AntagInfoBorer" + count_against_dynamic_roll_chance = FALSE // there are thousands of them, we do not need them to be the only antagonist prevent_roundtype_conversion = FALSE show_to_ghosts = TRUE /// Our linked borer, used for the antagonist panel TGUI From 359bd7d18c72237db5b6105a373d4f07d9c67407 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Tue, 2 Apr 2024 23:15:27 +0200 Subject: [PATCH 66/67] god i hate AI's breaking everything --- .../modules/antagonists/borers/code/mobs/cortical_borer.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index feeb9ca748f0..c4a9d8443d4d 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -239,6 +239,9 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a /// Skips unique borer status tab text, used for unique borer subtypes with their own status tabs var/skip_status_tab = FALSE +/mob/living/basic/cortical_borer/can_track(mob/living/user) + return FALSE // The validhunt box machines are onto us, we cannot let them track us + /mob/living/basic/cortical_borer/Initialize(mapload) . = ..() AddComponent( \ From 060fa6ff2d74e610646f660193011586e770fe35 Mon Sep 17 00:00:00 2001 From: Gboster-0 <82319946+Gboster-0@users.noreply.github.com> Date: Fri, 5 Apr 2024 02:37:44 +0200 Subject: [PATCH 67/67] doubles point gain --- .../modules/antagonists/borers/code/mobs/cortical_borer.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm index c4a9d8443d4d..b0e7953cbedc 100644 --- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm +++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm @@ -489,14 +489,14 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a . = TRUE if(upgrade_flags & BORER_STEALTH_MODE) return FALSE - timed_maturity = world.time + 1 SECONDS + timed_maturity = world.time + 0.5 SECONDS maturity_age++ /** * The point values are double what they seem * So in the beginning you start out with the following generation: - * Evolution point per 1 minute and 20 seconds - * Chemical point per 40 seconds + * Evolution point per 40 seconds + * Chemical point per 20 seconds */ //20:40, 15:30, 10:20, 5:10