Skip to main content

cuqueclicker_lib/game/tree/
state.rs

1//! Persistent state for the upgrade tree.
2//!
3//! Saved between sessions: `bought`, `cursor`, `last_bought`.
4//! Reconstructed on load: the `TreeAggregate` cache (lives on `GameState`,
5//! `#[serde(skip)]`, rebuilt by `migrate_runtime`).
6
7use std::collections::HashSet;
8
9use serde::{Deserialize, Serialize};
10
11use super::coord::TreeCoord;
12
13/// Player-owned tree state. Small on disk: a set of `i64`-sized coords,
14/// a cursor coord, and the lot of the most recently bought node.
15#[derive(Clone, Debug, Serialize, Deserialize)]
16pub struct UpgradeTreeState {
17    /// Lot coordinates of every bought node.
18    #[serde(default)]
19    pub bought: HashSet<TreeCoord>,
20    /// Cursor (focus) position on the canvas, in lot coordinates. The
21    /// renderer pans the viewport so the cursor's lot sits near the
22    /// center. Saved so reopening the tree lands where the player left it.
23    #[serde(default)]
24    pub cursor: TreeCoord,
25    /// Lot of the most recently bought node. Drives the `[1] last bought`
26    /// shortcut. `None` on fresh game / after prestige / after the only
27    /// bought node was refunded.
28    #[serde(default)]
29    pub last_bought: Option<TreeCoord>,
30}
31
32impl Default for UpgradeTreeState {
33    fn default() -> Self {
34        Self {
35            bought: HashSet::new(),
36            cursor: TreeCoord::ORIGIN,
37            last_bought: None,
38        }
39    }
40}
41
42impl UpgradeTreeState {
43    pub fn is_owned(&self, c: TreeCoord) -> bool {
44        self.bought.contains(&c)
45    }
46
47    pub fn owned_count(&self) -> usize {
48        self.bought.len()
49    }
50}