1#![allow(clippy::module_name_repetitions)]
2use chrono::{DateTime, Local};
3use enum_map::{Enum, EnumMap};
4use num_bigint::BigInt;
5use strum::EnumIter;
6
7use super::ServerTime;
8
9#[derive(Debug, Clone, Default)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct IdleGame {
13 pub current_money: BigInt,
15 pub current_runes: BigInt,
17 pub resets: u32,
19 pub sacrifice_runes: BigInt,
21 pub merchant_new_goods: DateTime<Local>,
23 pub total_sacrificed: BigInt,
27 _current_money_2: BigInt,
29 pub buildings: EnumMap<IdleBuildingType, IdleBuilding>,
31}
32
33#[derive(Debug, Clone, Default)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36pub struct IdleBuilding {
37 pub level: u32,
39 pub earning: BigInt,
41 pub cycle_start: Option<DateTime<Local>>,
45 pub cycle_end: Option<DateTime<Local>>,
49 pub golden: bool,
51 pub upgrade_cost: BigInt,
53 pub upgrade_cost_10x: BigInt,
55 pub upgrade_cost_25x: BigInt,
57 pub upgrade_cost_100x: BigInt,
59}
60
61impl IdleGame {
62 pub(crate) fn parse_idle_game(
63 data: &[BigInt],
64 server_time: ServerTime,
65 ) -> Option<IdleGame> {
66 if data.len() < 118 {
67 return None;
68 }
69
70 let mut res = IdleGame {
71 resets: data.get(2)?.try_into().ok()?,
72 merchant_new_goods: server_time.convert_to_local(
73 data.get(63)?.try_into().ok()?,
74 "trader time",
75 )?,
76 current_money: data.get(72)?.clone(),
77 total_sacrificed: data.get(73)?.clone(),
78 _current_money_2: data.get(74)?.clone(),
79 sacrifice_runes: data.get(75)?.clone(),
80 current_runes: data.get(76)?.clone(),
81 buildings: EnumMap::default(),
82 };
83
84 for (pos, building) in
86 res.buildings.as_mut_array().iter_mut().enumerate()
87 {
88 building.level = data.get(pos + 3)?.try_into().ok()?;
89 building.earning.clone_from(data.get(pos + 13)?);
90 building.cycle_start = server_time.convert_to_local(
91 data.get(pos + 23)?.try_into().ok()?,
92 "idle cycle start time",
93 );
94 building.cycle_end = server_time.convert_to_local(
95 data.get(pos + 33)?.try_into().ok()?,
96 "idle cycle end time",
97 );
98 building.golden = data.get(pos + 53)? == &1.into();
99 building.upgrade_cost.clone_from(data.get(pos + 78)?);
100 building.upgrade_cost_10x.clone_from(data.get(pos + 88)?);
101 building.upgrade_cost_25x.clone_from(data.get(pos + 98)?);
102 building.upgrade_cost_100x.clone_from(data.get(pos + 108)?);
103 }
104 Some(res)
105 }
106}
107
108#[derive(Debug, Clone, Copy, Enum, EnumIter, PartialEq, Eq, Hash)]
110#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
111#[allow(missing_docs)]
112pub enum IdleBuildingType {
113 Seat = 1,
114 PopcornStand,
115 ParkingLot,
116 Trap,
117 Drinks,
118 DeadlyTrap,
119 VIPSeat,
120 Snacks,
121 StrayingMonsters,
122 Toilet,
123}