From 27aaa875adec567672116b5ff0e289c4b60c3dbd Mon Sep 17 00:00:00 2001 From: Zonespace <41448081+Zonespace27@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:24:39 -0800 Subject: [PATCH] Xeno caste picks are now tracked in the DB (#8261) # About the pull request Tracks all evolved-into castes in the DB # Explain why it's good for the game Additional stat tracking is good, i'm cooking things # Testing Photographs and Procedure (T0/Hellhound/King no longer show up) ![image](https://github.com/user-attachments/assets/2a8d8758-66e0-4f3d-aaf6-131262801fc4) --- .../statistics/entities/round_caste_picks.dm | 51 +++++++++++++++++++ .../datums/statistics/entities/round_stats.dm | 11 ++++ .../mob/living/carbon/xenomorph/Evolution.dm | 18 ++++++- .../xenomorph/abilities/queen/queen_powers.dm | 3 +- colonialmarines.dme | 1 + 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 code/datums/statistics/entities/round_caste_picks.dm diff --git a/code/datums/statistics/entities/round_caste_picks.dm b/code/datums/statistics/entities/round_caste_picks.dm new file mode 100644 index 000000000000..761838e84683 --- /dev/null +++ b/code/datums/statistics/entities/round_caste_picks.dm @@ -0,0 +1,51 @@ +/datum/entity/round_caste_picks + /// Round ID that we're storing data on + var/round_id + /// Dict of "castename" : amount picked + var/list/castes_picked + +/datum/entity/round_caste_picks/New() + . = ..() + round_id = GLOB.round_id || -1 + +/datum/entity/round_caste_picks/assign_values(list/values, list/ignore = list()) + for(var/field in metadata.field_types) + if(ignore.Find(field)) + continue + if(field == "round_id") + vars[field] = values[field] + else + castes_picked[field] = values[field] + +/datum/entity_meta/round_caste_picks + entity_type = /datum/entity/round_caste_picks + table_name = "round_caste_picks" + field_types = list( + "round_id" = DB_FIELDTYPE_INT, + ) + +/datum/entity_meta/round_caste_picks/New() + . = ..() + for(var/caste_name in (ALL_XENO_CASTES - XENO_T0_CASTES - XENO_CASTE_HELLHOUND - XENO_CASTE_KING)) + field_types[lowertext(replacetext(caste_name, " ", "_"))] = DB_FIELDTYPE_INT + +/datum/entity_meta/round_caste_picks/map(datum/entity/round_caste_picks/entity, list/values) + var/strid = "[values[DB_DEFAULT_ID_FIELD]]" + entity.id = strid + for(var/field in field_types) + if(field == "round_id") + entity.vars[field] = values[field] + else + entity.castes_picked[field] = values[field] + +/datum/entity_meta/round_caste_picks/unmap(datum/entity/round_caste_picks/entity, include_id = TRUE) + var/list/values = list() + if(include_id) + values[DB_DEFAULT_ID_FIELD] = entity.id + for(var/field in field_types) + if(field == "round_id") + values[field] = entity.vars[field] + else + values[field] = entity.castes_picked[field] + + return values diff --git a/code/datums/statistics/entities/round_stats.dm b/code/datums/statistics/entities/round_stats.dm index 79493ca87ef0..f4b7bea10e43 100644 --- a/code/datums/statistics/entities/round_stats.dm +++ b/code/datums/statistics/entities/round_stats.dm @@ -28,6 +28,8 @@ var/list/abilities_used = list() // types of /datum/entity/statistic, "tail sweep" = 10, "screech" = 2 + var/list/castes_evolved = list() // dict of any caste that has been evolved into, and how many times, "Ravager" = 5, "Warrior" = 2 + var/list/participants = list() // types of /datum/entity/statistic, "[human.faction]" = 10, "xeno" = 2 var/list/final_participants = list() // types of /datum/entity/statistic, "[human.faction]" = 0, "xeno" = 45 var/list/hijack_participants = list() // types of /datum/entity/statistic, "[human.faction]" = 0, "xeno" = 45 @@ -44,6 +46,7 @@ . = ..() QDEL_NULL(current_map) QDEL_LIST(death_stats_list) + QDEL_LIST_ASSOC_VAL(castes_evolved) QDEL_LIST_ASSOC_VAL(abilities_used) QDEL_LIST_ASSOC_VAL(final_participants) QDEL_LIST_ASSOC_VAL(hijack_participants) @@ -305,9 +308,17 @@ death_data["death_stats_list"] = new_death_list track_dead_participant(new_death.faction_name) +/datum/entity/statistic/round/proc/store_caste_evo_data() + var/datum/entity/round_caste_picks/caste_picks = SSentity_manager.tables[/datum/entity/round_caste_picks].make_new() + caste_picks.castes_picked = castes_evolved + caste_picks.save() + /datum/entity/statistic/round/proc/log_round_statistics() if(!GLOB.round_stats) return + + store_caste_evo_data() + var/total_xenos_created = 0 var/total_predators_spawned = 0 var/total_predaliens = 0 diff --git a/code/modules/mob/living/carbon/xenomorph/Evolution.dm b/code/modules/mob/living/carbon/xenomorph/Evolution.dm index e4e89027b9cc..04f9f1f8d60e 100644 --- a/code/modules/mob/living/carbon/xenomorph/Evolution.dm +++ b/code/modules/mob/living/carbon/xenomorph/Evolution.dm @@ -4,6 +4,9 @@ //All castes need an evolves_to() list in their defines //Such as evolves_to = list(XENO_CASTE_WARRIOR, XENO_CASTE_SENTINEL, XENO_CASTE_RUNNER, "Badass") etc +/// A list of ckeys that have been de-evolved willingly or forcefully +GLOBAL_LIST_EMPTY(deevolved_ckeys) + /mob/living/carbon/xenomorph/verb/Evolve() set name = "Evolve" set desc = "Evolve into a higher form." @@ -198,8 +201,19 @@ if(new_xeno.mind && GLOB.round_statistics) GLOB.round_statistics.track_new_participant(new_xeno.faction, -1) //so an evolved xeno doesn't count as two. + SSround_recording.recorder.track_player(new_xeno) + // We prevent de-evolved people from being tracked for the rest of the round relating to T1s in order to prevent people + // Intentionally de/re-evolving to mess with the stats gathered. We don't track t2/3 because it's a legit strategy to open + // With a t1 into drone before de-evoing later to go t1 into another caste once survs are dead/capped + if(new_xeno.ckey && !((new_xeno.caste.caste_type in XENO_T1_CASTES) && (new_xeno.ckey in GLOB.deevolved_ckeys))) + var/caste_cleaned_key = lowertext(replacetext(castepick, " ", "_")) + if(!SSticker.mode?.round_stats.castes_evolved[caste_cleaned_key]) + SSticker.mode?.round_stats.castes_evolved[caste_cleaned_key] = 1 + else + SSticker.mode?.round_stats.castes_evolved[caste_cleaned_key] += 1 + SEND_SIGNAL(src, COMSIG_XENO_EVOLVE_TO_NEW_CASTE, new_xeno) /mob/living/carbon/xenomorph/proc/evolve_checks() @@ -314,8 +328,8 @@ if(new_xeno) log_game("EVOLVE: [key_name(src)] de-evolved into [new_xeno].") - - return + if(new_xeno.ckey) + GLOB.deevolved_ckeys += new_xeno.ckey /mob/living/carbon/xenomorph/proc/transmute(newcaste) // We have to delete the organ before creating the new xeno because all old_xeno contents are dropped to the ground on Initalize() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm index 31175d40bc38..a31de2316925 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm @@ -72,7 +72,8 @@ if(user_xeno.hive.living_xeno_queen && user_xeno.hive.living_xeno_queen.observed_xeno == target_xeno) user_xeno.hive.living_xeno_queen.overwatch(new_xeno) - return + if(new_xeno.ckey) + GLOB.deevolved_ckeys += new_xeno.ckey /datum/action/xeno_action/onclick/remove_eggsac/use_ability(atom/A) var/mob/living/carbon/xenomorph/queen/X = owner diff --git a/colonialmarines.dme b/colonialmarines.dme index b49e016f633e..0dc5b477768c 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -675,6 +675,7 @@ #include "code\datums\statistics\entities\player_entity.dm" #include "code\datums\statistics\entities\player_save.dm" #include "code\datums\statistics\entities\player_stats.dm" +#include "code\datums\statistics\entities\round_caste_picks.dm" #include "code\datums\statistics\entities\round_stats.dm" #include "code\datums\statistics\entities\weapon_stats.dm" #include "code\datums\statistics\entities\xeno_stats.dm"