Skip to content

Commit

Permalink
Adds strains framework (tgstation#15790)
Browse files Browse the repository at this point in the history
Co-authored-by: TiviPlus <[email protected]>
  • Loading branch information
TiviPlus and TiviPlus authored May 31, 2024
1 parent d409561 commit 519a74a
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 9 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ GLOBAL_LIST_INIT(xenoupgradetiers, list(XENO_UPGRADE_BASETYPE, XENO_UPGRADE_INVA
#define CASTE_DO_NOT_ANNOUNCE_DEATH (1<<14) // xenos with this flag wont be announced to hive when dying
#define CASTE_STAGGER_RESISTANT (1<<15) //Resistant to some forms of stagger, such as projectiles
#define CASTE_HAS_WOUND_MASK (1<<16) //uses an alpha mask for wounded states
#define CASTE_EXCLUDE_STRAINS (1<<17) // denotes castes/basetypes that should be excluded from being evoable as a strain

// Xeno defines that affect evolution, considering making a new var for these
#define CASTE_LEADER_TYPE (1<<16) //Whether we are a leader type caste, such as the queen, shrike or ?king?, and is affected by queen ban and playtime restrictions
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@
//regress and caste swap UI
#define TRAIT_CASTE_SWAP "caste_swap"
#define TRAIT_REGRESSING "regressing"
#define TRAIT_STRAIN_SWAP "strain swap"

///Pauses campaign mission timer
#define CAMPAIGN_MISSION_TIMER_PAUSED "campaign_mission_timer_paused"
3 changes: 2 additions & 1 deletion code/_globalvars/bitfields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ GLOBAL_LIST_INIT(bitfields, list(
"CASTE_PLASMADRAIN_IMMUNE" = CASTE_PLASMADRAIN_IMMUNE,
"CASTE_NOT_IN_BIOSCAN" = CASTE_NOT_IN_BIOSCAN,
"CASTE_DO_NOT_ANNOUNCE_DEATH" = CASTE_DO_NOT_ANNOUNCE_DEATH,
"CASTE_STAGGER_RESISTANT" = CASTE_STAGGER_RESISTANT
"CASTE_STAGGER_RESISTANT" = CASTE_STAGGER_RESISTANT,
"CASTE_EXCLUDE_STRAINS" = CASTE_EXCLUDE_STRAINS,
),
"can_flags" = list(
"CASTE_CAN_HOLD_FACEHUGGERS" = CASTE_CAN_HOLD_FACEHUGGERS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
sunder_recover = 1

// *** Flags *** //
caste_flags = CASTE_INNATE_HEALING|CASTE_INNATE_PLASMA_REGEN|CASTE_HIDE_IN_STATUS
caste_flags = CASTE_INNATE_HEALING|CASTE_INNATE_PLASMA_REGEN|CASTE_HIDE_IN_STATUS|CASTE_EXCLUDE_STRAINS
can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER|CASTE_CAN_HEAL_WITHOUT_QUEEN

// *** Defense *** //
Expand Down
5 changes: 4 additions & 1 deletion code/modules/mob/living/carbon/xenomorph/evo_datum.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! TODO: this needs a refactor/UI rewor at some point, we've probably bolted too much onto this over time

/// Empty datum parent for use as evolution panel entrance.
/datum/evolution_panel
// Empty
Expand Down Expand Up @@ -39,7 +41,7 @@
"type_path" = caste.type,
"name" = caste.display_name,
"abilities" = list(),
"instant_evolve" = (caste.caste_flags & CASTE_INSTANT_EVOLUTION || (HAS_TRAIT(xeno, TRAIT_CASTE_SWAP) || HAS_TRAIT(xeno, TRAIT_REGRESSING))),
"instant_evolve" = (caste.caste_flags & CASTE_INSTANT_EVOLUTION || (HAS_TRAIT(xeno, TRAIT_STRAIN_SWAP) || HAS_TRAIT(xeno, TRAIT_CASTE_SWAP) || HAS_TRAIT(xeno, TRAIT_REGRESSING))),
)
for(var/ability in caste.actions)
var/datum/action/ability/xeno_action/xeno_ability = ability
Expand Down Expand Up @@ -86,3 +88,4 @@
. = ..()
REMOVE_TRAIT(user, TRAIT_CASTE_SWAP, TRAIT_CASTE_SWAP)
REMOVE_TRAIT(user, TRAIT_REGRESSING, TRAIT_REGRESSING)
REMOVE_TRAIT(user, TRAIT_STRAIN_SWAP, TRAIT_STRAIN_SWAP)
17 changes: 16 additions & 1 deletion code/modules/mob/living/carbon/xenomorph/evolution.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,27 @@
set desc = "Change into another caste in the same tier."
set category = "Alien"

if(world.time - (GLOB.key_to_time_of_caste_swap[key] ? GLOB.key_to_time_of_caste_swap[key] : -INFINITY) < 9000) //casteswap timer, 15 minutes
if(world.time - (GLOB.key_to_time_of_caste_swap[key] ? GLOB.key_to_time_of_caste_swap[key] : -INFINITY) < (15 MINUTES))
to_chat(src, span_warning("Your caste swap timer is not done yet."))
return

SStgui.close_user_uis(src, GLOB.evo_panel)
ADD_TRAIT(src, TRAIT_CASTE_SWAP, TRAIT_CASTE_SWAP)
GLOB.evo_panel.ui_interact(src)

/mob/living/carbon/xenomorph/verb/strain_swap()
set name = "Strain Swap"
set desc = "Change into a strain of your current caste."
set category = "Alien"

if(world.time - (GLOB.key_to_time_of_caste_swap[key] ? GLOB.key_to_time_of_caste_swap[key] : -INFINITY) < (5 MINUTES)) // yes this is shared
to_chat(src, span_warning("Your caste swap timer is not done yet."))
return

SStgui.close_user_uis(src, GLOB.evo_panel)
ADD_TRAIT(src, TRAIT_STRAIN_SWAP, TRAIT_STRAIN_SWAP)
GLOB.evo_panel.ui_interact(src)

/mob/living/carbon/xenomorph/verb/regress()
set name = "Regress"
set desc = "Regress into a lower form."
Expand All @@ -36,6 +49,8 @@
///Creates a list of possible /datum/xeno_caste options for a caste based on their tier.
/mob/living/carbon/xenomorph/proc/get_evolution_options()
. = list()
if(HAS_TRAIT(src, TRAIT_STRAIN_SWAP))
return xeno_caste.get_strain_options()
if(HAS_TRAIT(src, TRAIT_CASTE_SWAP))
switch(tier)
if(XENO_TIER_ZERO, XENO_TIER_FOUR)
Expand Down
24 changes: 24 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,30 @@
current_type = initial(current_type.parent_type)
return current_type

/// basetype = list(strain1, strain2)
GLOBAL_LIST_INIT(strain_list, init_glob_strain_list())
/proc/init_glob_strain_list()
var/list/strain_list = list()
for(var/datum/xeno_caste/root_caste AS in GLOB.xeno_caste_datums)
if(root_caste.parent_type != /datum/xeno_caste)
continue
strain_list[root_caste] = list()
for(var/datum/xeno_caste/typepath AS in subtypesof(root_caste))
if(typepath::upgrade != XENO_UPGRADE_BASETYPE)
continue
if(typepath::caste_flags & CASTE_EXCLUDE_STRAINS)
continue
strain_list[root_caste] += typepath
return strain_list

///returns a list of strains(xeno castedatum paths) that this caste can currently evolve to
/datum/xeno_caste/proc/get_strain_options()
var/datum/xeno_caste/root_type = type
while(initial(root_type.parent_type) != /datum/xeno_caste)
root_type = root_type::parent_type
var/list/options = GLOB.strain_list[root_type]
return options?.Copy()

/mob/living/carbon/xenomorph
name = "Drone"
desc = "What the hell is THAT?"
Expand Down
9 changes: 4 additions & 5 deletions code/modules/unit_tests/xeno_logical_scaling.dm
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
/datum/unit_test/xeno_logical_scaling/Run()
var/list/by_xeno = list()
for(var/i in subtypesof(/datum/xeno_caste))
var/datum/xeno_caste/caste = i
for(var/datum/xeno_caste/caste AS in subtypesof(/datum/xeno_caste))
var/typepath = initial(caste.caste_type_path)
var/upgrade = initial(caste.upgrade)
if(isnull(typepath))
Fail("[i] has a null caste_type_path")
Fail("[caste] has a null caste_type_path")
continue
if(upgrade == "basetype")
if(upgrade == XENO_UPGRADE_BASETYPE)
continue
if(isnull(upgrade))
Fail("[i] has a null upgrade")
Fail("[caste] has a null upgrade")
continue
if(!("[typepath]" in by_xeno))
by_xeno["[typepath]"] = list()
Expand Down

0 comments on commit 519a74a

Please sign in to comment.