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 next_gather: Option<DateTime<Local>>,
43 pub next_next_gather: Option<DateTime<Local>>,
45 pub golden: bool,
47 pub upgrade_cost: BigInt,
49 pub upgrade_cost_10x: BigInt,
51 pub upgrade_cost_25x: BigInt,
53 pub upgrade_cost_100x: BigInt,
55}
56
57impl IdleGame {
58 pub(crate) fn parse_idle_game(
59 data: &[BigInt],
60 server_time: ServerTime,
61 ) -> Option<IdleGame> {
62 if data.len() < 118 {
63 return None;
64 }
65
66 let mut res = IdleGame {
67 resets: data.get(2)?.try_into().ok()?,
68 merchant_new_goods: server_time.convert_to_local(
69 data.get(63)?.try_into().ok()?,
70 "trader time",
71 )?,
72 current_money: data.get(72)?.clone(),
73 total_sacrificed: data.get(73)?.clone(),
74 _current_money_2: data.get(74)?.clone(),
75 sacrifice_runes: data.get(75)?.clone(),
76 current_runes: data.get(76)?.clone(),
77 buildings: EnumMap::default(),
78 };
79
80 for (pos, building) in
82 res.buildings.as_mut_array().iter_mut().enumerate()
83 {
84 building.level = data.get(pos + 3)?.try_into().ok()?;
85 building.earning.clone_from(data.get(pos + 13)?);
86 building.next_gather = server_time.convert_to_local(
87 data.get(pos + 23)?.try_into().ok()?,
88 "next gather time",
89 );
90 building.next_next_gather = server_time.convert_to_local(
91 data.get(pos + 33)?.try_into().ok()?,
92 "next next gather time",
93 );
94 building.golden = data.get(pos + 53)? == &1.into();
95 building.upgrade_cost.clone_from(data.get(pos + 78)?);
96 building.upgrade_cost_10x.clone_from(data.get(pos + 88)?);
97 building.upgrade_cost_25x.clone_from(data.get(pos + 98)?);
98 building.upgrade_cost_100x.clone_from(data.get(pos + 108)?);
99 }
100 Some(res)
101 }
102}
103
104#[derive(Debug, Clone, Copy, Enum, EnumIter, PartialEq, Eq, Hash)]
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
107#[allow(missing_docs)]
108pub enum IdleBuildingType {
109 Seat = 1,
110 PopcornStand,
111 ParkingLot,
112 Trap,
113 Drinks,
114 DeadlyTrap,
115 VIPSeat,
116 Snacks,
117 StrayingMonsters,
118 Toilet,
119}