medic stats

This commit is contained in:
Robin Appelman 2021-08-08 00:05:21 +02:00
commit a5040ec355
5 changed files with 147 additions and 20 deletions

View file

@ -3,34 +3,40 @@ use crate::event::GameEvent;
use crate::module::EventHandler;
use crate::raw_event::RawEventType;
use crate::SubjectMap;
use serde::Serialize;
use std::collections::HashMap;
use thiserror::Error;
#[derive(Default)]
pub struct MedicStatsBuilder {
struct MedicStatsBuilder {
advantages_lost: u32,
biggest_advantage_lost: u32,
biggest_advantage_lost: f32,
near_full_charge_death: u32,
deaths_after_uber: u32,
total_time_before_healing: u32,
total_time_before_healing: f32,
start_healing_count: u32,
total_time_to_build: u32,
uber_build_count: u32,
total_time_to_use: u32,
total_uber_length: u32,
total_time_to_use: f32,
total_uber_length: f32,
charge_count: u32,
last_build_start: u32,
last_uber_end: u32,
drops: u32,
}
#[derive(Debug, Serialize)]
pub struct MedicStats {
advantages_lost: u32,
biggest_advantage_lost: u32,
biggest_advantage_lost: f32,
near_full_charge_death: u32,
deaths_after_uber: u32,
avg_time_before_healing: u32,
avg_time_to_build: u32,
avg_time_to_use: u32,
avg_uber_length: u32,
avg_time_before_healing: f32,
avg_time_to_build: f32,
avg_time_to_use: f32,
avg_uber_length: f32,
charge_count: u32,
drops: u32,
}
impl From<MedicStatsBuilder> for MedicStats {
@ -41,11 +47,12 @@ impl From<MedicStatsBuilder> for MedicStats {
near_full_charge_death: builder.near_full_charge_death,
deaths_after_uber: builder.deaths_after_uber,
avg_time_before_healing: builder.total_time_before_healing
/ builder.start_healing_count,
avg_time_to_build: builder.total_time_to_build / builder.uber_build_count,
avg_time_to_use: builder.total_time_to_use / builder.charge_count,
avg_uber_length: builder.total_uber_length / builder.charge_count,
/ builder.start_healing_count as f32,
avg_time_to_build: builder.total_time_to_build as f32 / builder.uber_build_count as f32,
avg_time_to_use: builder.total_time_to_use / builder.charge_count as f32,
avg_uber_length: builder.total_uber_length / builder.charge_count as f32,
charge_count: builder.charge_count,
drops: builder.drops,
}
}
}
@ -64,13 +71,18 @@ impl EventHandler for MedicStatsHandler {
fn does_handle(&self, ty: RawEventType) -> bool {
matches!(
ty,
RawEventType::ChargeDeployed | RawEventType::ChargeEnd | RawEventType::ChargeReady
RawEventType::ChargeDeployed
| RawEventType::ChargeEnd
| RawEventType::ChargeReady
| RawEventType::UberAdvantageLost
| RawEventType::MedicDeath
| RawEventType::FirstHealAfterSpawn
)
}
fn handle(
&mut self,
_time: u32,
time: u32,
subject: SubjectId,
event: &GameEvent,
) -> Result<(), Self::Error> {
@ -79,12 +91,60 @@ impl EventHandler for MedicStatsHandler {
} else {
return Ok(());
};
match event {
GameEvent::ChargeEnded(end) => {
let builder = self.0.entry(SteamId3(healer_steam_id)).or_default();
builder.total_uber_length += end.duration.unwrap_or_default();
builder.last_uber_end = time;
}
GameEvent::ChargeDeployed(_deployed) => {
let builder = self.0.entry(SteamId3(healer_steam_id)).or_default();
builder.charge_count += 1;
}
GameEvent::AdvantageLost(lost) => {
let builder = self.0.entry(SteamId3(healer_steam_id)).or_default();
builder.advantages_lost += 1;
let time = lost.time.unwrap_or_default();
if time > builder.biggest_advantage_lost {
builder.biggest_advantage_lost = time;
}
}
GameEvent::FirstHeal(first) => {
let builder = self.0.entry(SteamId3(healer_steam_id)).or_default();
builder.total_time_before_healing += first.time.unwrap_or_default();
builder.start_healing_count += 1;
builder.last_build_start = time;
}
GameEvent::ChargeReady => {
let builder = self.0.entry(SteamId3(healer_steam_id)).or_default();
if builder.last_build_start > 0 {
let build_time = time - builder.last_build_start;
builder.last_build_start = 0;
builder.total_time_to_build += build_time;
builder.uber_build_count += 1;
}
}
GameEvent::MedicDeath(death) => {
let builder = self.0.entry(SteamId3(healer_steam_id)).or_default();
let charge = death.charge.unwrap_or_default();
if charge > 95 && charge < 100 {
builder.near_full_charge_death += 1;
} else if charge >= 100 {
builder.drops += 1;
}
if time - builder.last_uber_end <= 20 {
builder.deaths_after_uber += 1;
}
}
_ => {}
}
Ok(())
}
fn finish(self, _subjects: &SubjectMap) -> Self::Output {
self.0
.into_iter()
.filter(|(_, builder)| builder.start_healing_count > 0)
.map(|(steam_id, builder)| (steam_id, builder.into()))
.collect()
}

View file

@ -7,6 +7,7 @@ pub use healspread::HealSpreadHandler;
pub use lobbysettings::{
LobbySettingsError, LobbySettingsHandler, Location, Settings as LobbySettings,
};
pub use medicstats::{MedicStats, MedicStatsHandler};
use std::convert::Infallible;
use std::error::Error;
use std::fmt::Debug;