1use crate::ad_usage::AdUsageMap;
2use crate::buffs::ActiveBuff;
3use crate::character_settings::CharacterSettings;
4use crate::class::CharacterClass;
5use crate::cores::CoresState;
6use crate::currency::{CurrencyId, CurrencyUnit};
7use crate::entity::EntityAttributes;
8use crate::talent_tree::TalentLevelsMap;
9
10use crate::plinko::PlinkoPinBonusesMap;
11
12use super::{
13 abilities, ability_stones, bundles, characters, items, pets, skins, statue, users, vassals,
14};
15
16use crate::prelude::*;
17
18#[derive(Clone, PartialEq, Eq, Default, Debug, JsonSchema, Tsify, Serialize, Deserialize)]
19pub struct CharacterState {
20 pub user: users::User,
21 pub character: characters::Character,
22 pub currencies: Vec<CurrencyUnit>,
23 pub inventory: Vec<items::Item>,
24 pub all_abilities: Vec<abilities::Ability>, pub equipped_abilities: abilities::EquippedAbilities, pub ability_stones: Vec<ability_stones::OwnedAbilityStone>,
28 pub ability_stone_sockets: ability_stones::AbilityStoneSockets,
30 pub all_pets: Vec<pets::Pet>,
31 pub equipped_pets: pets::EquippedPets,
32 pub suzerain: Option<vassals::Suzerain>,
33 pub vassals: Vec<vassals::Vassal>,
34 pub vassal_tasks: Vec<vassals::VassalTask>,
35 pub player_attributes: EntityAttributes,
36 pub bundle_step_generic: Vec<bundles::BundleStepGeneric>,
37 pub character_settings: CharacterSettings,
38 pub character_skins: skins::CharacterSkins,
39 pub talent_levels: TalentLevelsMap,
40 pub statue_state: statue::StatueState,
41 pub plinko_pin_bonuses: PlinkoPinBonusesMap,
44 pub ad_usage: AdUsageMap,
45
46 pub kill_faucet_daily: crate::kill_faucets::KillFaucetDailyMap,
49 pub active_buffs: Vec<ActiveBuff>,
50 pub character_classes: Vec<CharacterClass>,
51 pub cores: CoresState,
53 pub stones: crate::stones::StoneInventory,
56 pub artifacts: crate::artifacts::ArtifactCollection,
59}
60
61impl CharacterState {
62 pub fn get_vassal(&self, vassal_id: uuid::Uuid) -> anyhow::Result<vassals::Vassal> {
63 match self
64 .vassals
65 .iter()
66 .find(|vassal| vassal.character_id == vassal_id)
67 {
68 Some(vassal) => Ok(vassal.clone()),
69 None => anyhow::bail!("No vassal with given id={}", vassal_id),
70 }
71 }
72
73 pub fn has_vassal(&self, vassal_id: uuid::Uuid) -> bool {
74 self.vassals
75 .iter()
76 .any(|vassal| vassal.character_id == vassal_id)
77 }
78
79 pub fn get_currency(&self, currency_id: CurrencyId) -> i64 {
80 if let Some(currency_unity) = self
81 .currencies
82 .iter()
83 .find(|currency| currency.currency_id == currency_id)
84 {
85 return currency_unity.amount;
86 };
87
88 0
89 }
90
91 pub fn get_arena_tickets(&self, currency_id: CurrencyId) -> i64 {
92 if let Some(arena_tickets_unit) = self
93 .currencies
94 .iter()
95 .find(|currency| currency.currency_id == currency_id)
96 {
97 return arena_tickets_unit.amount;
98 };
99
100 0
101 }
102
103 pub fn decrement_arena_tickets(&mut self, currency_id: CurrencyId) -> anyhow::Result<()> {
104 let Some(arena_tickets_unit) = self
105 .currencies
106 .iter_mut()
107 .find(|currency| currency.currency_id == currency_id)
108 else {
109 anyhow::bail!(
110 "Failed to get arena tickets currency unit with id={}",
111 currency_id
112 );
113 };
114
115 if arena_tickets_unit.amount <= 0 {
116 anyhow::bail!("No available arena tickets to decrement",);
117 }
118
119 arena_tickets_unit.amount -= 1;
120
121 Ok(())
122 }
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, JsonSchema, Tsify)]
126#[tsify(into_wasm_abi, from_wasm_abi)]
127pub struct GetCharacterStateRequest {
128 pub character_id: uuid::Uuid,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, JsonSchema, Tsify)]
132#[tsify(into_wasm_abi, from_wasm_abi)]
133pub struct FullClearCharacterRequest {
134 pub username: String,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, JsonSchema, Tsify)]
138#[tsify(into_wasm_abi, from_wasm_abi)]
139pub enum GetCharacterStateResponse {
140 Ok {
141 character_state: Box<CharacterState>,
142 flip_state: crate::flip::FlipState,
144 },
145 Error {
146 code: String,
147 message: String,
148 },
149}