Skip to content

Commit

Permalink
Xeno deaths are now tracked in the DB (#8257)
Browse files Browse the repository at this point in the history
# About the pull request

Tracks a ton of data relating to all xeno deaths
Additionally fixes xenos not being logged in round_stats.log files

# Explain why it's good for the game

Partially helping me learn how to navigate this DB API while also
allowing for me to cook some stat tracking stuff on the backend

# Changelog
:cl:
admin: Xenomorphs are now properly logged in round_stats.log files.
/:cl:

---------

Co-authored-by: harryob <[email protected]>
  • Loading branch information
Zonespace27 and harryob authored Jan 30, 2025
1 parent f8b60c5 commit 63ab11d
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 7 deletions.
10 changes: 7 additions & 3 deletions code/datums/statistics/entities/round_stats.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
var/list/weapon_stats_list = list() // list of types /datum/entity/weapon_stats
var/list/job_stats_list = list() // list of types /datum/entity/job_stats

/// A list of all player xenomorph deaths, type /datum/entity/xeno_death
var/list/xeno_deaths = list()

// nanoui data
var/list/round_data = list()
var/list/death_data = list()
Expand All @@ -46,6 +49,7 @@
. = ..()
QDEL_NULL(current_map)
QDEL_LIST(death_stats_list)
QDEL_LIST(xeno_deaths)
QDEL_LIST_ASSOC_VAL(castes_evolved)
QDEL_LIST_ASSOC_VAL(abilities_used)
QDEL_LIST_ASSOC_VAL(final_participants)
Expand Down Expand Up @@ -365,13 +369,13 @@
var/stats = ""
stats += "[SSticker.mode.round_finished]\n"
stats += "Game mode: [game_mode]\n"
stats += "Map name: [current_map.name]\n"
stats += "Map name: [current_map.map_name]\n"
stats += "Round time: [duration2text(round_length)]\n"
stats += "End round player population: [end_round_player_population]\n"

stats += "Total xenos spawned: [total_xenos_created]\n"
stats += "Total Preds spawned: [total_predators_spawned]\n"
stats += "Total Predaliens spawned: [total_predaliens]\n"
stats += "Total preds spawned: [total_predators_spawned]\n"
stats += "Total predaliens spawned: [total_predaliens]\n"
stats += "Total humans spawned: [total_humans_created]\n"

stats += "Xeno count during hijack: [xeno_count_during_hijack]\n"
Expand Down
68 changes: 68 additions & 0 deletions code/datums/statistics/entities/xeno_death.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/datum/entity/xeno_death
/// What map this death happened on
var/map_name
/// X coord of the death
var/x
/// Y coord of the death
var/y
/// Z coord of the death
var/z
/// What minute this death happened at, rounded down
var/death_minute
/// What hive this xeno was in
var/hive
/// What caste this xeno was
var/caste
/// What strain this xeno was, if any
var/strain
/// If this xeno was a leader or not
var/leader = FALSE
/// How many minutes the xeno had been alive for, rounded down
var/minutes_alive
/// Ckey of the player who died
var/ckey
/// How much damage this xeno took before dying
var/damage_taken
/// What killed this xeno ("m39 submachinegun")
var/killed_by
/// Round ID that this xeno died in
var/round_id

/datum/entity/xeno_death/proc/load_data(mob/living/carbon/xenomorph/dead_xeno, datum/cause_data/death_cause)
map_name = SSmapping.configs[GROUND_MAP]?.map_name || "Unknown Map"
x = dead_xeno.x || -1
y = dead_xeno.y || -1
z = dead_xeno.z || -1
death_minute = floor((world.time * 0.1) / 60) || -1
hive = dead_xeno.hive.name || "Unknown Hive"
caste = dead_xeno.caste.caste_type || "Unknown"
strain = dead_xeno.strain?.name || "None"
leader = (dead_xeno in dead_xeno.hive.xeno_leader_list)
minutes_alive = floor(((world.time - dead_xeno.creation_time) * 0.1) / 60) || -1
ckey = dead_xeno.ckey || dead_xeno.persistent_ckey || ""
damage_taken = dead_xeno.life_damage_taken_total || 0
killed_by = strip_improper(death_cause.cause_name) || "Unknown"
round_id = GLOB.round_id || -1

SSticker?.mode?.round_stats?.xeno_deaths += src
save()

/datum/entity_meta/xeno_death
entity_type = /datum/entity/xeno_death
table_name = "xeno_deaths"
field_types = list(
"map_name" = DB_FIELDTYPE_STRING_MEDIUM,
"x" = DB_FIELDTYPE_INT,
"y" = DB_FIELDTYPE_INT,
"z" = DB_FIELDTYPE_INT,
"death_minute" = DB_FIELDTYPE_INT,
"hive" = DB_FIELDTYPE_STRING_MEDIUM,
"caste" = DB_FIELDTYPE_STRING_MEDIUM,
"strain" = DB_FIELDTYPE_STRING_MEDIUM,
"leader" = DB_FIELDTYPE_INT,
"minutes_alive" = DB_FIELDTYPE_INT,
"ckey" = DB_FIELDTYPE_STRING_MEDIUM,
"damage_taken" = DB_FIELDTYPE_INT,
"killed_by" = DB_FIELDTYPE_STRING_MEDIUM,
"round_id" = DB_FIELDTYPE_INT,
)
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/xenomorph/Embryo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@
if(!larva_embryo.ckey && larva_embryo.burrowable && loc && is_ground_level(loc.z) && (locate(/obj/structure/bed/nest) in loc) && hive.living_xeno_queen && hive.living_xeno_queen.z == loc.z)
larva_embryo.visible_message(SPAN_XENODANGER("[larva_embryo] quickly burrows into the ground."))
if(GLOB.round_statistics && !larva_embryo.statistic_exempt)
GLOB.round_statistics.track_new_participant(faction, -1) // keep stats sane
GLOB.round_statistics.track_new_participant(faction, 0) // keep stats sane
hive.stored_larva++
hive.hive_ui.update_burrowed_larva()
qdel(larva_embryo)
Expand Down
7 changes: 4 additions & 3 deletions code/modules/mob/living/carbon/xenomorph/Evolution.dm
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ GLOBAL_LIST_EMPTY(deevolved_ckeys)
qdel(organ)
//From there, the new xeno exists, hopefully
var/mob/living/carbon/xenomorph/new_xeno = new M(get_turf(src), src)
new_xeno.creation_time = creation_time

if(!istype(new_xeno))
//Something went horribly wrong!
Expand Down Expand Up @@ -200,8 +201,7 @@ GLOBAL_LIST_EMPTY(deevolved_ckeys)
new_xeno.client.mouse_pointer_icon = initial(new_xeno.client.mouse_pointer_icon)

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.

GLOB.round_statistics.track_new_participant(new_xeno.faction, 0) //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
Expand Down Expand Up @@ -340,6 +340,7 @@ GLOBAL_LIST_EMPTY(deevolved_ckeys)
var/level_to_switch_to = get_vision_level()
var/xeno_type = GLOB.RoleAuthority.get_caste_by_text(newcaste)
var/mob/living/carbon/xenomorph/new_xeno = new xeno_type(get_turf(src), src)
new_xeno.creation_time = creation_time

if(!istype(new_xeno))
//Something went horribly wrong
Expand Down Expand Up @@ -387,7 +388,7 @@ GLOBAL_LIST_EMPTY(deevolved_ckeys)
new_xeno._status_traits = src._status_traits

if(GLOB.round_statistics && !new_xeno.statistic_exempt)
GLOB.round_statistics.track_new_participant(faction, -1) //so an evolved xeno doesn't count as two.
GLOB.round_statistics.track_new_participant(faction, 0) //so an evolved xeno doesn't count as two.
SSround_recording.recorder.stop_tracking(src)
SSround_recording.recorder.track_player(new_xeno)

Expand Down
4 changes: 4 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@
var/atom/movable/vis_obj/xeno_pack/backpack_icon_holder
/// If TRUE, the xeno cannot slash anything
var/cannot_slash = FALSE
/// The world.time when the xeno was created. Carries over between strains and evolving
var/creation_time = 0

/mob/living/carbon/xenomorph/Initialize(mapload, mob/living/carbon/xenomorph/old_xeno, hivenumber)
if(old_xeno && old_xeno.hivenumber)
Expand Down Expand Up @@ -504,6 +506,8 @@
if (hive && hive.hive_ui)
hive.hive_ui.update_all_xeno_data()

creation_time = world.time

Decorate()

RegisterSignal(src, COMSIG_MOB_SCREECH_ACT, PROC_REF(handle_screech_act))
Expand Down
3 changes: 3 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/death.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
update_icons()

if(!should_block_game_interaction(src)) //so xeno players don't get death messages from admin tests
var/datum/entity/xeno_death/death_log = SSentity_manager.tables[/datum/entity/xeno_death].make_new()
death_log.load_data(src, cause)

if(isqueen(src))
var/mob/living/carbon/xenomorph/queen/XQ = src
playsound(loc, 'sound/voice/alien_queen_died.ogg', 75, 0)
Expand Down
1 change: 1 addition & 0 deletions colonialmarines.dme
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
#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_death.dm"
#include "code\datums\statistics\entities\xeno_stats.dm"
#include "code\datums\statistics\random_facts\christmas_fact.dm"
#include "code\datums\statistics\random_facts\damage_fact.dm"
Expand Down

0 comments on commit 63ab11d

Please sign in to comment.