Hall of the fallen: kills and causes of death, in the game and over all games in the profile
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
065fe80218
commit
c52fc4c4ae
28 files changed
+534
-5
No files matched your search
+28
-1
@@ -63,8 +63,13 @@ pub struct Profile {
|
||||
pub totals: BTreeMap<String, f64>,
|
||||
#[serde(default)]
|
||||
pub unlocked: BTreeMap<String, u64>, // achievement id ("heroes.2", "flawless") -> unix time
|
||||
#[serde(default)]
|
||||
pub hall: Vec<crate::names::Fallen>, // the hall of the fallen over all games (newest last)
|
||||
}
|
||||
|
||||
// the hall of the fallen keeps this many
|
||||
pub const HALL_MAX: usize = 200;
|
||||
|
||||
impl Profile {
|
||||
pub fn total(&self, id: &str) -> f64 {
|
||||
self.totals.get(id).copied().unwrap_or(0.0)
|
||||
@@ -80,6 +85,15 @@ impl Profile {
|
||||
let e = self.unlocked.entry(k.clone()).or_insert(*t);
|
||||
*e = (*e).min(*t);
|
||||
}
|
||||
// the fallen of both, once each, in the order they fell
|
||||
for f in &other.hall {
|
||||
if !self.hall.iter().any(|h| h.name == f.name && h.kind == f.kind && h.when == f.when) {
|
||||
self.hall.push(f.clone());
|
||||
}
|
||||
}
|
||||
self.hall.sort_by_key(|h| h.when);
|
||||
let extra = self.hall.len().saturating_sub(HALL_MAX);
|
||||
self.hall.drain(..extra);
|
||||
}
|
||||
|
||||
// unlocks what the totals have reached; returns the new ones
|
||||
@@ -117,6 +131,7 @@ pub struct Context {
|
||||
pub struct Tracker {
|
||||
pub profile: Profile,
|
||||
flushed: Vec<f32>,
|
||||
hall_seen: usize, // entries of the game's hall already in the profile
|
||||
last_time: f32,
|
||||
ended: bool,
|
||||
t: f32,
|
||||
@@ -126,12 +141,13 @@ pub struct Tracker {
|
||||
|
||||
impl Tracker {
|
||||
pub fn new(profile: Profile) -> Tracker {
|
||||
Tracker { profile, flushed: vec![0.0; k::COUNTERS], last_time: 0.0, ended: false, t: 0.0, dirty: false, upload: false }
|
||||
Tracker { profile, flushed: vec![0.0; k::COUNTERS], hall_seen: 0, last_time: 0.0, ended: false, t: 0.0, dirty: false, upload: false }
|
||||
}
|
||||
|
||||
// a different game started (new, loaded): nothing of it has been counted yet
|
||||
fn restart(&mut self, g: &Game) {
|
||||
self.flushed = (0..k::COUNTERS).map(|i| g.stats.get(i)).collect();
|
||||
self.hall_seen = g.hall.len();
|
||||
self.ended = g.state != 0;
|
||||
}
|
||||
|
||||
@@ -154,6 +170,17 @@ impl Tracker {
|
||||
let played = self.t;
|
||||
self.t = 0.0;
|
||||
let mut new = Vec::new();
|
||||
// the newly fallen go into the profile's hall
|
||||
if g.hall.len() > self.hall_seen {
|
||||
for f in &g.hall[self.hall_seen..] {
|
||||
self.profile.hall.push(crate::names::Fallen { when: now, ..f.clone() });
|
||||
}
|
||||
self.hall_seen = g.hall.len();
|
||||
let extra = self.profile.hall.len().saturating_sub(HALL_MAX);
|
||||
self.profile.hall.drain(..extra);
|
||||
self.dirty = true;
|
||||
self.upload = true;
|
||||
}
|
||||
// the counters of the game
|
||||
for i in 0..k::COUNTERS {
|
||||
let cur = g.stats.get(i);
|
||||
|
||||
Reference in new issue
Block a user