From a7b4328d406d112fbcb97df3d5ae250b8cfe879b Mon Sep 17 00:00:00 2001
From: SabreML <57483089+SabreML@users.noreply.github.com>
Date: Mon, 22 Jan 2024 15:05:19 +0000
Subject: [PATCH 01/17] Initial Framework
oh boy here we go
---
code/__HELPERS/logging.dm | 6 +-
code/_globalvars/global_lists.dm | 4 +-
code/game/world.dm | 4 +-
code/modules/logging/global_logs.dm | 4 +-
.../carbon/xenomorph/XenoMutatorSets.dm | 264 ------------------
.../mob/living/carbon/xenomorph/Xenomorph.dm | 33 +--
.../carbon/xenomorph/mutators/mutator.dm | 103 -------
.../behavior_delegate.dm | 0
.../castes}/boiler/trapper.dm | 0
.../castes}/carrier/eggsac.dm | 0
.../castes}/crusher/charger.dm | 0
.../castes}/defender/steel_crest.dm | 0
.../castes}/drone/gardener.dm | 0
.../castes}/drone/healer.dm | 0
.../castes}/hivelord/resin_whisperer.dm | 0
.../castes}/lurker/vampire.dm | 0
.../castes}/praetorian/dancer.dm | 0
.../castes}/praetorian/oppressor.dm | 0
.../castes}/praetorian/vanguard.dm | 0
.../castes}/praetorian/warden.dm | 0
.../castes}/ravager/berserker.dm | 0
.../castes}/ravager/hedgehog.dm | 0
.../strains => strains/castes}/runner/acid.dm | 0
.../carbon/xenomorph/strains/xeno_strain.dm | 116 ++++++++
.../living/carbon/xenomorph/update_icons.dm | 4 +-
colonialmarines.dme | 35 ++-
26 files changed, 157 insertions(+), 416 deletions(-)
delete mode 100644 code/modules/mob/living/carbon/xenomorph/XenoMutatorSets.dm
delete mode 100644 code/modules/mob/living/carbon/xenomorph/mutators/mutator.dm
rename code/modules/mob/living/carbon/xenomorph/{mutators => strains}/behavior_delegate.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/boiler/trapper.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/carrier/eggsac.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/crusher/charger.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/defender/steel_crest.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/drone/gardener.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/drone/healer.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/hivelord/resin_whisperer.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/lurker/vampire.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/praetorian/dancer.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/praetorian/oppressor.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/praetorian/vanguard.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/praetorian/warden.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/ravager/berserker.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/ravager/hedgehog.dm (100%)
rename code/modules/mob/living/carbon/xenomorph/{mutators/strains => strains/castes}/runner/acid.dm (100%)
create mode 100644 code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm
diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm
index c20db3da303f..d6c18c8a93be 100644
--- a/code/__HELPERS/logging.dm
+++ b/code/__HELPERS/logging.dm
@@ -209,10 +209,10 @@ GLOBAL_VAR_INIT(log_end, world.system_type == UNIX ? ascii2text(13) : "")
WRITE_LOG(GLOB.world_game_log, "MISC: [text]")
GLOB.STUI?.debug.Add("\[[time]]MISC: [text]")
-/proc/log_mutator(text)
- if(!GLOB.mutator_logs)
+/proc/log_strain(text)
+ if(!GLOB.strain_logs)
return
- WRITE_LOG(GLOB.mutator_logs, "[text]")
+ WRITE_LOG(GLOB.strain_logs, "[text]")
/proc/log_hiveorder(text)
var/time = time_stamp()
diff --git a/code/_globalvars/global_lists.dm b/code/_globalvars/global_lists.dm
index 66eaf13df282..00a3bc256e6a 100644
--- a/code/_globalvars/global_lists.dm
+++ b/code/_globalvars/global_lists.dm
@@ -163,8 +163,8 @@ GLOBAL_LIST_INIT(language_keys, setup_language_keys()) //table of say codes for
GLOBAL_REFERENCE_LIST_INDEXED(origins, /datum/origin, name)
GLOBAL_LIST_INIT(player_origins, USCM_ORIGINS)
-//Xeno mutators
-GLOBAL_REFERENCE_LIST_INDEXED_SORTED(xeno_mutator_list, /datum/xeno_mutator, name)
+//Xeno strains
+GLOBAL_SUBTYPE_PATHS_LIST_INDEXED(xeno_strain_list, /datum/xeno_strain, name)
//Xeno hives
GLOBAL_LIST_INIT_TYPED(hive_datum, /datum/hive_status, list(
diff --git a/code/game/world.dm b/code/game/world.dm
index f68263412715..8a93f89a43f6 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -129,7 +129,7 @@ GLOBAL_LIST_INIT(reboot_sfx, file2list("config/reboot_sfx.txt"))
GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log"
GLOB.round_stats = "[GLOB.log_directory]/round_stats.log"
GLOB.scheduler_stats = "[GLOB.log_directory]/round_scheduler_stats.log"
- GLOB.mutator_logs = "[GLOB.log_directory]/mutator_logs.log"
+ GLOB.strain_logs = "[GLOB.log_directory]/strain_logs.log"
start_log(GLOB.tgui_log)
start_log(GLOB.world_href_log)
@@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(reboot_sfx, file2list("config/reboot_sfx.txt"))
start_log(GLOB.world_runtime_log)
start_log(GLOB.round_stats)
start_log(GLOB.scheduler_stats)
- start_log(GLOB.mutator_logs)
+ start_log(GLOB.strain_logs)
if(fexists(GLOB.config_error_log))
fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log")
diff --git a/code/modules/logging/global_logs.dm b/code/modules/logging/global_logs.dm
index ff384fe537c0..e0055907d67a 100644
--- a/code/modules/logging/global_logs.dm
+++ b/code/modules/logging/global_logs.dm
@@ -25,8 +25,8 @@ GLOBAL_PROTECT(world_runtime_log)
GLOBAL_VAR(scheduler_stats)
GLOBAL_PROTECT(scheduler_stats)
-GLOBAL_VAR(mutator_logs)
-GLOBAL_PROTECT(mutator_logs)
+GLOBAL_VAR(strain_logs)
+GLOBAL_PROTECT(strain_logs)
GLOBAL_VAR(round_stats)
GLOBAL_PROTECT(round_stats)
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoMutatorSets.dm b/code/modules/mob/living/carbon/xenomorph/XenoMutatorSets.dm
deleted file mode 100644
index fc5532955ff9..000000000000
--- a/code/modules/mob/living/carbon/xenomorph/XenoMutatorSets.dm
+++ /dev/null
@@ -1,264 +0,0 @@
-#define MUTATOR_GAIN_PER_QUEEN_LEVEL 6
-#define MUTATOR_GAIN_PER_XENO_LEVEL 3
-
-//A class that holds mutators for a given Xeno hive
-//Each time a Queen matures, the hive gets more points
-//Each time a Queen dies, the mutators are reset
-
-//The class contains a lot of variables that are applied to various xenos' stats and actions
-/datum/mutator_set
- var/remaining_points = 1 //How many points the xeno / hive still has to spend on mutators
- var/list/purchased_mutators = list() //List of purchased mutators
- var/user_level = 0 //Level of the Queen for Hive or the individual xeno. Starting at -1 so at tier 0 you'd get some mutators to play with
-
- var/tackle_strength_bonus = 0
-
-//Functions to be overloaded to call for when something gets updated on the xenos
-/datum/mutator_set/proc/recalculate_everything(description)
-/datum/mutator_set/proc/recalculate_stats(description)
-/datum/mutator_set/proc/recalculate_actions(description)
-/datum/mutator_set/proc/recalculate_pheromones(description)
-/datum/mutator_set/proc/give_feedback(description)
-
-
-/datum/mutator_set/proc/purchase_mutator(name)
- return FALSE
-
-/datum/mutator_set/proc/list_and_purchase_mutators()
- var/list/mutators_for_purchase = available_mutators()
- var/mob/living/carbon/xenomorph/Xeno = usr
- if(mutators_for_purchase.len == 0)
- to_chat(usr, "There are no available strains.")
- var/pick = tgui_input_list(usr, "Which strain would you like to purchase?", "Purchase strain", mutators_for_purchase, theme="hive_status")
- if(!pick)
- return FALSE
- if(alert(usr, "[GLOB.xeno_mutator_list[pick].description]\n\nConfirm mutation?", "Strain purchase", "Yes", "No") != "Yes") return
- if(!Xeno.strain_checks())
- return
- if(GLOB.xeno_mutator_list[pick].apply_mutator(src))
- to_chat(usr, "Mutation complete!")
- return TRUE
- else
- to_chat(usr, "Mutation failed!")
- return FALSE
-
-/datum/mutator_set/proc/can_purchase_mutator(mutator_name)
- var/datum/xeno_mutator/XM = GLOB.xeno_mutator_list[mutator_name]
- if(user_level < XM.required_level)
- return FALSE //xeno doesn't meet the level requirements
- if(remaining_points < XM.cost)
- return FALSE //mutator is too expensive
- if(XM.unique)
- if(XM.name in purchased_mutators)
- return FALSE //unique mutator already purchased
- if(XM.keystone)
- for(var/name in purchased_mutators)
- if(GLOB.xeno_mutator_list[name].keystone)
- return FALSE //We already have a keystone mutator
- if(XM.flaw)
- for(var/name in purchased_mutators)
- if(GLOB.xeno_mutator_list[name].flaw)
- return FALSE //We already have a flaw mutator
- return TRUE
-
-//Lists mutators available for purchase
-/datum/mutator_set/proc/available_mutators()
- var/list/can_purchase = list()
-
- for(var/str in GLOB.xeno_mutator_list)
- if (can_purchase_mutator(str))
- can_purchase += str //can purchase!
-
- return can_purchase
-
-//Mutators applying to the Hive as a whole
-/datum/mutator_set/hive_mutators
- var/datum/hive_status/hive //Which hive do these mutators apply to. Need this to affect variables there
- var/leader_count_boost = 0
- var/maturation_multiplier = 1
- var/tier_slot_multiplier = 1
- var/larva_gestation_multiplier = 1
- var/bonus_larva_spawn_chance = 0
-
-/datum/mutator_set/hive_mutators/list_and_purchase_mutators()
- if(!hive || !hive.living_xeno_queen)
- return //somehow Queen is not set but this function was called...
- if(hive.living_xeno_queen.is_dead())
- return //Dead xenos can't mutate!
- if(hive.living_xeno_queen.hardcore)
- to_chat(usr, SPAN_WARNING("No time for that, must KILL!"))
- return
- if(!hive.living_xeno_queen.ovipositor)
- to_chat(usr, "You must be in Ovipositor to purchase Hive Mutators.")
- return
- . = ..()
- if (. == TRUE && purchased_mutators.len)
- var/m = purchased_mutators[purchased_mutators.len]
- log_mutator("[hive.living_xeno_queen.name] purchased Hive Mutator '[m]'")
-
-/datum/mutator_set/hive_mutators/can_purchase_mutator(mutator_name)
- if (..() == FALSE)
- return FALSE //Can't buy it regardless
- var/datum/xeno_mutator/XM = GLOB.xeno_mutator_list[mutator_name]
- if(XM.individual_only)
- return FALSE //We can't buy individual mutators on a Hive level
- return TRUE
-
-//Called when the Queen dies
-// This isn't currently used, but if anyone wants to, expect it to be broken because
-// I haven't made any effort to integrate it into the new system (Fourkhan, 5/11/19)
-/datum/mutator_set/hive_mutators/proc/reset_mutators()
- if(purchased_mutators.len == 0)
- //No mutators purchased, nothing to reset!
- return
-
- var/depowered = FALSE
- for(var/name in purchased_mutators)
- if(!GLOB.xeno_mutator_list[name].death_persistent)
- purchased_mutators -= name
- depowered = TRUE
-
- if(!depowered)
- return //We haven't lost anything
-
- tackle_strength_bonus = 0
-
- leader_count_boost = 0
- maturation_multiplier = 1
- tier_slot_multiplier = 1
- larva_gestation_multiplier = 1
- bonus_larva_spawn_chance = 0
-
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- X.recalculate_everything()
- to_chat(X, SPAN_XENOANNOUNCE("Queen's influence wanes. You feel weak!"))
- playsound(X.loc, "alien_help", 25)
- X.xeno_jitter(15)
-
-/datum/mutator_set/hive_mutators/recalculate_everything(description)
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- X.recalculate_everything()
- to_chat(X, SPAN_XENOANNOUNCE("Queen has granted the Hive a boon! [description]"))
- X.xeno_jitter(15)
-/datum/mutator_set/hive_mutators/recalculate_stats(description)
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- X.recalculate_stats()
- to_chat(X, SPAN_XENOANNOUNCE("Queen has granted the Hive a boon! [description]"))
- X.xeno_jitter(15)
-/datum/mutator_set/hive_mutators/recalculate_actions(description)
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- X.recalculate_actions()
- to_chat(X, SPAN_XENOANNOUNCE("Queen has granted the Hive a boon! [description]"))
- X.xeno_jitter(15)
-/datum/mutator_set/hive_mutators/recalculate_pheromones(description)
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- X.recalculate_pheromones()
- to_chat(X, SPAN_XENOANNOUNCE("Queen has granted the Hive a boon! [description]"))
- X.xeno_jitter(15)
-/datum/mutator_set/hive_mutators/proc/recalculate_maturation(description)
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- X.recalculate_maturation()
- to_chat(X, SPAN_XENOANNOUNCE("Queen has granted the Hive a boon! [description]"))
- X.xeno_jitter(15)
-/datum/mutator_set/hive_mutators/proc/recalculate_hive(description)
- hive.recalculate_hive()
- give_feedback(description)
-/datum/mutator_set/hive_mutators/give_feedback(description)
- for(var/mob/living/carbon/xenomorph/X in GLOB.living_xeno_list)
- if(X.hivenumber == hive.hivenumber)
- to_chat(X, SPAN_XENOANNOUNCE("Queen has granted the Hive a boon! [description]"))
- X.xeno_jitter(15)
-
-//Mutators applying to an individual xeno
-/datum/mutator_set/individual_mutators
- var/mob/living/carbon/xenomorph/xeno
- var/pull_multiplier = 1
- var/egg_laying_multiplier = 1
- var/need_weeds = TRUE
- //Strains Below
- remaining_points = 6
-
-
-/datum/mutator_set/individual_mutators/Destroy()
- if(xeno)
- xeno.mutators = null
- xeno = null
- . = ..()
-
-/datum/mutator_set/individual_mutators/list_and_purchase_mutators()
- . = ..()
- if (. == TRUE && purchased_mutators.len)
- var/m = purchased_mutators[purchased_mutators.len]
- log_mutator("[xeno.name] purchased Mutator '[m]'")
-
-/datum/mutator_set/individual_mutators/can_purchase_mutator(mutator_name)
- if (..() == FALSE)
- return FALSE //Can't buy it regardless
- var/datum/xeno_mutator/XM = GLOB.xeno_mutator_list[mutator_name]
- if(XM.hive_only)
- return FALSE //We can't buy Hive mutators on an individual level
- if(XM.caste_whitelist && (XM.caste_whitelist.len > 0) && !(xeno.caste_type in XM.caste_whitelist))
- return FALSE //We are not on the whitelist
- return TRUE
-
-/datum/mutator_set/individual_mutators/recalculate_actions(description, flavor_description = null)
- xeno.recalculate_actions()
- to_chat(xeno, SPAN_XENOANNOUNCE("[description]"))
- if (flavor_description != null)
- to_chat(xeno, SPAN_XENOLEADER("[flavor_description]"))
- xeno.xeno_jitter(15)
-
-
-/mob/living/carbon/xenomorph/queen/verb/purchase_hive_mutators()
- set name = "Purchase Hive Mutators"
- set desc = "Purchase Mutators affecting the entire Hive."
- set category = "Alien"
- if(hardcore)
- to_chat(usr, SPAN_WARNING("No time for that, must KILL!"))
- return
- if(!src.hive || !src.hive.mutators)
- return //For some reason we don't have mutators
- src.hive.mutators.list_and_purchase_mutators()
-
-/mob/living/carbon/xenomorph/verb/purchase_strains()
- set name = "Purchase Strains"
- set desc = "Purchase Strains for yourself."
- set category = "Alien"
-
- if(!strain_checks())
- return
- if(!src.mutators)
- return //For some reason we don't have mutators
- src.mutators.list_and_purchase_mutators()
-
-/mob/living/carbon/xenomorph/proc/strain_checks()
- if(!check_state(TRUE))
- return FALSE
-
- if(is_ventcrawling)
- to_chat(src, SPAN_WARNING("This place is too constraining to take a strain."))
- return FALSE
-
- if(!isturf(loc))
- to_chat(src, SPAN_WARNING("We can't take a strain here."))
- return FALSE
-
- if(handcuffed || legcuffed)
- to_chat(src, SPAN_WARNING("The restraints are too restricting to allow us to take a strain."))
- return FALSE
-
- if(health < maxHealth)
- to_chat(src, SPAN_WARNING("We must be at full health to take a strain."))
- return FALSE
-
- if(agility || fortify || crest_defense || stealth)
- to_chat(src, SPAN_WARNING("We cannot take a strain while in this stance."))
- return FALSE
-
- return TRUE
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index fc25c80e795f..6aedbb24d0a2 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -130,10 +130,11 @@
var/weed_level = WEED_LEVEL_STANDARD
var/acid_level = 0
- // Mutator-related and other important vars
- var/mutation_icon_state = null
- var/mutation_type = null
- var/datum/mutator_set/individual_mutators/mutators = new
+ // Strain-related vars
+ /// A list of strain typepaths that the xeno is able to choose.
+ var/list/available_strains = list()
+ /// The xeno's strain, if they've taken one.
+ var/datum/xeno_strain/chosen_strain = null
// Hive-related vars
var/datum/hive_status/hive
@@ -389,8 +390,6 @@
for(var/trait in hive.hive_inherant_traits)
ADD_TRAIT(src, trait, TRAIT_SOURCE_HIVE)
- mutators.xeno = src
-
//Set caste stuff
if(caste_type && GLOB.xeno_datum_list[caste_type])
caste = GLOB.xeno_datum_list[caste_type]
@@ -661,8 +660,8 @@
. += "It appears to belong to [hive?.name ? "the [hive.name]" : "a different hive"]."
if(isxeno(user) || isobserver(user))
- if(mutation_type != "Normal")
- . += "It has specialized into a [mutation_type]."
+ if(chosen_strain)
+ . += "It has specialized into a [chosen_strain.name]."
if(iff_tag)
. += SPAN_NOTICE("It has an IFF tag sticking out of its carapace.")
@@ -693,7 +692,7 @@
selected_ability = null
queued_action = null
- QDEL_NULL(mutators)
+ QDEL_NULL(chosen_strain)
QDEL_NULL(behavior_delegate)
built_structures = null
@@ -709,18 +708,11 @@
if(hardcore)
attack_log?.Cut() // Completely clear out attack_log to limit mem usage if we fail to delete
- . = ..()
-
- // Everything below fits the "we have to clear by principle it but i dont wanna break stuff" bill
- mutators = null
-
-
+ return ..()
/mob/living/carbon/xenomorph/slip(slip_source_name, stun_level, weaken_level, run_only, override_noslip, slide_steps)
return FALSE
-
-
/mob/living/carbon/xenomorph/start_pulling(atom/movable/AM, lunge, no_msg)
if(SEND_SIGNAL(AM, COMSIG_MOVABLE_XENO_START_PULLING, src) & COMPONENT_ALLOW_PULL)
return do_pull(AM, lunge, no_msg)
@@ -823,10 +815,10 @@
//*********************************************************//
-//********************Mutator functions********************//
+// ******************** Strain Procs **********************//
//*********************************************************//
-//Call this function when major changes happen - evolutions, upgrades, mutators getting removed
+//Call this proc when major changes happen - evolutions, upgrades, mutators getting removed
/mob/living/carbon/xenomorph/proc/recalculate_everything()
recalculate_stats()
recalculate_actions()
@@ -1043,7 +1035,8 @@
handle_ghost_message()
/mob/living/carbon/xenomorph/proc/handle_ghost_message()
- notify_ghosts("[src] ([mutation_type] [caste_type]) has ghosted and their body is up for grabs!", source = src)
+ var/strain_name = chosen_strain ? chosen_strain.name : "Normal"
+ notify_ghosts("[src] ([strain_name] [caste_type]) has ghosted and their body is up for grabs!", source = src)
/mob/living/carbon/xenomorph/larva/handle_ghost_message()
if(locate(/obj/effect/alien/resin/special/pylon/core) in range(2, get_turf(src)))
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/mutator.dm b/code/modules/mob/living/carbon/xenomorph/mutators/mutator.dm
deleted file mode 100644
index 6736bdb0419b..000000000000
--- a/code/modules/mob/living/carbon/xenomorph/mutators/mutator.dm
+++ /dev/null
@@ -1,103 +0,0 @@
-#define MUTATOR_COST_CHEAP 2
-#define MUTATOR_COST_MODERATE 3
-#define MUTATOR_COST_EXPENSIVE 1
-
-//Individual mutator
-/datum/xeno_mutator
- var/name = "Mutator name" //Name of the mutator, should be short but informative
- var/description = "Mutator description" //Description to be displayed on purchase
- var/flavor_description = null // Optional flavor text to be shown. Semi-OOC
- var/cost = MUTATOR_COST_CHEAP //How expensive the mutator is
- var/required_level = 0 //Level of xeno upgrade required to unlock
- var/unique = TRUE //True if you can only buy it once
- var/death_persistent = FALSE //True if the mutators persists after Queen death (aka, mostly for "once ever" mutators)
- var/hive_only = FALSE //Hive-only mutators
- var/individual_only = FALSE //Individual-only mutators
- var/keystone = FALSE //Xeno can only take one Keystone mutator
- var/flaw = FALSE //Flaws give you points back, but you can only take one of them
- var/list/caste_whitelist = list() //List of the only castes that can buy this mutator
-
- // Rework by Fourkhan - 4/26/19, redone again c. 2/2020
- // HOW TO ADD A NEW MUTATOR
- // Step 0: Write an action(s)
- // the "handler" procs go in the appropriate caste's subfolder under the "ABILITIES" file.
- // the actual ACTION procs go in the appropriate caste's subfolder under the "POWERS" file.
- // Any constants you need to access for your strain should be in the behavior holder and
- // accessed using a cast to it using the mutator_type variable as defined below. (Or using an istype of the behavior holder)
- // vars that absolutely must be held on the xenos themselves can be added to the Xenomorph class itself.
- // Be sure to follow the spec in xeno_action.dm as far as setting up xeno_cooldown is concerned.
- //
- // Step 1: Write the Behavior Delegate datum IF NECESSARY
- // the "behavior holder" datum defines all unique behavior and state for each xeno/strain. It works by embedding a number of 'hooks'
- // for example, if you want to store bonus damage and apply it on slashes, behavior delegates are the way to do it.
- // in common procs that call back to Xeno features. See other behavior delegates for examples. Afterward, set the behavior_delegate_type
- // var on the strain datum to indicate which behavior holder to apply to your strain.
- //
- // Step 1: Copy/paste another datum definiton and edit it for your strain
- // make sure to populate each of the variables listed above (at least as much as other strains)
- //
- // Step 2: Write the apply_mutator proc.
- // FIRST: populate mutator_actions_to_add and mutator_actions_to_remove according to that documentation.
- // THEN: write the body of the apply_mutator method according to your speficiations
- // THEN: call mutator_update_actions on your xeno
- // call recalculate actions on your mutator set (this should be auto populated)
- // You should probably also call recalculate_everything() on the host Xeno to make sure you don't end up with any
- // strange transient values.
- // THEN: Set the mutation_type var on the host xeno to "name" the strain.
- // FINALLY: Call apply_behavior_holder() to add the behavior datum to the new Xeno.
- //
- // You're done!
-
- // Both should be set to null when their use is not necessary.
- /// A list of PATHS of actions that need to be removed when a xeno takes the mutator.
- var/list/mutator_actions_to_remove //Actions to remove when the mutator is added
- /// A list of PATHS of actions to be ADDED when the Xeno takes the mutator.
- var/list/mutator_actions_to_add //Actions to add when the mutator is added
-
- // Type of the behavior datum to add
- var/behavior_delegate_type = null // Specify this on subtypes
-
-/datum/xeno_mutator/New()
- . = ..()
- name = "[name]"
-
-
-/datum/xeno_mutator/proc/apply_mutator(datum/mutator_set/MS)
- if(!MS.can_purchase_mutator(name))
- return FALSE
- if(MS.remaining_points < cost)
- return FALSE
- MS.remaining_points -= cost
- MS.purchased_mutators += name
-
- if(istype(MS, /datum/mutator_set/individual_mutators))
- var/datum/mutator_set/individual_mutators/IS = MS
- if(IS.xeno)
- IS.xeno.hive.hive_ui.update_xeno_info()
-
- return TRUE
-
-// Sets up actions for when a mutator is taken
-// Must be called at the end of any mutator that changes available actions
-// (read: Strains) apply_mutator proc for the mutator to work correctly.
-/datum/xeno_mutator/proc/mutator_update_actions(mob/living/carbon/xenomorph/X)
- if(mutator_actions_to_remove)
- for(var/action_path in mutator_actions_to_remove)
- remove_action(X, action_path)
- if(mutator_actions_to_add)
- for(var/action_path in mutator_actions_to_add)
- give_action(X, action_path)
-
-// Substitutes the existing behavior delegate for the strain-defined one.
-/datum/xeno_mutator/proc/apply_behavior_holder(mob/living/carbon/xenomorph/X)
- if (!istype(X))
- log_debug("Null mob handed to apply_behavior_holder. Tell the devs.")
- log_admin("Null mob handed to apply_behavior_holder. Tell the devs.")
- message_admins("Null mob handed to apply_behavior_holder. Tell the devs.")
-
- if (behavior_delegate_type)
- if(X.behavior_delegate)
- qdel(X.behavior_delegate)
- X.behavior_delegate = new behavior_delegate_type()
- X.behavior_delegate.bound_xeno = X
- X.behavior_delegate.add_to_xeno()
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/behavior_delegate.dm b/code/modules/mob/living/carbon/xenomorph/strains/behavior_delegate.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/behavior_delegate.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/behavior_delegate.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/boiler/trapper.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/boiler/trapper.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/carrier/eggsac.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/carrier/eggsac.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/crusher/charger.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/crusher/charger.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/defender/steel_crest.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/defender/steel_crest.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/gardener.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/gardener.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/healer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/healer.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/hivelord/resin_whisperer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/hivelord/resin_whisperer.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/lurker/vampire.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/lurker/vampire.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/lurker/vampire.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/lurker/vampire.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/dancer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/dancer.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/dancer.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/dancer.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/oppressor.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/oppressor.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/oppressor.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/oppressor.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/vanguard.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/vanguard.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/warden.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/warden.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/warden.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/warden.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/ravager/berserker.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/berserker.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/ravager/berserker.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/berserker.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/ravager/hedgehog.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/hedgehog.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/ravager/hedgehog.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/hedgehog.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/runner/acid.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/runner/acid.dm
similarity index 100%
rename from code/modules/mob/living/carbon/xenomorph/mutators/strains/runner/acid.dm
rename to code/modules/mob/living/carbon/xenomorph/strains/castes/runner/acid.dm
diff --git a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm
new file mode 100644
index 000000000000..23ec13c6b596
--- /dev/null
+++ b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm
@@ -0,0 +1,116 @@
+/datum/xeno_strain
+ /// The name of the strain. Should be short but informative.
+ var/name
+ /// Description to be displayed on purchase.
+ var/description
+ /// (OPTIONAL) Flavor text to be shown on purchase. Semi-OOC
+ var/flavor_description
+ /// (OPTIONAL) A custom icon state prefix for xenos who have taken the strain.
+ var/xeno_icon_state
+
+ /// A list of action typepaths which should be removed when a xeno takes the strain.
+ var/list/actions_to_remove
+ /// A list of action typepaths which should be added when a xeno takes the strain.
+ var/list/actions_to_add
+
+ /// Typepath of the [/datum/behavior_delegate] to add.
+ var/behavior_delegate_type
+
+/// TODO: documentation
+/// Returns a bool indicating if the strain was successfully applied.
+/datum/xeno_strain/proc/apply_strain(mob/living/carbon/xenomorph/xeno)
+ SHOULD_CALL_PARENT(TRUE)
+
+ xeno.chosen_strain = src
+ update_actions(xeno)
+ register_signals(xeno)
+ apply_behavior_holder(xeno)
+ update_mob(xeno)
+
+ xeno.hive.hive_ui.update_xeno_info()
+
+ to_chat(xeno, SPAN_XENOANNOUNCE(description))
+ if(flavor_description)
+ to_chat(xeno, SPAN_XENOLEADER(flavor_description))
+ return TRUE
+
+/// Update the `xeno`'s action buttons based on [/datum/xeno_strain/var/actions_to_remove] and [/datum/xeno_strain/var/actions_to_add].
+/datum/xeno_strain/proc/update_actions(mob/living/carbon/xenomorph/xeno)
+ for(var/action_path in actions_to_remove)
+ remove_action(xeno, action_path)
+ for(var/action_path in actions_to_add)
+ give_action(xeno, action_path)
+
+/// TODO: documentation
+/datum/xeno_strain/proc/register_signals(mob/living/carbon/xenomorph/xeno)
+ return
+
+/// TODO: documentation
+/datum/xeno_strain/proc/apply_behavior_holder(mob/living/carbon/xenomorph/xeno)
+ if(!behavior_delegate_type)
+ // don't need to do anything
+ return
+
+ if(xeno.behavior_delegate)
+ qdel(xeno.behavior_delegate)
+ xeno.behavior_delegate = new behavior_delegate_type()
+ xeno.behavior_delegate.bound_xeno = xeno
+ xeno.behavior_delegate.add_to_xeno()
+
+/// TODO: documentation
+/datum/xeno_strain/proc/update_mob(mob/living/carbon/xenomorph/xeno)
+ xeno.xeno_jitter(1.5 SECONDS)
+ xeno.update_icons()
+
+
+/mob/living/carbon/xenomorph/verb/purchase_strain()
+ set name = "Purchase Strain"
+ set desc = "Purchase a strain for yourself"
+ set category = "Alien"
+
+ if(!can_take_strain())
+ return
+
+ var/strain_choice = tgui_input_list(usr, "Which strain would you like to take?", "Choose Strain", GLOB.xeno_strain_list, theme = "hive_status")
+ var/datum/xeno_strain/strain_path = GLOB.xeno_strain_list[strain_choice]
+ // Check again after the user has picked one.
+ if(!can_take_strain())
+ return
+ // Show the user the strain's description, and double check that they want it.
+ if(alert(usr, "[initial(strain_path.description)]\n\nConfirm mutation?", "Choose Strain", "Yes", "No") != "Yes")
+ return
+ // One more time after they confirm.
+ if(!can_take_strain())
+ return
+
+ var/datum/xeno_strain/strain_instance = new strain_path()
+ // Apply the strain to the xeno.
+ if(strain_instance.apply_strain(src))
+ // And log it if it was successful.
+ log_strain("[name] purchased strain '[strain_instance.type]'")
+
+/mob/living/carbon/xenomorph/proc/can_take_strain()
+ if(!length(available_strains) || !check_state(TRUE))
+ return FALSE
+
+ if(is_ventcrawling)
+ to_chat(src, SPAN_WARNING("This place is too constraining to take a strain."))
+ return FALSE
+
+ if(!isturf(loc))
+ to_chat(src, SPAN_WARNING("We can't take a strain here."))
+ return FALSE
+
+ if(handcuffed || legcuffed)
+ to_chat(src, SPAN_WARNING("The restraints are too restricting to allow us to take a strain."))
+ return FALSE
+
+ if(health < maxHealth)
+ to_chat(src, SPAN_WARNING("We must be at full health to take a strain."))
+ return FALSE
+
+ if(agility || fortify || crest_defense || stealth)
+ to_chat(src, SPAN_WARNING("We cannot take a strain while in this stance."))
+ return FALSE
+
+ return TRUE
diff --git a/code/modules/mob/living/carbon/xenomorph/update_icons.dm b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
index 55995ec0b264..722b5f7a48bb 100644
--- a/code/modules/mob/living/carbon/xenomorph/update_icons.dm
+++ b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
@@ -41,7 +41,7 @@
Q.queen_standing_icon = icon_xeno
Q.queen_ovipositor_icon = 'icons/mob/xenos/ovipositor.dmi'
- var/mutation_caste_state = "[mutation_type] [caste.caste_type]"
+ var/mutation_caste_state = "[chosen_strain?.xeno_icon_state] [caste.caste_type]"
if(!walking_state_cache[mutation_caste_state])
var/cache_walking_state = FALSE
for(var/state in icon_states(icon))
@@ -64,7 +64,7 @@
if(behavior_delegate?.on_update_icons())
return
- var/mutation_caste_state = "[mutation_icon_state || mutation_type] [caste.caste_type]"
+ var/mutation_caste_state = "[chosen_strain?.xeno_icon_state] [caste.caste_type]"
if(stat == DEAD)
icon_state = "[mutation_caste_state] Dead"
if(!(icon_state in icon_states(icon_xeno)))
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 0ad186e331cc..adffc94774b2 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -1961,7 +1961,6 @@
#include "code\modules\mob\living\carbon\xenomorph\xeno_verbs.dm"
#include "code\modules\mob\living\carbon\xenomorph\XenoAttacks.dm"
#include "code\modules\mob\living\carbon\xenomorph\Xenomorph.dm"
-#include "code\modules\mob\living\carbon\xenomorph\XenoMutatorSets.dm"
#include "code\modules\mob\living\carbon\xenomorph\XenoOverwatch.dm"
#include "code\modules\mob\living\carbon\xenomorph\XenoProcs.dm"
#include "code\modules\mob\living\carbon\xenomorph\XenoUpgrade.dm"
@@ -2041,23 +2040,23 @@
#include "code\modules\mob\living\carbon\xenomorph\castes\Spitter.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\Warrior.dm"
#include "code\modules\mob\living\carbon\xenomorph\items\iff_tag.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\behavior_delegate.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\mutator.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\boiler\trapper.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\carrier\eggsac.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\crusher\charger.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\defender\steel_crest.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\drone\gardener.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\drone\healer.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\hivelord\resin_whisperer.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\lurker\vampire.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\praetorian\dancer.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\praetorian\oppressor.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\praetorian\vanguard.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\praetorian\warden.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\ravager\berserker.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\ravager\hedgehog.dm"
-#include "code\modules\mob\living\carbon\xenomorph\mutators\strains\runner\acid.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\behavior_delegate.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\xeno_strain.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\boiler\trapper.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\carrier\eggsac.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\crusher\charger.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\defender\steel_crest.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\drone\gardener.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\drone\healer.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\hivelord\resin_whisperer.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\lurker\vampire.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\praetorian\dancer.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\praetorian\oppressor.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\praetorian\vanguard.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\praetorian\warden.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\ravager\berserker.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\ravager\hedgehog.dm"
+#include "code\modules\mob\living\carbon\xenomorph\strains\castes\runner\acid.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\login.dm"
#include "code\modules\mob\living\silicon\say.dm"
From 64eec09920f6f0c45bfad81469658a39983420bf Mon Sep 17 00:00:00 2001
From: SabreML <57483089+SabreML@users.noreply.github.com>
Date: Mon, 22 Jan 2024 15:51:17 +0000
Subject: [PATCH 02/17] Stuff
I removed the `tacklestrength_*` part since it wasn't being used at all
---
.../mob/living/carbon/xenomorph/Xenomorph.dm | 26 +++++--------------
.../living/carbon/xenomorph/castes/Carrier.dm | 6 ++++-
.../living/carbon/xenomorph/castes/Runner.dm | 7 ++++-
.../living/carbon/xenomorph/hive_status.dm | 16 +++---------
.../carbon/xenomorph/strains/xeno_strain.dm | 2 +-
.../living/carbon/xenomorph/update_icons.dm | 4 +--
.../living/carbon/xenomorph/xeno_helpers.dm | 11 +++++++-
tgui/packages/tgui/interfaces/HiveStatus.jsx | 2 +-
8 files changed, 35 insertions(+), 39 deletions(-)
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 6aedbb24d0a2..5245230c20e7 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -134,7 +134,7 @@
/// A list of strain typepaths that the xeno is able to choose.
var/list/available_strains = list()
/// The xeno's strain, if they've taken one.
- var/datum/xeno_strain/chosen_strain = null
+ var/datum/xeno_strain/strain = null
// Hive-related vars
var/datum/hive_status/hive
@@ -660,8 +660,8 @@
. += "It appears to belong to [hive?.name ? "the [hive.name]" : "a different hive"]."
if(isxeno(user) || isobserver(user))
- if(chosen_strain)
- . += "It has specialized into a [chosen_strain.name]."
+ if(strain)
+ . += "It has specialized into a [strain.name]."
if(iff_tag)
. += SPAN_NOTICE("It has an IFF tag sticking out of its carapace.")
@@ -692,7 +692,7 @@
selected_ability = null
queued_action = null
- QDEL_NULL(chosen_strain)
+ QDEL_NULL(strain)
QDEL_NULL(behavior_delegate)
built_structures = null
@@ -842,8 +842,6 @@
tackle_min = caste.tackle_min
tackle_max = caste.tackle_max
tackle_chance = caste.tackle_chance + tackle_chance_modifier
- tacklestrength_min = caste.tacklestrength_min + mutators.tackle_strength_bonus + hive.mutators.tackle_strength_bonus
- tacklestrength_max = caste.tacklestrength_max + mutators.tackle_strength_bonus + hive.mutators.tackle_strength_bonus
/mob/living/carbon/xenomorph/proc/recalculate_health()
var/new_max_health = nocrit ? health_modifier + maxHealth : health_modifier + caste.max_health
@@ -899,18 +897,8 @@
/mob/living/carbon/xenomorph/proc/recalculate_actions()
recalculate_acid()
recalculate_weeds()
- pull_multiplier = mutators.pull_multiplier
- if(isrunner(src))
- //Xeno runners need a small nerf to dragging speed mutator
- pull_multiplier = 1 - (1 - mutators.pull_multiplier) * 0.85
- if(is_zoomed)
- zoom_out()
- if(iscarrier(src))
- var/mob/living/carbon/xenomorph/carrier/carrier = src
- carrier.huggers_max = caste.huggers_max
- carrier.eggs_max = caste.eggs_max
- need_weeds = mutators.need_weeds
-
+ // Modified on subtypes
+ pull_multiplier = initial(pull_multiplier)
/mob/living/carbon/xenomorph/proc/recalculate_acid()
if(caste)
@@ -1035,7 +1023,7 @@
handle_ghost_message()
/mob/living/carbon/xenomorph/proc/handle_ghost_message()
- var/strain_name = chosen_strain ? chosen_strain.name : "Normal"
+ var/strain_name = strain ? strain.name : "Normal"
notify_ghosts("[src] ([strain_name] [caste_type]) has ghosted and their body is up for grabs!", source = src)
/mob/living/carbon/xenomorph/larva/handle_ghost_message()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
index 2e106743514a..131548bcb740 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
@@ -75,7 +75,6 @@
/mob/living/carbon/xenomorph/proc/rename_tunnel,
/mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher,
)
- mutation_type = CARRIER_NORMAL
icon_xenonid = 'icons/mob/xenonids/carrier.dmi'
@@ -207,6 +206,11 @@
if(eggs_dropped) //Checks whether or not to announce egg drop.
xeno_message(SPAN_XENOANNOUNCE("[src] has dropped some precious eggs!"), 2, hive.hivenumber)
+/mob/living/carbon/xenomorph/carrier/recalculate_actions()
+ . = ..()
+ huggers_max = caste.huggers_max
+ eggs_max = caste.eggs_max
+
/mob/living/carbon/xenomorph/carrier/get_status_tab_items()
. = ..()
if(huggers_max > 0)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm
index 3a23afc145d1..b55eb5b004b8 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm
@@ -62,7 +62,6 @@
inherent_verbs = list(
/mob/living/carbon/xenomorph/proc/vent_crawl,
)
- mutation_type = RUNNER_NORMAL
icon_xeno = 'icons/mob/xenos/runner.dmi'
icon_xenonid = 'icons/mob/xenonids/runner.dmi'
@@ -77,6 +76,12 @@
if (pass_flags_container)
pass_flags_container.flags_pass |= PASS_FLAGS_CRAWLER
+/mob/living/carbon/xenomorph/runner/recalculate_actions()
+ . = ..()
+ pull_multiplier *= 0.85
+ if(is_zoomed)
+ zoom_out()
+
/datum/behavior_delegate/runner_base
name = "Base Runner Behavior Delegate"
diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status.dm b/code/modules/mob/living/carbon/xenomorph/hive_status.dm
index bb67eaa055a8..c6d0b158c8b3 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_status.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_status.dm
@@ -46,7 +46,6 @@
var/allowed_nest_distance = 15 //How far away do we allow nests from an ovied Queen. Default 15 tiles.
var/obj/effect/alien/resin/special/pylon/core/hive_location = null //Set to ref every time a core is built, for defining the hive location
- var/datum/mutator_set/hive_mutators/mutators = new
var/tier_slot_multiplier = 1
var/larva_gestation_multiplier = 1
var/bonus_larva_spawn_chance = 1
@@ -143,7 +142,6 @@
var/static/list/evolution_menu_images
/datum/hive_status/New()
- mutators.hive = src
hive_ui = new(src)
mark_ui = new(src)
faction_ui = new(src)
@@ -279,7 +277,6 @@
/datum/hive_status/proc/set_living_xeno_queen(mob/living/carbon/xenomorph/queen/queen)
if(!queen)
- mutators.reset_mutators()
SStracking.delete_leader("hive_[hivenumber]")
SStracking.stop_tracking("hive_[hivenumber]", living_xeno_queen)
SShive_status.wait = 10 SECONDS
@@ -293,10 +290,8 @@
recalculate_hive()
/datum/hive_status/proc/recalculate_hive()
- if (!living_xeno_queen)
- queen_leader_limit = 0 //No leaders for a Hive without a Queen!
- else
- queen_leader_limit = 4 + mutators.leader_count_boost
+ //No leaders for a Hive without a Queen!
+ queen_leader_limit = living_xeno_queen ? 4 : 0
if (xeno_leader_list.len > queen_leader_limit)
var/diff = 0
@@ -310,11 +305,6 @@
open_xeno_leader_positions += i
xeno_leader_list.len++
-
- tier_slot_multiplier = mutators.tier_slot_multiplier
- larva_gestation_multiplier = mutators.larva_gestation_multiplier
- bonus_larva_spawn_chance = mutators.bonus_larva_spawn_chance
-
hive_ui.update_all_data()
/datum/hive_status/proc/add_hive_leader(mob/living/carbon/xenomorph/xeno)
@@ -524,7 +514,7 @@
xeno_name = "Larva ([X.nicknumber])"
xenos["[X.nicknumber]"] = list(
"name" = xeno_name,
- "strain" = X.mutation_type,
+ "strain" = X.strain,
"ref" = "\ref[X]"
)
diff --git a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm
index 23ec13c6b596..fd43b23de993 100644
--- a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm
+++ b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm
@@ -21,7 +21,7 @@
/datum/xeno_strain/proc/apply_strain(mob/living/carbon/xenomorph/xeno)
SHOULD_CALL_PARENT(TRUE)
- xeno.chosen_strain = src
+ xeno.strain = src
update_actions(xeno)
register_signals(xeno)
apply_behavior_holder(xeno)
diff --git a/code/modules/mob/living/carbon/xenomorph/update_icons.dm b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
index 722b5f7a48bb..ebf7566c0131 100644
--- a/code/modules/mob/living/carbon/xenomorph/update_icons.dm
+++ b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
@@ -41,7 +41,7 @@
Q.queen_standing_icon = icon_xeno
Q.queen_ovipositor_icon = 'icons/mob/xenos/ovipositor.dmi'
- var/mutation_caste_state = "[chosen_strain?.xeno_icon_state] [caste.caste_type]"
+ var/mutation_caste_state = "[strain?.xeno_icon_state] [caste.caste_type]"
if(!walking_state_cache[mutation_caste_state])
var/cache_walking_state = FALSE
for(var/state in icon_states(icon))
@@ -64,7 +64,7 @@
if(behavior_delegate?.on_update_icons())
return
- var/mutation_caste_state = "[chosen_strain?.xeno_icon_state] [caste.caste_type]"
+ var/mutation_caste_state = "[strain?.xeno_icon_state] [caste.caste_type]"
if(stat == DEAD)
icon_state = "[mutation_caste_state] Dead"
if(!(icon_state in icon_states(icon_xeno)))
diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_helpers.dm b/code/modules/mob/living/carbon/xenomorph/xeno_helpers.dm
index 7324a3af6892..4048af28bc81 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_helpers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_helpers.dm
@@ -34,6 +34,15 @@
return 100
return round(armor_integrity * 100 / armor_integrity_max)
+/**
+ * Returns the custom icon state from the xeno's strain, if it has one.
+ *
+ * If that isn't available, returns "Normal"
+ */
+/mob/living/carbon/xenomorph/proc/get_strain_sprite()
+ return strain?.xeno_icon_state || "Normal"
+ // TODO: Go through xeno/xenoid sprites and remove "Normal", so that this isn't needed.
+
//These don't do much currently. Or anything? Only around for legacy code.
/mob/living/carbon/xenomorph/is_mob_restrained()
return 0
@@ -58,4 +67,4 @@
return caste.fire_intensity_resistance
/mob/living/carbon/xenomorph/alter_ghost(mob/dead/observer/ghost)
- ghost.icon_state = "[mutation_type] [caste.caste_type] Running"
+ ghost.icon_state = "[get_strain_sprite()] [caste.caste_type] Running"
diff --git a/tgui/packages/tgui/interfaces/HiveStatus.jsx b/tgui/packages/tgui/interfaces/HiveStatus.jsx
index ea23b73aca55..72d9476f96dd 100644
--- a/tgui/packages/tgui/interfaces/HiveStatus.jsx
+++ b/tgui/packages/tgui/interfaces/HiveStatus.jsx
@@ -359,7 +359,7 @@ const XenoList = (props) => {
qdmd zJFL3q`eX#X``*C=b#w@CH5g0`mskRx18o-DEq&&w}XLzmD<0yWEc{99fnq0+} zM*;n!K4auBWB!3kQ)T+|(p2dhZS#rQ`PS1*F+Ml%W6ZBy3t@%vkixI3HKD+}H)u!m z)Q^;NG?j@VM0esLX@B#y?q!L~B*a=p;yW8xM9y{(MEKvMg=bs~;qJQ8&jP!`U1n6l zc%@6V&Gng2N0MzGof0LgWQc=L>W6?326!Lx*%#UCo*T*t^Bvm>DT&V40Z<)O8Rqt- zwG4NyNvsFl!eL{U94@=KebglsBY5oY7dNqB%6^U6>-=^Sczb}xWzuL)t48nWFPoH5 zea`iL!}dFaeNdQ0p9kiMP-S|t{&550B{xgh6g7Sk* WSYsjox&r$+Vdk8s82u7+C1UfwTNKUemVX+)a9^#S^YkCCq8G3X&q^c-dJ zDCZ7;t+NT&Riu$_#1HoL*U!4&B98*U0&KgC;c4z1#P?0j=LX>AmIZ1&Lz!axy!-aZ zOy@Cw@R@Uv=Tq`{lk|#D_Nc+gAF(9B!~$z!HahR!H@ dF+_W(TbRKL3Y$OT%g7myDbUK#$rMxuSTGu5rgK$`wWd zg6$I|_MPEqacz@NT0SRGse^idu810Be~{Ugp)R>`LBy+j@l&F={C>Yk_>CI;pnT*F zadZ`p$gb4{y>FR?bI@)#hXu#Js|p&*eBCWV9W37ySNhFoVH?VK27%3mmgH$G!(R=* zKYh>C_3^3KLkr}R;fm5fr7J#r*Eu>BGZ7?ET?%)tD7co;1H`}$PWOvH@M#oZGtgoN zt!f&C?S1{@4&Z6h?Q =t(ubXHV>&OK7#!Nwd*nD< zRdQbN|H!ocX&&O+cB!fsq_h{MS$1p5kO+oe{IJ`))fYyZhpBzb8d~LjhPk z3ad@5Z!2V&-FxVA_AqzGzJGF2K!^hcF;G6o3W_;3Flr3REFdACTcN&hOg#GfVj4F) zfr1{!>@Fsx6|)WE4=$WOIWFy2S@8K*%->C^x7SY&n1c=oNq ATgZ*Z?7?&dlGf1)9(5I0kWhI5;p LF*cR2y2^K_9ASj=_J4F8DFy`#a3k zYhhBv?Z?;-fXyj0-$<$yD)y@{OFJGQilsM=T)19PK;gXE>}-_>N@PG8l%h9@=|Rh- z!9;|{Z2iAH99nJe*9^XwB@8jdoRLu@FW;~QUGON|)INI|lWdBiJB(%^cfn@y+Ha9W zC>Vy<84Lj5#}h0+B=3C*1lMe$Ke9;)Y{n%|Edyj@dTi$@RAf)@46XUt8^njYDQ867 z?)vBNUa2q#=9cg2+6R?lh7LQXoK;24b21}8e52RrfAAbXSpT9 kUt(q+1#9Y82=R>9TXbAOat$^imfdmrgVAXEYdlTS&;|tFflY1w$uS!g~n0NJD8q zqOr>bdmppE^d0MXLjLJ#@h`9oi-1YgU1f_OASc4B-Br>o0^$N#uH8t?xR)KLGgNKo zriV|heT(&&1i#&i?cI)<7zt8$r5vBF%sEW9J5S0L)goDFh`d%xBKW*>cb=n`gGR$` zSNx+?!0BfUY3W0>MfS-v-Sd;Y98ct4p7{pxn$)u*{IPqJ4rfUGzXjg!gpBmoMZ@pz z4WXX9*WXHSSQu3>1y@Aa K)V4=n=ix-&$&a~c*_cxf3!E)A4dD^N*s 9xO(!NuYXW1e mFwZodoc1=W)Q^>inQW|a%2Gn&4rE0u C%aNrSR^~CS~#r8u`zlyLF3&J{efG5)zaNufs)IuGSw{@J$w|8 z-Iq-%3oFrD= jpm?jmUduB8LSBs+4%q>j2uS$psyqZzAIH9uI z3mJRTM?#q1>^#eXS6O0`3(CW>FTY$3_QCbe;4Pf$>~y~%9t*H%f_?#_rC# pb= z5kXz|0QFv5SoT|cWtCJ}h?{@E?RSVhTz;>32_QallGrv; 1Lpgem*M FQGe34PrZ&&Q)XMXFpI6M((3nS?3&j2V zJ^7jMUnLp1VH%dBUY*|Z&629J$vik-0ZODM8(VnhZ?%^j{t(-IC{jjkhTeDWkJm7# z#gohX6b75kkZ-chLz@)SRm;1;;XpVzT2(cR31AgDLqrHrLuzKxxNh-!4%n!f;tlh2 zpSV2juyEuLU@L&RyFwk8M#e*NSRn nj09*8{{gDk=j`-ci&4PoiUd;T z*X(O3{kqRrH`0~iF~QW8wb3z@7S1F6!9r&pon~7KKwQ_U!MllfGZes%^>ACa Sh`@nb=N}+QN&q};bb}!Brt+I6vW8pjkw?K! zLEcE|z@gGIY&LQgG-$rn-s=t_e0c9<{zq`0R0?$={&e7yWTD0MW8uChBTW}9=uz|p z3ybmRYK@NVKf8JUf7s0 UUhzAh7Uv5N32={r z;|_%Gyi&h*<)W(SJ_WvH86Ldm9l`DW(L27+wM=S1tWt-}G4s}AqcomQ67)2R++)NJ zvDK#uHBgKbS!?x(&J#rX@@=QE$lV3DDsY4cuMGyT76@j}McSXZE6Zbre~2N;`>4o? zus!5%%dHeF&ddZY@L>_2p}u6Klqc!bI{JX_OoH>qGch;i|D&}taza-`U+IIF#UsVT z^MPSv-O1>f#_E+v#efQaJ3>MnO}U@toTMUw F{^|&X(T9Q`=RDYH3xa&F6%ri4g62%{Scc1AV!KAdq1n70Tx >g!ztX5ig?M%Iep}w6YjTQCCDb8f6885vXq5sp21=&U0r7 z1pXZUcxsm$7Xw7#UcS0x5|Ds?RiJG;i2Yof%{3Qci9UHx13F @29$ss}?*6xS zeIz;h4Qi&|%+7@ z@RROtNPo|;0!TcKzZc7NbY!bc-Yqm8{Y%=0E#=?VV=>*U!8 zqjBTDX)K6{*P}cM=J}1Fsrdq^-U?|tUO+bllK+1k^3=5fstM0|BEGM*fRwi6veR4{ zF)JVcE_Arpvwycz-x5k}7$p2GpkjJ6RME&pBPD#Yci%DvCl 9&i4x&6~YsgA41qvSFb*Z4C2@`Kg{fA yMwvQBV z7=G1qx1FG_7m$)>RhS^ PY zPGew_ZI(q`3%WI5LAO}&H*eD O^+Ql`MaG zk{?7Iz=RfEilXPFKr}%J?k;pfGEq{@VYa=V-8gugYa_U9lEkF;!S#j2+xOU$3S``f z>Tjj29 }7m4>vAN*eo9MU|-v-QJ9*(h)Yo5D!=v{%@*P%%k`)R_ckJ|(U&`BJ}0|O z=UQ_*p>%Sg=5}ybs|WwJ9?CTM&8k4pbvtNE!s+dP;?xZsXyQGF5*z5b1svwG-vx`Q zi&u2PcKc5g-|!!`iHX}w7H`OD7#Z7&H-Tc71f8d)%Qre6o0_}k{!Z(jR_b94xj!|q zwP7y0x5TiPLD>Ijy+GdY>bh$ZUiTa7UH`Qmn!f(x{43CUXxyyWQZE;t95KlXWp2$+ zYIT8S?+YXH*`QbID~sN!t&bN!Zt5baeD2Dv%hsx!%DA-&EsTRNZmpz40K8DzxP 9w85``IjJd z@ZfWzsq1Kb*5lZ&ewANU6{%t1eQvF05{IY2^8T%w&q>GSj`&0Al6sGL8w>4jHUrf& zcL~a`wteW&^tmW;9aExcPe`r%fru^NfG-ESVMSQfy9Zxl6|n5=9wnr=eIJ^0(jI&e zuP*XssT+s&aT|i>bE1ck@*K7CGg59>B4JPpjxY+WSbnnAX}<%99l^?CVfVN3 9tc-F|Pu43_l_*Ds`>yDAx0DY-{r 9|bPC`l*;N^v_Dg@UxB`(w8$H3+AfQ50 zR^G_*l5L~aaBg^i1-Kzof2zL~PdO*p3+T1tL#rNMnHpA87vjd2Wj+3mpaK3_GqSfu zAhtz4?jfxfirfl{%o4`hY9dUQ9<6jnuKb~ivxT;C3`SSI7p{79z`NCrs{Of1F({pY zVejmkRv~WM0iCP^Cpb5BqMOR09Ive~>!_SS*5SwORiMbWG`~H2v<6c` zv`W%gTVK;NyN%FzWW2N24@L$aKB99_dD#Gac)7oPS0DTUD&)wfbv`o2&cOPN-{s&u z8)u)Jyf1^fU^l!A8rUO@W$}<*_FFj*o{hDgs>qT#_gI~~(%%e!tU*JFrcZ4cOEjs* zSXyT%gy!eeT=KhOo6$l1-0KOR(H6wkrB~aBCCxV(O$x3V2sFhZg_xLI!0z9{Ne2z) zdQS(wk-2(Z{?Ep& vYPDaE_&_+eIQ&YlQ-zF1a_ye&aAH2@B-D;I1EK%_)k=T zzq-zuWB@ hNhMA0r4$)AaN?F46^jCsd|) z_i8e@ SMR>}B0F7IV<&sLa&Ig6(`t$Dj?yJ10-b-zWrPH>w~uG{ap p)X%dDJ^{%QY0L)|@3x<3_`LHdY9&8xKe{MA zxB5Rl5Uj_F$p7sE{J-l_+mppr1O^MIB;}cfEq98L=gbe;nv>YL|F=wik-EJav6PMh z>TczJfI}_mEmy&bDpE4`LAd4du<#K2;`W9q=Dja*8U*O2#I7Lr`snOHkdmk^+e>c3 zN#`qg>egU}z(23pX<7f3k+aoK!Zc#ZpHew9aF!LVy3%q1LHiPW{}ugfC8U>sm?ax- zTIJ(ckGGGZM%PQlkh18P9Q_I%kRNGXl57fS&is?EOK0lTMDXkrZmP=mrvJUe{c-%= z7Ro8HXFy@T0^X>%HzE2D;{;p`NS!RRnqLTiMg(>X*tII94PwvLy^-e|Us31JArIQa zs7fUBYp7-(h-H83jRzTxBM|@wH>ddX6qLGBNX^drf!ZNzX3yMwkLI=7`ypE4uU3*K zoP|b)tVZPe$TFSJ@9pf5eU}3Uv0ZaaRFS-rcLG|}3n4m5L54{GglGf^ul4gFDwPJ6 zNrOr7*k6ZyAhCr>Ng8wf0)FsVfs*efNK!%WLBhT|DEeD(FLldm%(;-{-x+_s>6)r4 zbat01P3I>75CdgTW(6VGng$<8(|Y@k&QT|4IA8ugj-Y?cGxl97Vqk)jj9pQX4kcaX z(T`d!epFyCSRAVsXFoPe)x>fjVLj)Fp)yRur`cGMxQqu4Yf^rVb#c1NpRi8SS+ZaN zWc$yJ)XA0?FTg2s;M)36MSz|l6bw$YU5dg?29U7+`#il6f=nM)N;?i1dIFME0>*tI zGA@hel%A6z_r{q~-TzCRj#g)G+2?v%*_ekFpKKiwmX+LDRmChPh2~1ne+Z0n?r<%O z{~>pqksu1vkxW+mousQ@ypgi8JXY;hC*&6PLZF@vb1NMSg{_>qNe&;d!aBEoho{^A zw^V#H6vRv$pd|9v_`drLtYtcI!1n36po@d)ufj7F$ZYYj2dL2p2l&>Xc0u2T4p^{O zd|l_V__*QG0}fqGO$So)FOb?~{egiCbuCd5|02q%T72CN&U@cWu;Rdm)tGQB3`vlm zsZj#)Bc+36p-6fC+N2+7#09Q`1%JKv#%tUbqD&84Y<~e;I;tY@ELQ3%yw%U+rvEGD zy&Ek}FCkwQktgcnapG|CGXc{Q*MVfm3(;iEmTK1LyelPhyOCAAf#+0v%CKX1 g9tx{X~RlvhujV*U-FJxG}fZtaN7BlMLSh- `@)yw-oiRj%Ipa2I@;(&V&a3Pp4ABH5Q?Hv4t W1%s6bI<1WP%9|-nlR#`09Uy zO P2-4DV)C0Y1?%F{rY0X98g zgkNWv*x|bF;{2XBUpBwCFTtO1(CQ1rP=O9C5Hua4R(Y75{es=zTWX! Xt^HW5c z4e`Lg{8Vt?2j|O%62I3dYY7&WzZBReskFS@YQliEm8iA;UAQ}FJbtZ(v$()RBibdU zc=i^k;G;E4{nE5O*OzGvvU>|YOT2UG;O`d*$08npKUM(woI!ujsiU~>|GEKqi hmV>P)bWF)0G_c0BB>DSrDo5;q$qns!usepSU!V;EVs&+j&RB8U5@29d(c> z(TSdjl87#PmyjsYgXlp>h!(wz=p~3K(OVFri(quoTM#{o7QL6j%-lV{a?iQvoV(Wj z>#k*Cu@>{b@7~|<-p~F#&k)YSH?7&b{PJkxis$+Npz-OK2v{$qA)Un`&Zkwwr6A8_ zdZ*3$>mr%{q$*$x1!)J1po$MlDW`SFA(iI>NT(>O(bw^qw51O0zS+gFPHpLJGc2?j zHvRkaB5VLB2dyVL49Xmk-hoLI-q^LA?QOP!rKz8f Nj%Rdln?e+f?v0ibs`|@Kl zRRG&vM5^)m6^Mn8id4-R&_=_czUkc#wHNu3q- f>y~l-w8=pq+9DGPpPyXAOwt_pbeVGu}-&=GcXJjXi0m+u=_`_ zawq+kV-8dpz`!rzCii!)GfeEL(_~3yysNW5ATScgQ_9RqtGEgQIRwlu`1OD*pewQg zZU~zzlNizO`T$uQl45ngs0hJc|MX_LSN Rr1L{%`ub z@4Gc8?+RS*&D8(QewP6IF4hlrwJ%`8woDOiEQ+U;DhtTaLKX3iG+gW}|L>N6OFH;E zN~wPhOjx|+M+A{iXL3lHfFA&W{{X%Pvc^G1_BZHgYaCF0#zXM`Yg~bX=iUE^D|lp@ z0a}AqbIrko<3IBX%#@CgfYlzz8vtBpHy)ZQ`q}i4yaMW~$6@7n+GUwPolQ7kkzWaE zR038Z#WIXQV%AshYSafeT<0;XWder#*cA%LNl<@}0eGB!e=j~ahM+HC{Iz1S&oxi5 zOvlC>NHkZxHXV6dOt(QHxUhB=`aa{!Sm=3+8~;Di*SRWzT8vp`m#IhB;>)ExIIHo_ zLR@f0G%RXxK@Ix9f!E&sz(^0Il1?`Zd1gke#p~*Fop0q&yWtkN*3Oix3d_gd+o_zk zOKF5`%l4$(4!vPuUrOFbQdr`fmE;DTtllU<2T|voP7KZBAe~e> YnGHq`d zj}X;Zj>(x(F WQA4o^h$r?6Qg5}0z@2z`S+v+vQ>o_I{C`w4u;Dy7g7A5;f|Dl2f z{(j?xf9#oQZ>HZ* y@K)E%leGdMU4Y954fEO z7#Zh)U4Nl{skzU`)07ObwwBzL`~%Kmi>ju_blDo-^p))m`mron$eM&{r<}OI*tC8+ z;|e|psH8ggb#=ZK-v+EG80z#K`l-FTlL=SYlC1u0zrfS|KAuBl&I8O6pSytF-Q;XR zY=5KPA81|ofZFRcZrR4P!)I)z=yM#d`+)2Ry5!`UCobJTcyNWM+l_(6cijy}oDpP+ zf8&J5$IZyF9$N+wv6H* f#4z}K~27rH(%Zd zbOmt#2*he2Wz9|HaG^bdK9ZYT6;>jAg9@Rnkt-R`1Rnc<#p{pW7V{fYg>7P4xYuAx z{XSlLlmyfpH-5X&b8}=r{fBO&BQ&Fp7dST;)nsts0$Jf@hj}TX;1)%@8Z8`nD%2aB z>l#@0ZjTtEdO^!3lJ;*R{NdG!(0>x)%e@tLU%BnXm4d?O;N@LYVZa1UT>R97=PJlB zu%UxdyiYi&z$Rhc`&R&im^?Z?cbGx29P4N8!c(tPpaXE{j|P`piqDGVy*~vjC%&ap ztk&N3n `X@KPy{u8t!}$8b)wbE=_2apeb^@SUJzJH9e#0l?F^!qkL?DFc zoE{J%xZ8IzjG~b6I>;CJ-5GA65qbxZb+t+SUVq2eOG*1Y^cf}7srpyeg<7w(=*EG5 z2TC1vPL>TlEYesztnbaPA0;+5W38Cc1*XCk*pv$@I|K2Uv-{)d#&l~*g-QpY*1dL| z5aPINCatlrxyhqVtyWOYvuI z&&HaTTxawQ@Ul+YEgS3<4xAL9g^C|J_xBBB+32o99ZS#Ra&M3d!P$Xz?-=x(81W{J zH-S0 -y&_{kU8`SW9?Uhi8^mpAgq{v)BuTb#OEQqEmFe3RM|* zz{Ps)(Rm+^X)50X##s7o$1LrJ$6yXpOz>9o(Df-1arzbFYX(x_MBpUwpk~}YQ{NF& zPSu#yYXOD+(|27>!+G9-YQ<1%UwZ)IB8`?2mj6saND%ps=-qSkW{@?jf+179iz6>3 zp}* 9wm5n~->~n@-`yPO;H#UTc-}(T;2l)PX_&_B@M4+40%Q% zfWWBr2pEQVE&l~aZ@78f2Se!}83`;oT0~tkUG6itaPf+%6y$yw@IPs-IgsrV`)t}o zhmW`HV<9C)aS+^L)$QW-?akxOoEdwoYZ@XB_<@zr(*<=6TrogG$!$$bBD?dqs{HIG zm)L?m9`quO?TgMO$O2eAL6$J>9v$7EWW^+4J-ibi#zZ!NrtuS8a~9Z~&0|9m0{p61 z7AGN4i3-|lcDMyoReR0OVLaoPfn^z6r3OgjU82?_++G(w3-OvC;K8l?FZnxb*vVbG zT UuV(Vur aEJcN$54l)aL{bF^I~@gB!O{(X=6jc7)hWCF^I3uk zn#w0JkaWm{L~34#j+HHPh*ME(2UB=aj668z%Mii@8!G}|7s_EG4kT4zn>51#3rxu_ zBKkfxa&hE)D?5gC)7BvgljdEV3NX_p09vB=gyJCbX&MOR8r9|IJePlKpFH7fz+1|V z0d#c!2I>cOkZ`>m^@A9GAcx0_r~iG&l(k@7&z{Y8;T;|LJ2`uUEN%8*0SmbQJz&8d zk5wOj@uK`jHWJ7EbVMcJ|J{MXh0tf4+Rgic4=!p>0@6AQTiELBv;;#y8q|M@SI|dR zodg^QZ2lYA=IjknUqKKcvo?VL0?a~(9Yq!0T#JL9It|%&HT<{C{PiyOsd^oGr70 z0j+{7?hS!?W0oEgH=dcIpeJG*zw;Dy?_gE4E+42+ >t?pEged_SS=Y}VC1Iz z2twU>y+vYl=h;~$QrcZ|_GjgaN#eL%d&^m3uxxkj)s@hf;xEV3Xw*_4LVI%#agdyK zZ9<@T^m4x;y~9?ml^%d2NbY$|o=ICkKmqd{^m)hb7<^e#a=DolKyNf>iS$r{`BAPQ zo^x-HL0DrwnXD@vfbK}ZL0`a8sTquQEF)vbk=4rgQ~o>@=u$>3I6M(+)R(n`Y}?#r zPaA$nQvTXVesUSfI9z#SS6$IcVv&5cOx2M4>C3!-*t;k%*j*m0DWo>^hj-`4)&c0- zc^z3_3BCr&B6-KRz<~RIB%Mc1l~&dJN=`W kU299 zvV5}*(yAVN#~z^6o>yOI`Onb|u^@7&w2pQjwC|Km#Qt?-9!%_Xr%W^K;BGT!n+J2H zga7}-$IE}@BUsR3)iwhRFkHnvJ0!I%oyn4<@2G*WNAzHI4)hxc(96&lwg#P_B`0e` zUHo@&xM2|RUPD+t= g{2IKno*sZ5+TDwOcU&tN?t*g2~Jj zF9JkMQQ~#q`R}Ow^GrQkwGD^^(D!(#nXvT`cQ$_TMZk{Km1=w?e}p1oV6*Iu@%}V8 zngj<%;KUsG5qW}ungZz1Lf2{Xn!6JU66w=u$;rc;VHT5w-2QT00csaQL}$+chsO=J zrjKm2>E4nFK;TaSp<{1`45MJWJAv!7KZkhQql)J)inEO+UHLeDNH*;;AR5sM7@>e3 z2C@VckR_WA0hzewAJkb7E|?^^F$TNSQGf$(BmRv|pajq{0Ls>3CE&$)Zodr(S`@#G zI&i<4gbQ7EEOc_Fgg+r$J}wo ZJ95@{^G(KpPv4xVWYMs~|<=7mJKPBcaW=R{)pmA!``fo{0dD zODEh(E%n3s;|{RJX0K8`Tm%1z4g$(w+PA<~z#|5HKve7hg!l(I_Z+4O`AL4MalQTa z?VR6#QwYSEF3lw$5QVJ%blk%@?Rs0KH&$H^J2wm0y{O`zZnV3Vq>S51QM?h&Ih4J} zX5ST^^gKsFizrv)nW0MXD6vgS$$)(=2MBMexx=DX@GPSK^G`cMs;h6<^&Xe%N>X^s z&y+XH3kXdp-P{TH7L#N8_PVb{b-}+u=Jcb7-}b!-Ow+*XEw<~kyU2N;9cj$)*A^)m zzYU#e(l`4f3sj;34fK^EPv0TO3lYK+Z-;<}YeOA{|NNq4(kvFe@21k^NYs0J%Tc6q zmoE!l%9pKImfM{zETeEChTtXk+lf5oo+tYf;$4G;{UY0y4Z7oGO@WzWJhMTw^2H4G z?!p2Ewv4ahe4|ss48?j`zcbz1+~ t0uJ2#@T9_vauyepi%PQkNR?WNw(8o{oD+ zdkRXtMeh!AAlEQa6~h=(?2mR;;NyofHD2mcAD%0OaR+5qFt;6JaAKXvew~_?w;9tS z+Q&U6t=94oT}opb%)K|7OHsilS2Qp~?lPB-Hl*+YJtfRyx|!;^+2BG)B3VUSNGfO9 z6JzP~3cd_*Ns(H9Ew *x8)_l&Cw1+u66I?M=xt W0!kOe~D sPv& zuMO``p-pqI+Gl>5jJE$xVr9<_rn9fbTmvP|PRY8M}_5%QpU% z+(H=sOY_F_qN^HTd|bmyaaX8uTUo=(x`>0?XzPvQj&{0+OfxgX-XVHZWr}V-7i>LP z>-hZ2==tlq`<&~_ohd!<#j4J><3gaV7+FzzJWjS+X_4J;)mEk>l2?5%de@xKgTJFe zT1(}Ggqt(XH#2{N-4<`Xel7+gnY&7gRzKIyqN^+j2!8+dei9+NxV88zGV{U8Us>3i zzacS7+~!axR{Z&i)0g*(m`11DCBfsV(vFLNqq-`OXK!z8&VSXo?K{&{Ljj-v_Ckmv zutVvFR>dp5&DB#*l}C&ukoIg=S93y6 }Mf5S6HMs__y6FDvBt7j$U)7BKk-_oMY=m3}&&>!@!FO zz15Kie;MBIi|~umE0sB^lp}YZ+Kfub2xTU=?0ZUZ^xTg&+fEthGH?+;PYjk6r8f~o z^;>*Bs_3`g?~NXwE`5V% zBK5ItorJmf(kqS@Qm)`=ks8um?2dg8hp7A}4^OgiApZs*wHD1qSCYe`<6$xYe@}_i zUUu@UA|EG{q;(iR{4U^e8DRMyOwcH!rHQaubOr*(l`9)VQXGwz5=mMp+P#yE7V&^N zX9cWDu$&yjS4EubS@#Q;hjI7R2Aytp<9YH&3I#x ^auMGEG%Y5XLKGEFoui0}czC=50b9cn> zA^am#7g}?Mijq7y`q6x4FRMa*Rn-^;mmw}wp>Uq!wrjZu(Wn#?4}bZj181}e@#r?J zlN=|W&{J#I4xTr9TjQiCP>xQ$MV~N){E;%3N}lZHwS6}NX`fzi4GTA}EuPig@F$-S zbE*m7_?}8dTV$E=&Ij?E?)F-lYxxd8P|$Cb(KhU%+;$CT)9t)RWTIoLA@V|m?bO%e zqidIbK|niRBkrT;MuBKyTD `sXkJxzOfhHY1D59tw+5O<@%Ou;c?FdKtUlHFF zswrpWa(+`B`bb_Fl|6bj$Sf!SMdZ03(tacf4~FmWwHW8aMQ%14_P` $mc*tx@+~zC;8pw88H!t#yJn7;6X* zKpd%jX+vd8uw{R<`Kon?j_L5O$5o>HEgy)4X? 2s_m53_gQ#lM M`h~K5DIQH4Juj~;faEQx@T+V$4?-jyPe05me zQ19och_I;pz(yObZ|2$cgRkxnf0G4$gTd|fX@AX~&8a_tX_lZ-ZPjr($1@#JpdxKo z;i|Gi#-y8Orhp65MAjd*TCrh6RJ^p-X7-k*3{L1sk2|8@b (Y9;&tV|2W$gVZW>$enXLzeO)eE=-riGA1J bi9(glH_+q+m7E#nFQVM`M|c(+F-%l4fqr_|9f53R4@-QZ8~20rF& zNAy{3ZTRsZ6xb1?m_4O3MzZB%Ux8hvK&?IoEg%}=*L-+pGxy~M0!0*^0dgM2oI1Gp z0WhAG)e@KGyU7RzPRXFJ`^1{GuDGJU-)I&gOFOM|f0A?ZB4@*Wq3!Z{%y^6bQ*Yfp zyq{03?QI_296%(D2n4iSu2=jCN ~$z}&BoBiKU$rDLRsHu`-OjB2#swiVT+chEO`sX z_v4Pk+!zyLgy+iL{hd++7`$6b`;EAy&syQzAuja~{#*V?`lh3L%nMmr2shqqT7~b; zgNMajH+7lPtw@PwUQk=#p<8Mn6meQm;pD#kCUo87=`60*&$nPjT3NK~KqpJ8Rv(tu zCHMtF4^|l#%i8dH;-q6MgwQFy%G-8Na}6)^DtBv|iceW_H?L;}RA7=zVm?!O3eebg zD=< g3YA{HR1=Zb2ap sd@U$vtf2TS zit&}8dZXAPyo5hLd-Pj{X;<%5R(B=`ZAlu#1N8U)wR7k5PCX9Gv*#YcER) zlU2k3p`%1%z>&8EOz=%mJ8HJEOoap%i2-Zv7hW7uPO?ZT|MQP=`A(95`Z?+l^t%Io z!I|wMrx(l}imq8X7pPm1HPgVulxfAoS!0`~m>qm!QTikq-{eteS~gmOuxlI~g8}y+ z;^mx_MYDiEs`R7U`3aL6N85S@jomdA1>DN|Jgi7}#id}W7$4;z7y|keXzP>yG@7>8 z6J8Q;eNrY3Jshu(($4puZM-d(A3l~3M$1t2TBO98GeS%&bL0lxZBh&Lgi-bBD!z}P zfcJbaC>gp$qE4@W{bD{!gzxIE&@@L!Bz)g@r@@CibLiKAr^bTfV5l9H!nW&KwYenr z3Y8-B#->n&!!lt%+xRZGYlJD*XdsvN1pGg!^$zI!OT8tv)7#EYGFl*U41kH=B zkvqz8G1@9-DE*WPQ(i<_^}g$S0lB8_^5Wb}uZC@BdPTJl*a7>D_&IkynWl&%)ekpE z4UG1qC$<#A7h;Ab*~K?erH-(@w+4rE;tlv(eOdkLJTACI0qKUUj?ZC?^GV4qm!3xC z?h8$19JX1jdHw#dUn5sQk-hQA`3{>!7{!~93PmRbzl&?r%idiaR$Yd!_cVE>`!T$? z!c%kL^_8aknv_At%zCBP_G#)hwUz*vmu~46kdWtYAMIJkMI6o rnVnJc5(;PsrrM^EIAzM6j+`ctUwxxF;JKhu+iYga~K z*n7kEb4pyq!%gt0*1RQxz|(b>-j dC1bPKkJK_hmw z
-l<41;g)VKo)dswpSgK}5W$I9o=-}IpS0=ybn6^0c#9m3>E( T*xkkI?|VQt|4%lklGG zNAk8@31slpS+J2s2RKn0+xdf@Up|a=AE0uF-*z{X8=&1KW&i_*^c24<9mRM%q4ow^ z |g-kryOMG~Pgh0dOJv%!JI>vhBs#5vK7%G&N4IN~=1q4j7X&_svb4_oTk zel&TR33{6n%8?H!ym&pWzMBg#IZ#Kfy9r^pX?r}-^5z&p{q;l{)9)vvD?9hws- !p 4 J2$bN zAp*NSrpne6b1fJ^%$bbJYB;DdgMHJeQCu?GQKa?rFxV1>qy!34OZ<>|JILbL9aQhX zR0&Y=lSVc%LZWEw5I;MCG?Y1LP`t-imeoq@Ny6Vru(wEA`U%ZsidMdle-sj3Bvf^a z^rje8XDheuq%7@TOh#Iu*fUQ5RfAz(_}yR4VZB&%jgz>J(+yA|ookS!_0oJ|+YT%N zu}pU;q8}~p?X?pL;`XN0b<@_ou2Hf+H<0?6&>pm-xkC_K9$Y?S#U{mHEqFIGyR=)c zlvez&5PD#Rjt0d^mJQpvM{cqWsS2kLYI@NyP&OALZ;NO)df{h05faXl@V?^^7zN30 zDm)8qV$k>C!_C6Yq|14aOexv9u?lvGWyU6 Zdx?!YsTIXptD$UK1Kj!Tv3>)}8d6TyuOwUG;wBE0p0BGf!C0sm4}vrx9&` zWL_kv#-ChM4XX)aTo~?%unbau#LQKG@baWqLPPCOOipZ$fS>b^YR&a&xP2WiOJaF! z&YTo|Aob%J+;9=r)ht_FY5r ^JEJHZNXQm2$6Iv3#zQ` 0XT>zgA9fgCb(;64nq5#;0!JVa zR6+3T_|5RLr!F@~7nAgsL 8p8QCg~RTu1Sdm0 z!p&z^)U`K_x!N+a?;-^bq4EG6ZPHRcen5M8y`->n_bS!57Q68uM&y6#WHEm8&z)Mw zd{SHo!xz(U%PkngzYOlHtv}%{ZqN9mboqo=nmBni?E^2ZXMU*Gms*M^k4+9&^h;*; zu6!YrXK#@!@?RfoqwT|Sa3e4jFQYo2dV! O(Ip8?%Sy(1hQGg)GhvN3$ z^^8{;js2Jqb#;Fk8mH7o!e~kAg-*NLV~#4m z(w9-<%w1Jl&xWi$w2noF2}%lQv7|GPNjg7tT|t#vOKSdc3}vyrI$r_NEwcb`RRw57 z$msa={TTaux_z*=TJ~8^T;XioSmo|H3+nrTS*K+Ae%kP)KS1;9feUX)MTNH8($ULM z=vT1~EH6D3!*leC1hvTy6|;t4o*%WEz(+W5v83=_gqRr*+U8G5c*uX6!rMv9L3qif zgb3>%tY9y?yxFawY_TQdL}^%&x}FC&Q|#j%%XHt*4Zh`O7wJ8dPSxlB`?pW7f6Z>z zXucbm+fnMy)nmRc765h~%Nfus_#J Date: Mon, 22 Jan 2024 19:49:30 +0000 Subject: [PATCH 05/17] More stuff --- code/__DEFINES/mobs.dm | 42 ------------------- code/__DEFINES/xeno.dm | 42 +++++++++++++++++++ .../carbon/xenomorph/castes/Hellhound.dm | 1 - .../living/carbon/xenomorph/castes/Larva.dm | 1 - .../carbon/xenomorph/castes/Predalien.dm | 2 - .../living/carbon/xenomorph/castes/Queen.dm | 2 - .../carbon/xenomorph/castes/Sentinel.dm | 1 - .../living/carbon/xenomorph/castes/Spitter.dm | 1 - .../living/carbon/xenomorph/castes/Warrior.dm | 1 - .../carbon/xenomorph/castes/lesser_drone.dm | 2 - .../living/carbon/xenomorph/update_icons.dm | 4 +- 11 files changed, 44 insertions(+), 55 deletions(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index e67fa1b21845..5e35411d3b20 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -306,48 +306,6 @@ #define CAN_HOLD_TWO_HANDS 1 #define CAN_HOLD_ONE_HAND 2 -// ------------ // -// STRAIN FLAGS // -// ------------ // - -// Facehugger strain flags -#define FACEHUGGER_WATCHER "Watcher" - -// Drone strain flags -#define DRONE_HEALER "Healer" -#define DRONE_GARDENER "Gardener" - -// Hivelord strain flags -#define HIVELORD_RESIN_WHISPERER "Resin Whisperer" - -// Carrier strain flags -#define CARRIER_EGGSAC "Eggsac" - -// Boiler strain flags -#define BOILER_TRAPPER "Trapper" - -// Runner strain flags -#define RUNNER_ACIDER "Acider" - -// Lurker strain flags -#define LURKER_VAMPIRE "Vampire" - -// Ravager strain flags -#define RAVAGER_HEDGEHOG "Hedgehog" -#define RAVAGER_BERSERKER "Berserker" - -// Defender strain flags -#define DEFENDER_STEELCREST "Steelcrest" - -// Crusher strain flags -#define CRUSHER_CHARGER "Charger" - -// Praetorian strain flags -#define PRAETORIAN_VANGUARD "Vanguard" -#define PRAETORIAN_DANCER "Dancer" -#define PRAETORIAN_WARDEN "Warden" -#define PRAETORIAN_OPPRESSOR"Oppressor" - GLOBAL_LIST_INIT(default_onmob_icons, list( WEAR_L_HAND = 'icons/mob/humans/onmob/items_lefthand_0.dmi', WEAR_R_HAND = 'icons/mob/humans/onmob/items_righthand_0.dmi', diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index e3a35d0c4744..33aa3d5fbc64 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -361,6 +361,48 @@ #define RESIN_CONSTRUCTION_NO_MAX -1 +// -------------- // +// STRAIN DEFINES // +// -------------- // + +// Facehugger strain flags +#define FACEHUGGER_WATCHER "Watcher" + +// Drone strain flags +#define DRONE_HEALER "Healer" +#define DRONE_GARDENER "Gardener" + +// Hivelord strain flags +#define HIVELORD_RESIN_WHISPERER "Resin Whisperer" + +// Carrier strain flags +#define CARRIER_EGGSAC "Eggsac" + +// Boiler strain flags +#define BOILER_TRAPPER "Trapper" + +// Runner strain flags +#define RUNNER_ACIDER "Acider" + +// Lurker strain flags +#define LURKER_VAMPIRE "Vampire" + +// Ravager strain flags +#define RAVAGER_HEDGEHOG "Hedgehog" +#define RAVAGER_BERSERKER "Berserker" + +// Defender strain flags +#define DEFENDER_STEELCREST "Steelcrest" + +// Crusher strain flags +#define CRUSHER_CHARGER "Charger" + +// Praetorian strain flags +#define PRAETORIAN_VANGUARD "Vanguard" +#define PRAETORIAN_DANCER "Dancer" +#define PRAETORIAN_WARDEN "Warden" +#define PRAETORIAN_OPPRESSOR "Oppressor" + ///////////////////////////////////////////////////////////////////////////////////// // // Modifiers diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm b/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm index 6868fd5ac589..93d40820bf7b 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm @@ -64,7 +64,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - mutation_type = HELLHOUND_NORMAL icon_xeno = 'icons/mob/xenos/hellhound.dmi' icon_xenonid = 'icons/mob/xenos/hellhound.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm b/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm index f1c77e7fb757..c06b8c43839d 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm @@ -46,7 +46,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - mutation_type = "Normal" var/burrowable = TRUE //Can it be safely burrowed if it has no player? var/state_override diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm index bcf47386fefc..ebae6f56830f 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm @@ -63,8 +63,6 @@ /datum/action/xeno_action/onclick/tacmap, ) - mutation_type = "Normal" - weed_food_icon = 'icons/mob/xenos/weeds_64x64.dmi' weed_food_states = list("Predalien_1","Predalien_2","Predalien_3") weed_food_states_flipped = list("Predalien_1","Predalien_2","Predalien_3") diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm index f847c1a4ac8a..db2a9b4a38de 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm @@ -350,8 +350,6 @@ /datum/action/xeno_action/activable/xeno_spit/queen_macro, //third macro /datum/action/xeno_action/onclick/shift_spits, //second macro ) - mutation_icon_state = QUEEN_NORMAL - mutation_type = QUEEN_NORMAL claw_type = CLAW_TYPE_VERY_SHARP var/queen_aged = FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm index a568a093b3a4..2e53f97e297b 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm @@ -53,7 +53,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - mutation_type = SENTINEL_NORMAL icon_xeno = 'icons/mob/xenos/sentinel.dmi' icon_xenonid = 'icons/mob/xenonids/sentinel.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Spitter.dm b/code/modules/mob/living/carbon/xenomorph/castes/Spitter.dm index 9ad2f4909fb8..984a2d08bb75 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Spitter.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Spitter.dm @@ -56,7 +56,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - mutation_type = SPITTER_NORMAL icon_xeno = 'icons/mob/xenos/spitter.dmi' icon_xenonid = 'icons/mob/xenonids/spitter.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm b/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm index b19978a33766..1c329c8b9e82 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm @@ -55,7 +55,6 @@ /datum/action/xeno_action/onclick/tacmap, ) - mutation_type = WARRIOR_NORMAL claw_type = CLAW_TYPE_SHARP icon_xeno = 'icons/mob/xenos/warrior.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm index f050a0dcfe8a..de239aa72e5c 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm @@ -74,8 +74,6 @@ /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, ) - mutation_type = DRONE_NORMAL - icon_xeno = 'icons/mob/xenos/lesser_drone.dmi' icon_xenonid = 'icons/mob/xenonids/lesser_drone.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/update_icons.dm b/code/modules/mob/living/carbon/xenomorph/update_icons.dm index ebf7566c0131..571f261ab981 100644 --- a/code/modules/mob/living/carbon/xenomorph/update_icons.dm +++ b/code/modules/mob/living/carbon/xenomorph/update_icons.dm @@ -41,7 +41,7 @@ Q.queen_standing_icon = icon_xeno Q.queen_ovipositor_icon = 'icons/mob/xenos/ovipositor.dmi' - var/mutation_caste_state = "[strain?.xeno_icon_state] [caste.caste_type]" + var/mutation_caste_state = "[get_strain_icon()] [caste.caste_type]" if(!walking_state_cache[mutation_caste_state]) var/cache_walking_state = FALSE for(var/state in icon_states(icon)) @@ -64,7 +64,7 @@ if(behavior_delegate?.on_update_icons()) return - var/mutation_caste_state = "[strain?.xeno_icon_state] [caste.caste_type]" + var/mutation_caste_state = "[get_strain_icon()] [caste.caste_type]" if(stat == DEAD) icon_state = "[mutation_caste_state] Dead" if(!(icon_state in icon_states(icon_xeno))) From e75a626f05dffa299e4aa9d81950a387ddbe276d Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Mon, 22 Jan 2024 23:58:23 +0000 Subject: [PATCH 06/17] `available_strains` to caste It makes more sense there really --- .../modules/mob/living/carbon/xenomorph/Xenomorph.dm | 3 --- .../mob/living/carbon/xenomorph/castes/Boiler.dm | 2 +- .../mob/living/carbon/xenomorph/castes/Carrier.dm | 3 ++- .../mob/living/carbon/xenomorph/castes/Crusher.dm | 2 +- .../mob/living/carbon/xenomorph/castes/Defender.dm | 3 +-- .../mob/living/carbon/xenomorph/castes/Drone.dm | 9 +++++---- .../mob/living/carbon/xenomorph/castes/Facehugger.dm | 3 ++- .../mob/living/carbon/xenomorph/castes/Hivelord.dm | 4 ++-- .../mob/living/carbon/xenomorph/castes/Lurker.dm | 2 +- .../mob/living/carbon/xenomorph/castes/Praetorian.dm | 12 ++++++------ .../mob/living/carbon/xenomorph/castes/Ravager.dm | 8 ++++---- .../mob/living/carbon/xenomorph/castes/Runner.dm | 3 ++- .../living/carbon/xenomorph/castes/caste_datum.dm | 3 +++ .../living/carbon/xenomorph/strains/xeno_strain.dm | 2 +- 14 files changed, 31 insertions(+), 28 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index 5245230c20e7..cb1704c8be5b 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -130,9 +130,6 @@ var/weed_level = WEED_LEVEL_STANDARD var/acid_level = 0 - // Strain-related vars - /// A list of strain typepaths that the xeno is able to choose. - var/list/available_strains = list() /// The xeno's strain, if they've taken one. var/datum/xeno_strain/strain = null diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm index 02c48ae3d6dd..f7e906a82b28 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm @@ -13,6 +13,7 @@ evasion = XENO_EVASION_NONE speed = XENO_SPEED_TIER_3 + available_strains = list(/datum/xeno_strain/trapper) behavior_delegate_type = /datum/behavior_delegate/boiler_base evolution_allowed = FALSE @@ -53,7 +54,6 @@ spit_delay = 30 SECONDS tileoffset = 3 viewsize = 7 - available_strains = list(/datum/xeno_strain/trapper) icon_xeno = 'icons/mob/xenos/boiler.dmi' icon_xenonid = 'icons/mob/xenonids/boiler.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm index 713b66bfa5c1..c800f129e3ff 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm @@ -14,6 +14,8 @@ evasion = XENO_EVASION_NONE speed = XENO_SPEED_TIER_4 + available_strains = list(/datum/xeno_strain/eggsac) + evolution_allowed = FALSE deevolves_to = list(XENO_CASTE_DRONE) throwspeed = SPEED_AVERAGE @@ -75,7 +77,6 @@ /mob/living/carbon/xenomorph/proc/rename_tunnel, /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, ) - available_strains = list(/datum/xeno_strain/eggsac) icon_xenonid = 'icons/mob/xenonids/carrier.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm index b48de1b34d54..f7d986570f9f 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm @@ -14,6 +14,7 @@ speed = XENO_SPEED_TIER_2 heal_standing = 0.66 + available_strains = list(/datum/xeno_strain/charger) behavior_delegate_type = /datum/behavior_delegate/crusher_base minimum_evolve_time = 15 MINUTES @@ -63,7 +64,6 @@ ) claw_type = CLAW_TYPE_VERY_SHARP - available_strains = list(/datum/xeno_strain/charger) icon_xeno = 'icons/mob/xenos/crusher.dmi' icon_xenonid = 'icons/mob/xenonids/crusher.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm b/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm index 18a7f2aeab65..23ba08e294ba 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm @@ -18,6 +18,7 @@ deevolves_to = list("Larva") can_vent_crawl = 0 + available_strains = list(/datum/xeno_strain/steel_crest) behavior_delegate_type = /datum/behavior_delegate/defender_base tackle_min = 2 @@ -51,8 +52,6 @@ /datum/action/xeno_action/onclick/tacmap, ) - available_strains = list(/datum/xeno_strain/steel_crest) - icon_xeno = 'icons/mob/xenos/defender.dmi' icon_xenonid = 'icons/mob/xenonids/defender.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm index 5c476e4a4067..a0ce70316eb8 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm @@ -12,6 +12,11 @@ evasion = XENO_EVASION_MEDIUM speed = XENO_SPEED_TIER_7 + available_strains = list( + /datum/xeno_strain/gardener, + /datum/xeno_strain/healer, + ) + build_time_mult = BUILD_TIME_MULT_BUILDER caste_desc = "A builder of hives. Only drones may evolve into Queens." @@ -69,10 +74,6 @@ /mob/living/carbon/xenomorph/proc/rename_tunnel, /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, ) - available_strains = list( - /datum/xeno_strain/gardener, - /datum/xeno_strain/healer, - ) icon_xeno = 'icons/mob/xenos/drone.dmi' icon_xenonid = 'icons/mob/xenonids/drone.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index 75de76737255..83c61358e49d 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -9,6 +9,8 @@ caste_desc = "Ewwww, that's disgusting!" speed = XENO_SPEED_TIER_8 + available_strains = list(/datum/xeno_strain/watcher) + evolution_allowed = FALSE can_be_revived = FALSE @@ -55,7 +57,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - available_strains = list(/datum/xeno_strain/watcher) icon_xeno = 'icons/mob/xenos/facehugger.dmi' icon_xenonid = 'icons/mob/xenonids/facehugger.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm b/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm index 766a3e571f8c..c821fbc49208 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm @@ -13,6 +13,8 @@ evasion = XENO_EVASION_NONE speed = XENO_SPEED_TIER_2 + available_strains = list(/datum/xeno_strain/resin_whisperer) + evolution_allowed = FALSE caste_desc = "A builder of really big hives." deevolves_to = list(XENO_CASTE_DRONE) @@ -76,8 +78,6 @@ /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, ) - available_strains = list(/datum/xeno_strain/resin_whisperer) - icon_xeno = 'icons/mob/xenos/hivelord.dmi' icon_xenonid = 'icons/mob/xenonids/hivelord.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm index df2589073f9c..b9bde4c78992 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm @@ -15,6 +15,7 @@ attack_delay = 2 // VERY high slash damage, but attacks relatively slowly + available_strains = list(/datum/xeno_strain/vampire) behavior_delegate_type = /datum/behavior_delegate/lurker_base deevolves_to = list(XENO_CASTE_RUNNER) @@ -50,7 +51,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - available_strains = list(/datum/xeno_strain/vampire) claw_type = CLAW_TYPE_SHARP tackle_min = 2 diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/Praetorian.dm index a4c105de1dd6..69b679573352 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Praetorian.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Praetorian.dm @@ -26,6 +26,12 @@ tackle_max = 5 tackle_chance = 45 + available_strains = list( + /datum/xeno_strain/dancer, + /datum/xeno_strain/oppressor, + /datum/xeno_strain/vanguard, + /datum/xeno_strain/warden, + ) behavior_delegate_type = /datum/behavior_delegate/praetorian_base minimum_evolve_time = 15 MINUTES @@ -46,12 +52,6 @@ mob_size = MOB_SIZE_BIG drag_delay = 6 //pulling a big dead xeno is hard tier = 3 - available_strains = list( - /datum/xeno_strain/dancer, - /datum/xeno_strain/oppressor, - /datum/xeno_strain/vanguard, - /datum/xeno_strain/warden, - ) base_actions = list( /datum/action/xeno_action/onclick/xeno_resting, diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm b/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm index d05f2e22f4f7..e50a0f026d65 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm @@ -26,6 +26,10 @@ fire_immunity = FIRE_IMMUNITY_NO_DAMAGE|FIRE_IMMUNITY_XENO_FRENZY attack_delay = -1 + available_strains = list( + /datum/xeno_strain/berserker, + /datum/xeno_strain/hedgehog, + ) behavior_delegate_type = /datum/behavior_delegate/ravager_base minimum_evolve_time = 15 MINUTES @@ -45,10 +49,6 @@ tier = 3 pixel_x = -16 old_x = -16 - available_strains = list( - /datum/xeno_strain/berserker, - /datum/xeno_strain/hedgehog, - ) claw_type = CLAW_TYPE_VERY_SHARP base_actions = list( diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm index 3026ee2ee9da..400195f21de0 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm @@ -13,6 +13,8 @@ evasion = XENO_EVASION_NONE speed = XENO_SPEED_RUNNER attack_delay = -4 + + available_strains = list(/datum/xeno_strain/acider) behavior_delegate_type = /datum/behavior_delegate/runner_base evolves_to = list(XENO_CASTE_LURKER) deevolves_to = list("Larva") @@ -62,7 +64,6 @@ inherent_verbs = list( /mob/living/carbon/xenomorph/proc/vent_crawl, ) - available_strains = list(/datum/xeno_strain/acider) icon_xeno = 'icons/mob/xenos/runner.dmi' icon_xenonid = 'icons/mob/xenonids/runner.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/caste_datum.dm b/code/modules/mob/living/carbon/xenomorph/castes/caste_datum.dm index cfaedf013a44..feee2edecb67 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/caste_datum.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/caste_datum.dm @@ -66,6 +66,9 @@ var/agility_speed_increase = 0 // this opens up possibilities for balancing + /// A list of strain typepaths that are able to be chosen by this caste. + var/list/available_strains = list() + // The type of mutator delegate to instantiate on the base caste. Will // be replaced when the Xeno chooses a strain. var/behavior_delegate_type = /datum/behavior_delegate diff --git a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm index fd43b23de993..57ba97050075 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm @@ -90,7 +90,7 @@ log_strain("[name] purchased strain '[strain_instance.type]'") /mob/living/carbon/xenomorph/proc/can_take_strain() - if(!length(available_strains) || !check_state(TRUE)) + if(!length(caste.available_strains) || !check_state(TRUE)) return FALSE if(is_ventcrawling) From f6d142c118caeb2d301af81d86da48fcdbc33d08 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Tue, 23 Jan 2024 13:32:28 +0000 Subject: [PATCH 07/17] Second pass (squashed commits) There's a lot of removed `mutation_type` checks in here, but as far as I can tell there's no way for other strains to access the ability in those cases. --- .../shield_types/vanguard_shield.dm | 7 +- .../abilities/crusher/crusher_powers.dm | 6 +- .../abilities/defender/defender_abilities.dm | 12 ++- .../abilities/defender/defender_powers.dm | 75 +++++++------ .../abilities/lurker/lurker_abilities.dm | 35 ------ .../abilities/lurker/lurker_powers.dm | 47 ++++++-- .../abilities/praetorian/praetorian_powers.dm | 82 ++++++-------- .../abilities/queen/queen_abilities.dm | 4 + .../abilities/ravager/ravager_powers.dm | 100 +++++++----------- .../abilities/runner/runner_powers.dm | 5 +- .../abilities/sentinel/sentinel_powers.dm | 6 -- .../living/carbon/xenomorph/castes/Carrier.dm | 23 ++-- .../living/carbon/xenomorph/castes/Crusher.dm | 2 +- .../carbon/xenomorph/castes/Defender.dm | 4 +- .../carbon/xenomorph/castes/Facehugger.dm | 35 +++--- .../carbon/xenomorph/castes/Hivelord.dm | 7 -- .../living/carbon/xenomorph/castes/Queen.dm | 4 +- .../strains/castes/carrier/eggsac.dm | 8 ++ .../strains/castes/defender/steel_crest.dm | 4 + .../xenomorph/strains/castes/drone/healer.dm | 11 +- .../strains/castes/facehugger/watcher.dm | 6 ++ .../castes/hivelord/resin_whisperer.dm | 15 +-- 22 files changed, 227 insertions(+), 271 deletions(-) diff --git a/code/datums/xeno_shields/shield_types/vanguard_shield.dm b/code/datums/xeno_shields/shield_types/vanguard_shield.dm index 5b9eebc04ab8..faf38e466e99 100644 --- a/code/datums/xeno_shields/shield_types/vanguard_shield.dm +++ b/code/datums/xeno_shields/shield_types/vanguard_shield.dm @@ -50,7 +50,6 @@ if (!istype(linked_xeno)) return - if (linked_xeno.mutation_type == PRAETORIAN_VANGUARD) - var/datum/behavior_delegate/praetorian_vanguard/BD = linked_xeno.behavior_delegate - if (istype(BD)) - BD.last_combat_time = world.time + var/datum/behavior_delegate/praetorian_vanguard/BD = linked_xeno.behavior_delegate + if (istype(BD)) + BD.last_combat_time = world.time diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm index 4ac166c58c69..e1af5e36a40f 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm @@ -37,7 +37,7 @@ RegisterSignal(owner, COMSIG_XENO_PRE_CALCULATE_ARMOURED_DAMAGE_PROJECTILE, PROC_REF(check_directional_armor)) var/mob/living/carbon/xenomorph/xeno_owner = owner - if(!istype(xeno_owner) || xeno_owner.mutation_type != CRUSHER_NORMAL) + if(!istype(xeno_owner)) return var/datum/behavior_delegate/crusher_base/crusher_delegate = xeno_owner.behavior_delegate @@ -51,7 +51,7 @@ ..() UnregisterSignal(owner, COMSIG_XENO_PRE_CALCULATE_ARMOURED_DAMAGE_PROJECTILE) var/mob/living/carbon/xenomorph/xeno_owner = owner - if(!istype(xeno_owner) || xeno_owner.mutation_type != CRUSHER_NORMAL) + if(!istype(xeno_owner)) return var/datum/behavior_delegate/crusher_base/crusher_delegate = xeno_owner.behavior_delegate @@ -62,7 +62,7 @@ /datum/action/xeno_action/activable/pounce/crusher_charge/proc/undo_charging_icon() var/mob/living/carbon/xenomorph/xeno_owner = owner - if(!istype(xeno_owner) || xeno_owner.mutation_type != CRUSHER_NORMAL) + if(!istype(xeno_owner)) return var/datum/behavior_delegate/crusher_base/crusher_delegate = xeno_owner.behavior_delegate diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_abilities.dm index 22d5f4b57aa2..d28a4bb67978 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_abilities.dm @@ -20,6 +20,13 @@ ability_primacy = XENO_PRIMARY_ACTION_2 xeno_cooldown = 4 SECONDS + var/base_damage = 30 + var/usable_while_fortified = FALSE + +/datum/action/xeno_action/activable/headbutt/steel_crest + base_damage = 37.5 + usable_while_fortified = TRUE + /datum/action/xeno_action/onclick/tail_sweep name = "Tail Sweep" action_icon_state = "tail_sweep" @@ -41,8 +48,9 @@ /// Extra armor when fortified and facing bullets. var/frontal_armor = 5 - /// Extra armor when steelcrest, fortified, and facing bullets. - var/steelcrest_frontal_armor = 15 + +/datum/action/xeno_action/activable/fortify/steel_crest + frontal_armor = 15 /datum/action/xeno_action/activable/tail_stab/slam name = "Tail Slam" diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm index bd01376c9f9d..610dbc4694ae 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm @@ -40,7 +40,7 @@ // Defender Headbutt /datum/action/xeno_action/activable/headbutt/use_ability(atom/target_atom) var/mob/living/carbon/xenomorph/fendy = owner - if (!istype(fendy)) + if(!istype(fendy)) return if(!isxeno_human(target_atom) || fendy.can_not_harm(target_atom)) @@ -49,13 +49,13 @@ if(!fendy.check_state()) return - if (!action_cooldown_check()) + if(!action_cooldown_check()) return if(!check_and_use_plasma_owner()) return - if(fendy.fortify && !(fendy.mutation_type == DEFENDER_STEELCREST)) + if(fendy.fortify && !usable_while_fortified) to_chat(fendy, SPAN_XENOWARNING("We cannot use headbutt while fortified.")) return @@ -81,11 +81,10 @@ fendy.visible_message(SPAN_XENOWARNING("[fendy] rams [carbone] with its armored crest!"), \ SPAN_XENOWARNING("We ram [carbone] with our armored crest!")) - if(carbone.stat != DEAD && (!(carbone.status_flags & XENO_HOST) || !HAS_TRAIT(carbone, TRAIT_NESTED)) ) - var/h_damage = 30 - (fendy.crest_defense * 10) - if(fendy.mutation_type == DEFENDER_STEELCREST) - h_damage += 7.5 - carbone.apply_armoured_damage(get_xeno_damage_slash(carbone, h_damage), ARMOR_MELEE, BRUTE, "chest", 5) + if(carbone.stat != DEAD && (!(carbone.status_flags & XENO_HOST) || !HAS_TRAIT(carbone, TRAIT_NESTED))) + // -10 damage if their crest is down. + var/damage = base_damage - (fendy.crest_defense * 10) + carbone.apply_armoured_damage(get_xeno_damage_slash(carbone, damage), ARMOR_MELEE, BRUTE, "chest", 5) var/facing = get_dir(fendy, carbone) var/headbutt_distance = 1 + (fendy.crest_defense * 2) + (fendy.fortify * 2) @@ -157,10 +156,6 @@ if (!istype(xeno)) return - if(xeno.crest_defense && xeno.mutation_type == DEFENDER_STEELCREST) - to_chat(src, SPAN_XENOWARNING("We cannot fortify while our crest is already down!")) - return - if(xeno.crest_defense) to_chat(src, SPAN_XENOWARNING("We cannot use fortify with our crest lowered.")) return @@ -205,49 +200,53 @@ if(fortify_state) to_chat(X, SPAN_XENOWARNING("We tuck ourself into a defensive stance.")) - if(X.mutation_type == DEFENDER_STEELCREST) - X.armor_deflection_buff += 10 - X.armor_explosive_buff += 60 - X.ability_speed_modifier += 3 - X.damage_modifier -= XENO_DAMAGE_MOD_SMALL - else - X.armor_deflection_buff += 30 - X.armor_explosive_buff += 60 - ADD_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Fortify")) - X.anchored = TRUE - X.small_explosives_stun = FALSE RegisterSignal(owner, COMSIG_XENO_PRE_CALCULATE_ARMOURED_DAMAGE_PROJECTILE, PROC_REF(check_directional_armor)) X.mob_size = MOB_SIZE_IMMOBILE //knockback immune X.mob_flags &= ~SQUEEZE_UNDER_VEHICLES - X.update_icons() X.fortify = TRUE else to_chat(X, SPAN_XENOWARNING("We resume our normal stance.")) REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Fortify")) X.anchored = FALSE - if(X.mutation_type == DEFENDER_STEELCREST) - X.armor_deflection_buff -= 10 - X.armor_explosive_buff -= 60 - X.ability_speed_modifier -= 3 - X.damage_modifier += XENO_DAMAGE_MOD_SMALL - else - X.armor_deflection_buff -= 30 - X.armor_explosive_buff -= 60 - X.small_explosives_stun = TRUE UnregisterSignal(owner, COMSIG_XENO_PRE_CALCULATE_ARMOURED_DAMAGE_PROJECTILE) X.mob_size = MOB_SIZE_XENO //no longer knockback immune X.mob_flags |= SQUEEZE_UNDER_VEHICLES - X.update_icons() X.fortify = FALSE + apply_modifiers(X, fortify_state) + X.update_icons() + +/datum/action/xeno_action/activable/fortify/proc/apply_modifiers(mob/living/carbon/xenomorph/X, fortify_state) + if(fortify_state) + X.armor_deflection_buff += 30 + X.armor_explosive_buff += 60 + ADD_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Fortify")) + X.anchored = TRUE + X.small_explosives_stun = FALSE + else + X.armor_deflection_buff -= 30 + X.armor_explosive_buff -= 60 + X.small_explosives_stun = TRUE + +// Steel crest override +/datum/action/xeno_action/activable/fortify/steel_crest/apply_modifiers(mob/living/carbon/xenomorph/X, fortify_state) + if(fortify_state) + X.armor_deflection_buff += 10 + X.armor_explosive_buff += 60 + X.ability_speed_modifier += 3 + X.damage_modifier -= XENO_DAMAGE_MOD_SMALL + else + X.armor_deflection_buff -= 10 + X.armor_explosive_buff -= 60 + X.ability_speed_modifier -= 3 + X.damage_modifier += XENO_DAMAGE_MOD_SMALL + /datum/action/xeno_action/activable/fortify/proc/check_directional_armor(mob/living/carbon/xenomorph/defendy, list/damagedata) SIGNAL_HANDLER var/projectile_direction = damagedata["direction"] + // If the defender is facing the projectile. if(defendy.dir & REVERSE_DIR(projectile_direction)) - if(defendy.mutation_type == DEFENDER_STEELCREST) - damagedata["armor"] += steelcrest_frontal_armor - else - damagedata["armor"] += frontal_armor + damagedata["armor"] += frontal_armor /datum/action/xeno_action/activable/fortify/proc/death_check() SIGNAL_HANDLER diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_abilities.dm index fd525701b12d..8a829d8d6bc0 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_abilities.dm @@ -6,46 +6,11 @@ plasma_cost = 20 // Config options - distance = 6 knockdown = FALSE knockdown_duration = 2.5 - freeze_self = TRUE freeze_time = 15 can_be_shield_blocked = TRUE -/datum/action/xeno_action/activable/pounce/lurker/additional_effects_always() - var/mob/living/carbon/xenomorph/xeno = owner - if (!istype(xeno)) - return - if (xeno.mutation_type == LURKER_NORMAL) - var/found = FALSE - for (var/mob/living/carbon/human/human in get_turf(xeno)) - if(human.stat == DEAD) - continue - found = TRUE - break - - if (found) - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis = get_xeno_action_by_type(xeno, /datum/action/xeno_action/onclick/lurker_invisibility) - if (istype(lurker_invis)) - lurker_invis.invisibility_off() - -/datum/action/xeno_action/activable/pounce/lurker/additional_effects(mob/living/living_mob) - var/mob/living/carbon/xenomorph/xeno = owner - if (!istype(xeno)) - return - - if (xeno.mutation_type == LURKER_NORMAL) - RegisterSignal(xeno, COMSIG_XENO_SLASH_ADDITIONAL_EFFECTS_SELF, PROC_REF(remove_freeze), TRUE) // Suppresses runtime ever we pounce again before slashing - -/datum/action/xeno_action/activable/pounce/lurker/proc/remove_freeze(mob/living/carbon/xenomorph/xeno) - SIGNAL_HANDLER - - var/datum/behavior_delegate/lurker_base/behaviour_del = xeno.behavior_delegate - if (istype(behaviour_del)) - UnregisterSignal(xeno, COMSIG_XENO_SLASH_ADDITIONAL_EFFECTS_SELF) - end_pounce_freeze() - /datum/action/xeno_action/onclick/lurker_invisibility name = "Turn Invisible" action_icon_state = "lurker_invisibility" diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm index 4ec301a17819..29ef331d723f 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm @@ -1,3 +1,35 @@ +/datum/action/xeno_action/activable/pounce/lurker/additional_effects_always() + var/mob/living/carbon/xenomorph/xeno = owner + if(!istype(xeno)) + return + + var/found = FALSE + for(var/mob/living/carbon/human/human in get_turf(xeno)) + if(human.stat == DEAD) + continue + found = TRUE + break + + if(found) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis = get_xeno_action_by_type(xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + if(istype(lurker_invis)) + lurker_invis.invisibility_off() + +/datum/action/xeno_action/activable/pounce/lurker/additional_effects(mob/living/living_mob) + var/mob/living/carbon/xenomorph/xeno = owner + if(!istype(xeno)) + return + + RegisterSignal(xeno, COMSIG_XENO_SLASH_ADDITIONAL_EFFECTS_SELF, PROC_REF(remove_freeze), TRUE) // Suppresses runtime ever we pounce again before slashing + +/datum/action/xeno_action/activable/pounce/lurker/proc/remove_freeze(mob/living/carbon/xenomorph/xeno) + SIGNAL_HANDLER + + var/datum/behavior_delegate/lurker_base/behaviour_del = xeno.behavior_delegate + if(istype(behaviour_del)) + UnregisterSignal(xeno, COMSIG_XENO_SLASH_ADDITIONAL_EFFECTS_SELF) + end_pounce_freeze() + /datum/action/xeno_action/onclick/lurker_invisibility/use_ability(atom/targeted_atom) var/mob/living/carbon/xenomorph/xeno = owner @@ -16,9 +48,8 @@ xeno.speed_modifier -= speed_buff xeno.recalculate_speed() - if (xeno.mutation_type == LURKER_NORMAL) - var/datum/behavior_delegate/lurker_base/behavior = xeno.behavior_delegate - behavior.on_invisibility() + var/datum/behavior_delegate/lurker_base/behavior = xeno.behavior_delegate + behavior.on_invisibility() // if we go off early, this also works fine. invis_timer_id = addtimer(CALLBACK(src, PROC_REF(invisibility_off)), duration, TIMER_STOPPABLE) @@ -45,10 +76,9 @@ xeno.speed_modifier += speed_buff xeno.recalculate_speed() - if (xeno.mutation_type == LURKER_NORMAL) - var/datum/behavior_delegate/lurker_base/behavior = xeno.behavior_delegate - if (istype(behavior)) - behavior.on_invisibility_off() + var/datum/behavior_delegate/lurker_base/behavior = xeno.behavior_delegate + if (istype(behavior)) + behavior.on_invisibility_off() /datum/action/xeno_action/onclick/lurker_invisibility/ability_cooldown_over() to_chat(owner, SPAN_XENOHIGHDANGER("We are ready to use our invisibility again!")) @@ -66,9 +96,6 @@ if (!check_and_use_plasma_owner()) return - if (xeno.mutation_type != LURKER_NORMAL) - return - var/datum/behavior_delegate/lurker_base/behavior = xeno.behavior_delegate if (istype(behavior)) behavior.next_slash_buffed = TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm index 2eaf332755dc..b0f5adcfdde3 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm @@ -70,10 +70,9 @@ playsound(current_mob, 'sound/weapons/alien_tail_attack.ogg', 30, TRUE) if (target_mobs.len >= shield_regen_threshold) - if (source_xeno.mutation_type == PRAETORIAN_VANGUARD) - var/datum/behavior_delegate/praetorian_vanguard/BD = source_xeno.behavior_delegate - if (istype(BD)) - BD.regen_shield() + var/datum/behavior_delegate/praetorian_vanguard/BD = source_xeno.behavior_delegate + if (istype(BD)) + BD.regen_shield() apply_cooldown() return ..() @@ -135,10 +134,9 @@ playsound(get_turf(H), "alien_claw_flesh", 30, 1) if (target_mobs.len >= shield_regen_threshold) - if (X.mutation_type == PRAETORIAN_VANGUARD) - var/datum/behavior_delegate/praetorian_vanguard/BD = X.behavior_delegate - if (istype(BD)) - BD.regen_shield() + var/datum/behavior_delegate/praetorian_vanguard/BD = X.behavior_delegate + if (istype(BD)) + BD.regen_shield() /datum/action/xeno_action/activable/cleave/use_ability(atom/target_atom) var/mob/living/carbon/xenomorph/vanguard_user = owner @@ -545,16 +543,12 @@ if (!check_and_use_plasma_owner()) return - var/buffed = FALSE apply_cooldown() - if (dancer_user.mutation_type == PRAETORIAN_DANCER) - var/found = FALSE - for (var/datum/effects/dancer_tag/dancer_tag_effect in target_carbon.effects_list) - found = TRUE - qdel(dancer_tag_effect) - break - - buffed = found + var/buffed = FALSE + for (var/datum/effects/dancer_tag/dancer_tag_effect in target_carbon.effects_list) + buffed = TRUE + qdel(dancer_tag_effect) + break if(ishuman(target_carbon)) var/mob/living/carbon/human/Hu = target_carbon @@ -601,9 +595,6 @@ if (!check_and_use_plasma_owner()) return - if (xeno.mutation_type != PRAETORIAN_DANCER) - return - var/datum/behavior_delegate/praetorian_dancer/behavior = xeno.behavior_delegate if (!istype(behavior)) return @@ -626,9 +617,6 @@ if (!istype(xeno)) return - if (xeno.mutation_type != PRAETORIAN_DANCER) - return - var/datum/behavior_delegate/praetorian_dancer/behavior = xeno.behavior_delegate if (!istype(behavior)) return @@ -806,17 +794,16 @@ var/bonus_shield = 0 - if (X.mutation_type == PRAETORIAN_WARDEN) - var/datum/behavior_delegate/praetorian_warden/BD = X.behavior_delegate - if (!istype(BD)) - return + var/datum/behavior_delegate/praetorian_warden/BD = X.behavior_delegate + if (!istype(BD)) + return - if (!BD.use_internal_hp_ability(shield_cost)) - return + if (!BD.use_internal_hp_ability(shield_cost)) + return - bonus_shield = BD.internal_hitpoints*0.5 - if (!BD.use_internal_hp_ability(bonus_shield)) - bonus_shield = 0 + bonus_shield = BD.internal_hitpoints*0.5 + if (!BD.use_internal_hp_ability(bonus_shield)) + bonus_shield = 0 var/total_shield_amount = shield_amount + bonus_shield @@ -841,7 +828,7 @@ if (!X.Adjacent(A)) to_chat(X, SPAN_XENODANGER("We must be within touching distance of [targetXeno]!")) return - if (targetXeno.mutation_type == PRAETORIAN_WARDEN) + if(istype(targetXeno.strain, /datum/xeno_strain/warden)) to_chat(X, SPAN_XENODANGER("We cannot heal a sister of the same strain!")) return if (SEND_SIGNAL(targetXeno, COMSIG_XENO_PRE_HEAL) & COMPONENT_CANCEL_XENO_HEAL) @@ -849,18 +836,16 @@ return var/bonus_heal = 0 + var/datum/behavior_delegate/praetorian_warden/BD = X.behavior_delegate + if (!istype(BD)) + return - if (X.mutation_type == PRAETORIAN_WARDEN) - var/datum/behavior_delegate/praetorian_warden/BD = X.behavior_delegate - if (!istype(BD)) - return - - if (!BD.use_internal_hp_ability(heal_cost)) - return + if (!BD.use_internal_hp_ability(heal_cost)) + return - bonus_heal = BD.internal_hitpoints*0.5 - if (!BD.use_internal_hp_ability(bonus_heal)) - bonus_heal = 0 + bonus_heal = BD.internal_hitpoints*0.5 + if (!BD.use_internal_hp_ability(bonus_heal)) + bonus_heal = 0 to_chat(X, SPAN_XENODANGER("We heal [targetXeno]!")) to_chat(targetXeno, SPAN_XENOHIGHDANGER("We are healed by [X]!")) @@ -876,13 +861,12 @@ to_chat(X, SPAN_XENOHIGHDANGER("We cannot rejuvenate targets through overwatch!")) return - if (X.mutation_type == PRAETORIAN_WARDEN) - var/datum/behavior_delegate/praetorian_warden/BD = X.behavior_delegate - if (!istype(BD)) - return + var/datum/behavior_delegate/praetorian_warden/BD = X.behavior_delegate + if (!istype(BD)) + return - if (!BD.use_internal_hp_ability(debuff_cost)) - return + if (!BD.use_internal_hp_ability(debuff_cost)) + return to_chat(X, SPAN_XENODANGER("We rejuvenate [targetXeno]!")) to_chat(targetXeno, SPAN_XENOHIGHDANGER("We are rejuvenated by [X]!")) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm index d245449fa2cf..307f28261d28 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_abilities.dm @@ -62,6 +62,10 @@ . = ..() SSticker.OnRoundstart(CALLBACK(src, PROC_REF(apply_queen_build_boost))) +// queenos don't need weeds under them to build +/datum/action/xeno_action/activable/secrete_resin/remote/queen/can_remote_build() + return TRUE + /datum/action/xeno_action/activable/secrete_resin/remote/queen/proc/apply_queen_build_boost() var/boost_duration = 30 MINUTES // In the event secrete_resin is given after round start diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm index daad0362e91e..8fe101a08dfa 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm @@ -6,9 +6,6 @@ if(!xeno.check_state()) return - if(xeno.mutation_type != RAVAGER_NORMAL) - return - if(!action_cooldown_check()) return @@ -122,8 +119,6 @@ var/mob/living/carbon/human/human = living var/mob/living/carbon/xenomorph/xeno = owner - if(xeno.mutation_type != RAVAGER_NORMAL) - return var/datum/behavior_delegate/ravager_base/behavior = xeno.behavior_delegate if(behavior.empower_targets < behavior.super_empower_threshold) return @@ -146,8 +141,6 @@ // Determine whether or not we should daze here var/should_sslow = FALSE - if(ravager_user.mutation_type != RAVAGER_NORMAL) - return var/datum/behavior_delegate/ravager_base/ravager_delegate = ravager_user.behavior_delegate if(ravager_delegate.empower_targets >= ravager_delegate.super_empower_threshold) should_sslow = TRUE @@ -302,17 +295,14 @@ if (carbon.stat == DEAD) return - // All strain-specific behavior - if (xeno.mutation_type == RAVAGER_BERSERKER) - var/datum/behavior_delegate/ravager_berserker/behavior = xeno.behavior_delegate - - if (behavior.rage >= 2) - behavior.decrement_rage() - heal_amount += additional_healing_enraged - else - to_chat(xeno, SPAN_XENOWARNING("Our rejuvenation was weaker without rage!")) - debilitate = FALSE - fling_distance-- + var/datum/behavior_delegate/ravager_berserker/behavior = xeno.behavior_delegate + if (behavior.rage >= 2) + behavior.decrement_rage() + heal_amount += additional_healing_enraged + else + to_chat(xeno, SPAN_XENOWARNING("Our rejuvenation was weaker without rage!")) + debilitate = FALSE + fling_distance-- // Damage var/obj/limb/head/head = carbon.get_limb("head") @@ -361,17 +351,16 @@ var/max_lifesteal = 250 var/lifesteal_range = 1 - if (xeno.mutation_type == RAVAGER_BERSERKER) - var/datum/behavior_delegate/ravager_berserker/behavior = xeno.behavior_delegate - if (behavior.rage == 0) - to_chat(xeno, SPAN_XENODANGER("We cannot eviscerate when we have 0 rage!")) - return - damage = damage_at_rage_levels[clamp(behavior.rage, 1, behavior.max_rage)] - range = range_at_rage_levels[clamp(behavior.rage, 1, behavior.max_rage)] - windup_reduction = windup_reduction_at_rage_levels[clamp(behavior.rage, 1, behavior.max_rage)] - behavior.decrement_rage(behavior.rage) + var/datum/behavior_delegate/ravager_berserker/behavior = xeno.behavior_delegate + if (behavior.rage == 0) + to_chat(xeno, SPAN_XENODANGER("We cannot eviscerate when we have 0 rage!")) + return + damage = damage_at_rage_levels[clamp(behavior.rage, 1, behavior.max_rage)] + range = range_at_rage_levels[clamp(behavior.rage, 1, behavior.max_rage)] + windup_reduction = windup_reduction_at_rage_levels[clamp(behavior.rage, 1, behavior.max_rage)] + behavior.decrement_rage(behavior.rage) - apply_cooldown() + apply_cooldown() if (range > 1) xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] begins digging in for a massive strike!"), SPAN_XENOHIGHDANGER("We begin digging in for a massive strike!")) @@ -439,12 +428,11 @@ if (!xeno.check_state()) return - if (xeno.mutation_type == RAVAGER_HEDGEHOG) - var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate - if (!behavior.check_shards(shard_cost)) - to_chat(xeno, SPAN_DANGER("Not enough shards! We need [shard_cost - behavior.shards] more!")) - return - behavior.use_shards(shard_cost) + var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate + if (!behavior.check_shards(shard_cost)) + to_chat(xeno, SPAN_DANGER("Not enough shards! We need [shard_cost - behavior.shards] more!")) + return + behavior.use_shards(shard_cost) xeno.visible_message(SPAN_XENODANGER("[xeno] ruffles its bone-shard quills, forming a defensive shell!"), SPAN_XENODANGER("We ruffle our bone-shard quills, forming a defensive shell!")) @@ -468,10 +456,8 @@ return FALSE else if (cooldown_timer_id == TIMER_ID_NULL) var/mob/living/carbon/xenomorph/xeno = owner - if (xeno.mutation_type == RAVAGER_HEDGEHOG) - var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate - return behavior.check_shards(shard_cost) - return TRUE + var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate + return behavior.check_shards(shard_cost) return FALSE /datum/action/xeno_action/onclick/spike_shield/proc/remove_shield() @@ -502,12 +488,11 @@ if(!affected_atom || affected_atom.layer >= FLY_LAYER || !isturf(xeno.loc) || !xeno.check_state()) return - if (xeno.mutation_type == RAVAGER_HEDGEHOG) - var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate - if (!behavior.check_shards(shard_cost)) - to_chat(xeno, SPAN_DANGER("Not enough shards! We need [shard_cost - behavior.shards] more!")) - return - behavior.use_shards(shard_cost) + var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate + if (!behavior.check_shards(shard_cost)) + to_chat(xeno, SPAN_DANGER("Not enough shards! We need [shard_cost - behavior.shards] more!")) + return + behavior.use_shards(shard_cost) xeno.visible_message(SPAN_XENOWARNING("[xeno] fires their spikes at [affected_atom]!"), SPAN_XENOWARNING("We fire our spikes at [affected_atom]!")) @@ -531,11 +516,8 @@ var/mob/living/carbon/xenomorph/xeno = owner if(!istype(xeno)) return FALSE - if (xeno.mutation_type == RAVAGER_HEDGEHOG) - var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate - return behavior.check_shards(shard_cost) - - return TRUE + var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate + return behavior.check_shards(shard_cost) else return FALSE @@ -548,13 +530,12 @@ if (!xeno.check_state()) return - if (xeno.mutation_type == RAVAGER_HEDGEHOG) - var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate - if (!behavior.check_shards(shard_cost)) - to_chat(xeno, SPAN_DANGER("Not enough shards! We need [shard_cost - behavior.shards] more!")) - return - behavior.use_shards(shard_cost) - behavior.lock_shards() + var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate + if (!behavior.check_shards(shard_cost)) + to_chat(xeno, SPAN_DANGER("Not enough shards! We need [shard_cost - behavior.shards] more!")) + return + behavior.use_shards(shard_cost) + behavior.lock_shards() xeno.visible_message(SPAN_XENOWARNING("[xeno] sheds their spikes, firing them in all directions!"), SPAN_XENOWARNING("We shed our spikes, firing them in all directions!!")) xeno.spin_circle() @@ -567,10 +548,7 @@ /datum/action/xeno_action/onclick/spike_shed/action_cooldown_check() if (cooldown_timer_id == TIMER_ID_NULL) var/mob/living/carbon/xenomorph/xeno = owner - if (xeno.mutation_type == RAVAGER_HEDGEHOG) - var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate - return behavior.check_shards(shard_cost) - - return TRUE + var/datum/behavior_delegate/ravager_hedgehog/behavior = xeno.behavior_delegate + return behavior.check_shards(shard_cost) else return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm index b907a382dda1..f5e090bc7e4b 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/runner/runner_powers.dm @@ -45,7 +45,7 @@ return ..() /mob/living/carbon/xenomorph/runner/corrosive_acid(atom/affected_atom, acid_type, plasma_cost) - if (mutation_type != RUNNER_ACIDER) + if(!istype(strain, /datum/xeno_strain/acider)) return ..() if(!affected_atom.Adjacent(src)) if(istype(affected_atom,/obj/item/explosive/plastic)) @@ -159,9 +159,6 @@ if(!action_cooldown_check()) return - if(xeno.mutation_type != RUNNER_ACIDER) - return - var/datum/behavior_delegate/runner_acider/behavior_delegate = xeno.behavior_delegate if(!istype(behavior_delegate)) return diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/sentinel/sentinel_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/sentinel/sentinel_powers.dm index 1ddec771d075..1ed8863c231a 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/sentinel/sentinel_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/sentinel/sentinel_powers.dm @@ -35,9 +35,6 @@ if(!xeno.check_state()) return - if(xeno.mutation_type != SENTINEL_NORMAL) - return - if(!action_cooldown_check()) to_chat(src, SPAN_WARNING("We must wait for your spit glands to refill.")) return @@ -77,9 +74,6 @@ if (!check_and_use_plasma_owner()) return - if (xeno.mutation_type != SENTINEL_NORMAL) - return - var/datum/behavior_delegate/sentinel_base/behavior = xeno.behavior_delegate if (istype(behavior)) behavior.next_slash_buffed = TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm index c800f129e3ff..9c8478a93eb2 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm @@ -78,6 +78,8 @@ /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, ) + behavior_delegate = /datum/behavior_delegate/carrier_base + icon_xenonid = 'icons/mob/xenonids/carrier.dmi' weed_food_icon = 'icons/mob/xenos/weeds_64x64.dmi' @@ -96,18 +98,9 @@ var/eggs_max = 0 var/laid_egg = 0 -/mob/living/carbon/xenomorph/carrier/update_icons() - . = ..() - if (mutation_type == CARRIER_NORMAL) - update_hugger_overlays() - if (mutation_type == CARRIER_EGGSAC) - update_eggsac_overlays() - /mob/living/carbon/xenomorph/carrier/proc/update_hugger_overlays() if(!hugger_overlays_icon) return - if(mutation_type != CARRIER_NORMAL) - return overlays -= hugger_overlays_icon hugger_overlays_icon.overlays.Cut() @@ -147,8 +140,6 @@ /mob/living/carbon/xenomorph/carrier/proc/update_eggsac_overlays() if(!eggsac_overlays_icon) return - if(mutation_type != CARRIER_EGGSAC) - return overlays -= eggsac_overlays_icon eggsac_overlays_icon.overlays.Cut() @@ -185,9 +176,6 @@ . = ..(cause, gibbed) if(.) var/chance = 75 //75% to drop an egg or hugger. - if(mutation_type == CARRIER_EGGSAC) - visible_message(SPAN_XENOWARNING("[src] throes as its eggsac bursts into a mess of acid!")) - playsound(src.loc, 'sound/effects/alien_egg_burst.ogg', 25, 1) if(huggers_cur) //Hugger explosion, like an egg morpher @@ -403,3 +391,10 @@ return GLOB.hive_datum[hivenumber].spawn_as_hugger(user, src) huggers_cur-- + +/datum/behavior_delegate/carrier_base + name = "Base Carrier Behavior Delegate" + +/datum/behavior_delegate/carrier_base/on_update_icons() + var/mob/living/carbon/xenomorph/carrier/bound_carrier = bound_xeno + bound_carrier.update_hugger_overlays() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm index f7d986570f9f..38b1e5816ffe 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm @@ -280,5 +280,5 @@ /datum/behavior_delegate/crusher_base/on_update_icons() if(bound_xeno.throwing || is_charging) //Let it build up a bit so we're not changing icons every single turf - bound_xeno.icon_state = "[bound_xeno.mutation_icon_state || bound_xeno.mutation_type] Crusher Charging" + bound_xeno.icon_state = "[bound_xeno.get_strain_icon()] Crusher Charging" return TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm b/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm index 23ba08e294ba..a63bafb5d2b0 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Defender.dm @@ -88,8 +88,8 @@ return if(bound_xeno.fortify && bound_xeno.health > 0) - bound_xeno.icon_state = "[bound_xeno.mutation_icon_state || bound_xeno.mutation_type] Defender Fortify" + bound_xeno.icon_state = "[bound_xeno.get_strain_icon()] Defender Fortify" return TRUE if(bound_xeno.crest_defense && bound_xeno.health > 0) - bound_xeno.icon_state = "[bound_xeno.mutation_icon_state || bound_xeno.mutation_type] Defender Crest" + bound_xeno.icon_state = "[bound_xeno.get_strain_icon()] Defender Crest" return TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index 83c61358e49d..b9c5b140047e 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -58,6 +58,8 @@ /mob/living/carbon/xenomorph/proc/vent_crawl, ) + behavior_delegate = /datum/behavior_delegate/facehugger_base + icon_xeno = 'icons/mob/xenos/facehugger.dmi' icon_xenonid = 'icons/mob/xenonids/facehugger.dmi' @@ -75,34 +77,16 @@ if(stat == DEAD) return ..() - if(body_position == STANDING_UP && !(mutation_type == FACEHUGGER_WATCHER) && !(locate(/obj/effect/alien/weeds) in get_turf(src))) - adjustBruteLoss(1) - return ..() - if(!client && !aghosted && away_timer > XENO_FACEHUGGER_LEAVE_TIMER) // Become a npc once again new /obj/item/clothing/mask/facehugger(loc, hivenumber) qdel(src) return ..() -/mob/living/carbon/xenomorph/facehugger/update_icons(is_pouncing) - if(!caste) - return - - if(stat == DEAD) - icon_state = "[mutation_type] [caste.caste_type] Dead" - else if(body_position == LYING_DOWN) - if(!HAS_TRAIT(src, TRAIT_INCAPACITATED) && !HAS_TRAIT(src, TRAIT_FLOORED)) - icon_state = "[mutation_type] [caste.caste_type] Sleeping" - else - icon_state = "[mutation_type] [caste.caste_type] Knocked Down" - else if(is_pouncing) - icon_state = "[mutation_type] [caste.caste_type] Thrown" - else - icon_state = "[mutation_type] [caste.caste_type] Running" - - update_fire() //the fire overlay depends on the xeno's stance, so we must update it. - update_wounds() +/mob/living/carbon/xenomorph/facehugger/update_icons() + . = ..() + if(throwing) + icon_state = "[get_strain_icon()] [caste.caste_type] Thrown" /mob/living/carbon/xenomorph/facehugger/start_pulling(atom/movable/AM) return @@ -235,3 +219,10 @@ . += "Lifetime Hugs: [total_facehugs] / [next_facehug_goal]" else . += "Lifetime Hugs: [total_facehugs]" + +/datum/behavior_delegate/facehugger_base + name = "Base Facehugger Behavior Delegate" + +/datum/behavior_delegate/facehugger_base/on_life() + if(bound_xeno.body_position == STANDING_UP && !(locate(/obj/effect/alien/weeds) in get_turf(src))) + bound_xeno.adjustBruteLoss(1) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm b/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm index c821fbc49208..ee4157a67d84 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Hivelord.dm @@ -121,10 +121,3 @@ toggle_resin_walker() to_chat(bound_xeno, SPAN_WARNING("You feel dizzy as the world slows down.")) bound_xeno.recalculate_move_delay = TRUE - -/// This check mainly exists because of the new resin node ability for resin whisperer. -/mob/living/carbon/xenomorph/hivelord/proc/on_weeds() - var/turf/turf = get_turf(src) - if(locate(/obj/effect/alien/weeds) in turf) - return TRUE - return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm index db2a9b4a38de..1957487bf778 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm @@ -517,7 +517,7 @@ overwatch(observed_xeno, TRUE) if(ovipositor && !is_mob_incapacitated(TRUE)) - egg_amount += 0.07 * mutators.egg_laying_multiplier //one egg approximately every 30 seconds + egg_amount += 0.07 //one egg approximately every 30 seconds if(egg_amount >= 1) if(isturf(loc)) var/turf/T = loc @@ -950,7 +950,7 @@ var/mob/living/carbon/xenomorph/queen/Queen = bound_xeno if(Queen.ovipositor) Queen.icon = Queen.queen_ovipositor_icon - Queen.icon_state = "[Queen.mutation_icon_state || Queen.mutation_type] Queen Ovipositor" + Queen.icon_state = "Normal Queen Ovipositor" return TRUE // Switch icon back and then let normal icon behavior happen diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm index c2229122a99a..f1ba672d63e5 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm @@ -50,6 +50,10 @@ . = list() . += "Eggs sustained: [length(eggs_sustained)] / [egg_sustain_cap]" +/datum/behavior_delegate/carrier_eggsac/on_update_icons() + var/mob/living/carbon/xenomorph/carrier/bound_carrier = bound_xeno + bound_carrier.update_eggsac_overlays() + /datum/behavior_delegate/carrier_eggsac/on_life() if(length(eggs_sustained) > egg_sustain_cap) var/obj/effect/alien/egg/carrier_egg/my_egg = eggs_sustained[1] @@ -65,6 +69,10 @@ else my_egg.check_decay() +/datum/behavior_delegate/carrier_eggsac/handle_death(mob/M) + M.visible_message(SPAN_XENOWARNING("[M] throes as its eggsac bursts into a mess of acid!")) + playsound(M.loc, 'sound/effects/alien_egg_burst.ogg', 25, TRUE) + ///Remove owner of egg /datum/behavior_delegate/carrier_eggsac/proc/remove_egg_owner(obj/effect/alien/egg/carrier_egg/egg) if(!egg.owner || egg.owner != bound_xeno) diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm index 5f1f85b5b1bd..891c1ce08e1e 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm @@ -5,9 +5,13 @@ xeno_icon_state = DEFENDER_STEELCREST actions_to_remove = list( + /datum/action/xeno_action/activable/headbutt, + /datum/action/xeno_action/activable/fortify, /datum/action/xeno_action/onclick/tail_sweep, ) actions_to_add = list( + /datum/action/xeno_action/activable/headbutt/steel_crest, + /datum/action/xeno_action/activable/fortify/steel_crest, /datum/action/xeno_action/onclick/soak, ) diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm index 3f698345193e..bca247899428 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm @@ -111,13 +111,14 @@ to_chat(src, SPAN_XENOWARNING("[target_xeno] is already at max health!")) return -///Tiny xenos (Larva and Facehuggers), don't need as much health so don't cost as much. - if(target_xeno.mob_size == 0) + //Tiny xenos (Larva and Facehuggers), don't need as much health so don't cost as much. + if(target_xeno.mob_size == MOB_SIZE_SMALL) amount = amount * 0.15 damage_taken_mod = 1 -//Forces an equivalent exchange of health between healers so they do not spam heal each other to full health. - if(target_xeno.mutation_type == DRONE_HEALER) + //Forces an equivalent exchange of health between healers so they do not spam heal each other to full health. + var/target_is_healer = istype(target_xeno.strain, /datum/xeno_strain/healer) + if(target_is_healer) damage_taken_mod = 1 face_atom(target_xeno) @@ -132,7 +133,7 @@ playsound(src, "alien_drool", 25) var/datum/behavior_delegate/drone_healer/healer_delegate = behavior_delegate healer_delegate.salve_applied_recently = TRUE - if(target_xeno.mutation_type != DRONE_HEALER && !isfacehugger(target_xeno)) // no cheap grinding + if(!target_is_healer && !isfacehugger(target_xeno)) // no cheap grinding healer_delegate.modify_transferred(amount * damage_taken_mod) update_icons() addtimer(CALLBACK(healer_delegate, /datum/behavior_delegate/drone_healer/proc/un_salve), 10 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm index 1b7e09a584ef..c5d9986c7b6a 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm @@ -10,9 +10,15 @@ /datum/action/xeno_action/onclick/toggle_long_range/runner, ) + behavior_delegate_type = /datum/behavior_delegate/facehugger_watcher + /datum/xeno_strain/watcher/apply_strain(mob/living/carbon/xenomorph/facehugger/huggy) . = ..() huggy.viewsize = 10 huggy.layer = initial(huggy.layer) return TRUE + +// This has no special effects, it's just here to skip `/datum/behavior_delegate/facehugger_base/on_life()`. +/datum/behavior_delegate/facehugger_watcher + name = "Watcher Facehugger Behavior Delegate" diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm index a2013470df8a..2b3e790ab21b 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm @@ -58,12 +58,9 @@ action_type = XENO_ACTION_CLICK /datum/action/xeno_action/activable/secrete_resin/remote/use_ability(atom/target_atom, mods) - var/mob/living/carbon/xenomorph/xeno_owner = owner - if(xeno_owner.mutation_type == HIVELORD_RESIN_WHISPERER) - var/mob/living/carbon/xenomorph/hivelord/hivelord_mob = owner - if(!hivelord_mob.on_weeds()) // There is a chance that queen can't place down buildings in ovi build view so we place the rein whisperer check here. - to_chat(owner, SPAN_XENONOTICE("We must be standing on weeds to establish a connection to the resin.")) - return + if(!can_remote_build()) + to_chat(owner, SPAN_XENONOTICE("We must be standing on weeds to establish a connection to the resin.")) + return if(!action_cooldown_check()) return @@ -105,6 +102,12 @@ playsound(target_turf, "alien_resin_build", 25) return TRUE +// By default, the xeno must be on a weed tile in order to build from a distance. +/datum/action/xeno_action/activable/secrete_resin/remote/proc/can_remote_build() + if(!locate(/obj/effect/alien/weeds) in get_turf(owner)) + return FALSE + return TRUE + /datum/action/xeno_action/verb/verb_coerce_resin() set category = "Alien" set name = "Coerce Resin" From 874d730b146a75688327f526bb8ffde1618aea44 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:25:45 +0000 Subject: [PATCH 08/17] xeno_strain streamlining --- code/_globalvars/global_lists.dm | 3 - .../carbon/xenomorph/strains/xeno_strain.dm | 74 ++++++++++--------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/code/_globalvars/global_lists.dm b/code/_globalvars/global_lists.dm index 00a3bc256e6a..4ea67bab3905 100644 --- a/code/_globalvars/global_lists.dm +++ b/code/_globalvars/global_lists.dm @@ -163,9 +163,6 @@ GLOBAL_LIST_INIT(language_keys, setup_language_keys()) //table of say codes for GLOBAL_REFERENCE_LIST_INDEXED(origins, /datum/origin, name) GLOBAL_LIST_INIT(player_origins, USCM_ORIGINS) -//Xeno strains -GLOBAL_SUBTYPE_PATHS_LIST_INDEXED(xeno_strain_list, /datum/xeno_strain, name) - //Xeno hives GLOBAL_LIST_INIT_TYPED(hive_datum, /datum/hive_status, list( XENO_HIVE_NORMAL = new /datum/hive_status(), diff --git a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm index 57ba97050075..0098f61b1e29 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm @@ -16,79 +16,81 @@ /// Typepath of the [/datum/behavior_delegate] to add. var/behavior_delegate_type -/// TODO: documentation -/// Returns a bool indicating if the strain was successfully applied. +/** + * Add this strain to `xeno`, replacing their actions and behavior holder. + * + * Returns a bool indicating if the strain was successfully applied. + */ /datum/xeno_strain/proc/apply_strain(mob/living/carbon/xenomorph/xeno) SHOULD_CALL_PARENT(TRUE) xeno.strain = src - update_actions(xeno) register_signals(xeno) - apply_behavior_holder(xeno) - update_mob(xeno) + // Update the xeno's actions. + for(var/action_path in actions_to_remove) + remove_action(xeno, action_path) + for(var/action_path in actions_to_add) + give_action(xeno, action_path) + + // Update the xeno's behavior delegate. + if(behavior_delegate_type) + if(xeno.behavior_delegate) + qdel(xeno.behavior_delegate) + xeno.behavior_delegate = new behavior_delegate_type() + xeno.behavior_delegate.bound_xeno = xeno + xeno.behavior_delegate.add_to_xeno() + + xeno.update_icons() xeno.hive.hive_ui.update_xeno_info() + // Give them all the info about the strain. to_chat(xeno, SPAN_XENOANNOUNCE(description)) if(flavor_description) to_chat(xeno, SPAN_XENOLEADER(flavor_description)) return TRUE -/// Update the `xeno`'s action buttons based on [/datum/xeno_strain/var/actions_to_remove] and [/datum/xeno_strain/var/actions_to_add]. -/datum/xeno_strain/proc/update_actions(mob/living/carbon/xenomorph/xeno) - for(var/action_path in actions_to_remove) - remove_action(xeno, action_path) - for(var/action_path in actions_to_add) - give_action(xeno, action_path) - /// TODO: documentation /datum/xeno_strain/proc/register_signals(mob/living/carbon/xenomorph/xeno) return -/// TODO: documentation -/datum/xeno_strain/proc/apply_behavior_holder(mob/living/carbon/xenomorph/xeno) - if(!behavior_delegate_type) - // don't need to do anything - return - - if(xeno.behavior_delegate) - qdel(xeno.behavior_delegate) - xeno.behavior_delegate = new behavior_delegate_type() - xeno.behavior_delegate.bound_xeno = xeno - xeno.behavior_delegate.add_to_xeno() - -/// TODO: documentation -/datum/xeno_strain/proc/update_mob(mob/living/carbon/xenomorph/xeno) - xeno.xeno_jitter(1.5 SECONDS) - xeno.update_icons() - /mob/living/carbon/xenomorph/verb/purchase_strain() set name = "Purchase Strain" set desc = "Purchase a strain for yourself" set category = "Alien" + // Firstly, make sure the xeno is actually able to take a strain. if(!can_take_strain()) return - var/strain_choice = tgui_input_list(usr, "Which strain would you like to take?", "Choose Strain", GLOB.xeno_strain_list, theme = "hive_status") - var/datum/xeno_strain/strain_path = GLOB.xeno_strain_list[strain_choice] - // Check again after the user has picked one. + // Make an assoc list of {name: typepath} from the strains available to the xeno's caste. + var/list/strain_list = list() + for(var/datum/xeno_strain/strain_type as anything in caste.available_strains) + strain_list[initial(strain_type.name)] = strain_type + + // Ask the user which strain they want. + var/strain_choice = tgui_input_list(usr, "Which strain would you like to take?", "Choose Strain", strain_list, theme = "hive_status") + var/datum/xeno_strain/chosen_strain = strain_list[strain_choice] + + // Check again after the user picks one, in case anything changed. if(!can_take_strain()) return // Show the user the strain's description, and double check that they want it. - if(alert(usr, "[initial(strain_path.description)]\n\nConfirm mutation?", "Choose Strain", "Yes", "No") != "Yes") + if(alert(usr, "[initial(chosen_strain.description)]\n\nConfirm mutation?", "Choose Strain", "Yes", "No") != "Yes") return // One more time after they confirm. if(!can_take_strain()) return - var/datum/xeno_strain/strain_instance = new strain_path() - // Apply the strain to the xeno. + // Create the strain datum and apply it to the xeno. + var/datum/xeno_strain/strain_instance = new chosen_strain() if(strain_instance.apply_strain(src)) - // And log it if it was successful. + xeno_jitter(1.5 SECONDS) + // If it applied successfully, add it to the logs. log_strain("[name] purchased strain '[strain_instance.type]'") +/// Is this xeno currently able to take a strain? /mob/living/carbon/xenomorph/proc/can_take_strain() if(!length(caste.available_strains) || !check_state(TRUE)) return FALSE From d566cfe16ba1fdd5525bbc0064dc096550a25b8f Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:43:20 +0000 Subject: [PATCH 09/17] eg I don't like using `istype()`, but I think one's needed here. (woo final error fixed!!) --- code/modules/mob/living/carbon/xenomorph/egg_item.dm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/egg_item.dm b/code/modules/mob/living/carbon/xenomorph/egg_item.dm index 1bc41b881129..59e2b964d848 100644 --- a/code/modules/mob/living/carbon/xenomorph/egg_item.dm +++ b/code/modules/mob/living/carbon/xenomorph/egg_item.dm @@ -104,12 +104,15 @@ if(weed.weed_strength >= WEED_LEVEL_WEAK && weed.linked_hive.hivenumber == hivenumber) //check for ANY weeds any_weeds = weed + // If the user isn't an eggsac carrier, they're only able to plant eggs on hive weeds. + var/needs_hive_weeds = !istype(user.strain, /datum/xeno_strain/eggsac) + var/datum/hive_status/hive = GLOB.hive_datum[hivenumber] if(!any_weeds && !hive_weeds) //you need at least some weeds to plant on. to_chat(user, SPAN_XENOWARNING("[src] must be planted on [lowertext(hive.prefix)]weeds.")) return - if(!hive_weeds && user.mutation_type != CARRIER_EGGSAC) + if(!hive_weeds && needs_hive_weeds) to_chat(user, SPAN_XENOWARNING("[src] can only be planted on [lowertext(hive.prefix)]hive weeds.")) return @@ -138,7 +141,7 @@ return for(var/obj/effect/alien/weeds/weed in T) - if(weed.weed_strength >= WEED_LEVEL_HIVE || user.mutation_type == CARRIER_EGGSAC) + if(weed.weed_strength >= WEED_LEVEL_HIVE || !needs_hive_weeds) user.use_plasma(30) var/obj/effect/alien/egg/newegg if(weed.weed_strength >= WEED_LEVEL_HIVE) From f4a153aca7a129e49041dc3c751c1c10249948e8 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Tue, 23 Jan 2024 23:19:25 +0000 Subject: [PATCH 10/17] Splitting off `apply_strain()` Mainly just so that `update_icons()` can be called after it. --- .../strains/castes/boiler/trapper.dm | 2 -- .../strains/castes/carrier/eggsac.dm | 2 -- .../strains/castes/crusher/charger.dm | 3 --- .../strains/castes/defender/steel_crest.dm | 2 -- .../strains/castes/drone/gardener.dm | 2 -- .../xenomorph/strains/castes/drone/healer.dm | 2 -- .../strains/castes/facehugger/watcher.dm | 3 --- .../castes/hivelord/resin_whisperer.dm | 2 -- .../strains/castes/lurker/vampire.dm | 2 -- .../strains/castes/praetorian/dancer.dm | 2 -- .../strains/castes/praetorian/oppressor.dm | 2 -- .../strains/castes/praetorian/vanguard.dm | 2 -- .../strains/castes/praetorian/warden.dm | 2 -- .../strains/castes/ravager/berserker.dm | 2 -- .../strains/castes/ravager/hedgehog.dm | 2 -- .../xenomorph/strains/castes/runner/acid.dm | 3 --- .../carbon/xenomorph/strains/xeno_strain.dm | 21 ++++++++++++------- 17 files changed, 14 insertions(+), 42 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm index c18973209220..e6c8061bd0fe 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm @@ -20,7 +20,6 @@ behavior_delegate_type = /datum/behavior_delegate/boiler_trapper /datum/xeno_strain/trapper/apply_strain(mob/living/carbon/xenomorph/boiler/boiler) - . = ..() if(!istype(boiler)) return FALSE @@ -35,7 +34,6 @@ boiler.speed_modifier += XENO_SPEED_SLOWMOD_TIER_5 // compensating for base buffs boiler.recalculate_everything() - return TRUE /datum/behavior_delegate/boiler_trapper name = "Boiler Trapper Behavior Delegate" diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm index f1ba672d63e5..97d6770be33c 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/carrier/eggsac.dm @@ -17,7 +17,6 @@ behavior_delegate_type = /datum/behavior_delegate/carrier_eggsac /datum/xeno_strain/eggsac/apply_strain(mob/living/carbon/xenomorph/carrier/carrier) - . = ..() carrier.plasma_types = list(PLASMA_EGG) carrier.phero_modifier += XENO_PHERO_MOD_LARGE // praetorian level pheremones @@ -32,7 +31,6 @@ carrier.eggs_max = 12 carrier.egg_planting_range = 2 carrier.update_eggsac_overlays() - return TRUE #define EGGSAC_OFF_WEED_EGGCAP 4 #define EGGSAC_EGG_SUSTAIN_DISTANCE 14 diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/crusher/charger.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/crusher/charger.dm index f2dd564cb2ee..84877b43571e 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/crusher/charger.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/crusher/charger.dm @@ -32,8 +32,6 @@ behavior_delegate_type = /datum/behavior_delegate/crusher_charger /datum/xeno_strain/charger/apply_strain(mob/living/carbon/xenomorph/crusher/crusher) - . = ..() - crusher.small_explosives_stun = FALSE crusher.health_modifier += XENO_HEALTH_MOD_LARGE crusher.speed_modifier += XENO_SPEED_FASTMOD_TIER_3 @@ -42,7 +40,6 @@ crusher.ignore_aura = "frenzy" // no funny crushers going 7 morbillion kilometers per second crusher.phero_modifier = -crusher.caste.aura_strength crusher.recalculate_everything() - return TRUE /datum/behavior_delegate/crusher_charger name = "Charger Crusher Behavior Delegate" diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm index 891c1ce08e1e..1560387c218b 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/defender/steel_crest.dm @@ -18,8 +18,6 @@ behavior_delegate_type = /datum/behavior_delegate/defender_steel_crest /datum/xeno_strain/steel_crest/apply_strain(mob/living/carbon/xenomorph/defender/defender) - . = ..() - defender.damage_modifier -= XENO_DAMAGE_MOD_VERY_SMALL if(defender.fortify) defender.ability_speed_modifier += 2.5 diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm index 456768cdd25a..88a6cb50148b 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm @@ -19,8 +19,6 @@ behavior_delegate_type = /datum/behavior_delegate/drone_gardener /datum/xeno_strain/gardener/apply_strain(mob/living/carbon/xenomorph/drone/drone) - . = ..() - drone.available_fruits = list( /obj/effect/alien/resin/fruit/greater, /obj/effect/alien/resin/fruit/unstable, diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm index bca247899428..6a985eb8d7ec 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm @@ -22,8 +22,6 @@ behavior_delegate_type = /datum/behavior_delegate/drone_healer /datum/xeno_strain/healer/apply_strain(mob/living/carbon/xenomorph/drone/drone) - . = ..() - drone.phero_modifier += XENO_PHERO_MOD_LARGE drone.plasma_types += PLASMA_PHEROMONE drone.damage_modifier -= XENO_DAMAGE_MOD_VERY_SMALL diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm index c5d9986c7b6a..7fba30b6f352 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/facehugger/watcher.dm @@ -13,11 +13,8 @@ behavior_delegate_type = /datum/behavior_delegate/facehugger_watcher /datum/xeno_strain/watcher/apply_strain(mob/living/carbon/xenomorph/facehugger/huggy) - . = ..() - huggy.viewsize = 10 huggy.layer = initial(huggy.layer) - return TRUE // This has no special effects, it's just here to skip `/datum/behavior_delegate/facehugger_base/on_life()`. /datum/behavior_delegate/facehugger_watcher diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm index 2b3e790ab21b..cca2210a30b4 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm @@ -17,8 +17,6 @@ ) /datum/xeno_strain/resin_whisperer/apply_strain(mob/living/carbon/xenomorph/hivelord/hivelord) - . = ..() - hivelord.plasmapool_modifier = 0.8 // -20% plasma pool hivelord.extra_build_dist = 12 // 1 + 12 = 13 tile build range hivelord.can_stack_builds = TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/lurker/vampire.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/lurker/vampire.dm index 4beec851c420..1f220a02dd79 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/lurker/vampire.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/lurker/vampire.dm @@ -16,8 +16,6 @@ ) /datum/xeno_strain/vampire/apply_strain(mob/living/carbon/xenomorph/lurker/lurker) - . = ..() - lurker.plasmapool_modifier = 0 lurker.health_modifier -= XENO_HEALTH_MOD_MED lurker.speed_modifier += XENO_SPEED_FASTMOD_TIER_1 diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/dancer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/dancer.dm index 2d6d7bb7b15d..ef2eb377d01e 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/dancer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/dancer.dm @@ -20,8 +20,6 @@ behavior_delegate_type = /datum/behavior_delegate/praetorian_dancer /datum/xeno_strain/dancer/apply_strain(mob/living/carbon/xenomorph/praetorian/prae) - . = ..() - prae.armor_modifier -= XENO_ARMOR_MOD_VERY_SMALL prae.speed_modifier += XENO_SPEED_FASTMOD_TIER_5 prae.plasma_types = list(PLASMA_CATECHOLAMINE) diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/oppressor.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/oppressor.dm index 6d3d50c1d12d..74dc1b9d6ecd 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/oppressor.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/oppressor.dm @@ -23,8 +23,6 @@ behavior_delegate_type = /datum/behavior_delegate/oppressor_praetorian /datum/xeno_strain/oppressor/apply_strain(mob/living/carbon/xenomorph/praetorian/prae) - . = ..() - prae.damage_modifier -= XENO_DAMAGE_MOD_SMALL prae.explosivearmor_modifier += XENO_EXPOSIVEARMOR_MOD_SMALL prae.small_explosives_stun = FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm index b8baef5e518f..a5d4b757cf6d 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm @@ -21,8 +21,6 @@ behavior_delegate_type = /datum/behavior_delegate/praetorian_vanguard /datum/xeno_strain/vanguard/apply_strain(mob/living/carbon/xenomorph/praetorian/prae) - . = ..() - prae.speed_modifier += XENO_SPEED_FASTMOD_TIER_3 prae.health_modifier -= XENO_HEALTH_MOD_MED prae.claw_type = CLAW_TYPE_SHARP diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/warden.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/warden.dm index 3cb42e59e175..56dfca99a732 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/warden.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/warden.dm @@ -21,8 +21,6 @@ behavior_delegate_type = /datum/behavior_delegate/praetorian_warden /datum/xeno_strain/warden/apply_strain(mob/living/carbon/xenomorph/praetorian/prae) - . = ..() - // Make a 'halftank' prae.speed_modifier += XENO_SPEED_SLOWMOD_TIER_5 prae.damage_modifier -= XENO_DAMAGE_MOD_SMALL diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/berserker.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/berserker.dm index 80261d295ab6..7b912cc620a0 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/berserker.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/berserker.dm @@ -17,8 +17,6 @@ behavior_delegate_type = /datum/behavior_delegate/ravager_berserker /datum/xeno_strain/berserker/apply_strain(mob/living/carbon/xenomorph/ravager/ravager) - . = ..() - ravager.plasma_max = 0 ravager.health_modifier -= XENO_HEALTH_MOD_MED ravager.armor_modifier += XENO_ARMOR_MOD_VERY_SMALL diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/hedgehog.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/hedgehog.dm index 75a85ca3e72e..4e452fb1a18a 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/hedgehog.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/ravager/hedgehog.dm @@ -17,8 +17,6 @@ behavior_delegate_type = /datum/behavior_delegate/ravager_hedgehog /datum/xeno_strain/hedgehog/apply_strain(mob/living/carbon/xenomorph/ravager/ravager) - . = ..() - ravager.plasma_max = 0 ravager.small_explosives_stun = FALSE ravager.explosivearmor_modifier += XENO_EXPOSIVEARMOR_MOD_SMALL diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/runner/acid.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/runner/acid.dm index d768ad61ce2d..8f2ce0ef7150 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/runner/acid.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/runner/acid.dm @@ -17,15 +17,12 @@ behavior_delegate_type = /datum/behavior_delegate/runner_acider /datum/xeno_strain/acider/apply_strain(mob/living/carbon/xenomorph/runner/runner) - . = ..() - runner.speed_modifier += XENO_SPEED_SLOWMOD_TIER_5 runner.armor_modifier += XENO_ARMOR_MOD_MED runner.health_modifier += XENO_HEALTH_MOD_ACIDER runner.recalculate_everything() - /datum/behavior_delegate/runner_acider var/acid_amount = 0 diff --git a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm index 0098f61b1e29..586bf95aec7b 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm @@ -21,11 +21,11 @@ * * Returns a bool indicating if the strain was successfully applied. */ -/datum/xeno_strain/proc/apply_strain(mob/living/carbon/xenomorph/xeno) - SHOULD_CALL_PARENT(TRUE) +/datum/xeno_strain/proc/_add_to_xeno(mob/living/carbon/xenomorph/xeno) + // Override `apply_changes()`, not this! (Unless you know what you're doing.) + SHOULD_NOT_OVERRIDE(TRUE) xeno.strain = src - register_signals(xeno) // Update the xeno's actions. for(var/action_path in actions_to_remove) @@ -41,17 +41,24 @@ xeno.behavior_delegate.bound_xeno = xeno xeno.behavior_delegate.add_to_xeno() + apply_strain() + xeno.update_icons() xeno.hive.hive_ui.update_xeno_info() - // Give them all the info about the strain. + // Give them all of the info about the strain. to_chat(xeno, SPAN_XENOANNOUNCE(description)) if(flavor_description) to_chat(xeno, SPAN_XENOLEADER(flavor_description)) return TRUE -/// TODO: documentation -/datum/xeno_strain/proc/register_signals(mob/living/carbon/xenomorph/xeno) +/** + * Adds any special modifiers/changes from this strain to `xeno`. + * + * Called when the strain is first added to the player. + */ +/datum/xeno_strain/proc/apply_strain(mob/living/carbon/xenomorph/xeno) + // Override with custom behaviour. return @@ -85,7 +92,7 @@ // Create the strain datum and apply it to the xeno. var/datum/xeno_strain/strain_instance = new chosen_strain() - if(strain_instance.apply_strain(src)) + if(strain_instance._add_to_xeno(src)) xeno_jitter(1.5 SECONDS) // If it applied successfully, add it to the logs. log_strain("[name] purchased strain '[strain_instance.type]'") From 8ffee8e0d78e0c876d10ea71eb9ffd19ad715791 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Wed, 24 Jan 2024 20:43:19 +0000 Subject: [PATCH 11/17] Initial fixes from testing --- code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm | 3 +-- code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm | 3 +-- .../living/carbon/xenomorph/strains/castes/drone/gardener.dm | 3 --- .../mob/living/carbon/xenomorph/strains/xeno_strain.dm | 4 ++++ 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm index 9c8478a93eb2..d290b917e945 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm @@ -15,6 +15,7 @@ speed = XENO_SPEED_TIER_4 available_strains = list(/datum/xeno_strain/eggsac) + behavior_delegate_type = /datum/behavior_delegate/carrier_base evolution_allowed = FALSE deevolves_to = list(XENO_CASTE_DRONE) @@ -78,8 +79,6 @@ /mob/living/carbon/xenomorph/proc/set_hugger_reserve_for_morpher, ) - behavior_delegate = /datum/behavior_delegate/carrier_base - icon_xenonid = 'icons/mob/xenonids/carrier.dmi' weed_food_icon = 'icons/mob/xenos/weeds_64x64.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index b9c5b140047e..00feaa44b9a3 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -10,6 +10,7 @@ speed = XENO_SPEED_TIER_8 available_strains = list(/datum/xeno_strain/watcher) + behavior_delegate_type = /datum/behavior_delegate/facehugger_base evolution_allowed = FALSE can_be_revived = FALSE @@ -58,8 +59,6 @@ /mob/living/carbon/xenomorph/proc/vent_crawl, ) - behavior_delegate = /datum/behavior_delegate/facehugger_base - icon_xeno = 'icons/mob/xenos/facehugger.dmi' icon_xenonid = 'icons/mob/xenonids/facehugger.dmi' diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm index 88a6cb50148b..6bb2f87dbb77 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/gardener.dm @@ -363,9 +363,6 @@ var/mutable_appearance/fruit_sac_overlay_icon -/datum/behavior_delegate/drone_gardener/add_to_xeno() - on_update_icons() - /datum/behavior_delegate/drone_gardener/on_update_icons() if(!fruit_sac_overlay_icon) fruit_sac_overlay_icon = mutable_appearance('icons/mob/xenos/drone_strain_overlays.dmi', "Gardener Drone Walking") diff --git a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm index 586bf95aec7b..1b260f4647a1 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/xeno_strain.dm @@ -102,6 +102,10 @@ if(!length(caste.available_strains) || !check_state(TRUE)) return FALSE + if(strain) + to_chat(src, SPAN_WARNING("We have already chosen a strain.")) + return FALSE + if(is_ventcrawling) to_chat(src, SPAN_WARNING("This place is too constraining to take a strain.")) return FALSE From bd43b18df9c0926706adb3b3740f615ee58e1e38 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:02:54 +0000 Subject: [PATCH 12/17] todo removal to appease the CI I still need to test this though --- tgui/packages/tgui/interfaces/HiveStatus.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgui/packages/tgui/interfaces/HiveStatus.jsx b/tgui/packages/tgui/interfaces/HiveStatus.jsx index 72d9476f96dd..ea23b73aca55 100644 --- a/tgui/packages/tgui/interfaces/HiveStatus.jsx +++ b/tgui/packages/tgui/interfaces/HiveStatus.jsx @@ -359,7 +359,7 @@ const XenoList = (props) => {