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}