essences/
currency.rs

1use crate::prelude::*;
2use event_system::script::types::ESCurrencyUnit;
3
4#[declare]
5pub type CurrencyId = uuid::Uuid;
6
7#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Tsify)]
8#[tsify(from_wasm_abi, into_wasm_abi)]
9pub enum CurrencySource {
10    EntityDeath,
11    ItemSell,
12    AutoItemSell,
13    QuestClaim,
14    QuestsTrackReward,
15    VassalTaskCompletion,
16    ReferralLvlUp,
17    ReferralDailyReward,
18    GiftClaim,
19    ArenaTicketBuy,
20    ClaimVassalReward,
21    ClaimSuzerainReward,
22    ArenaMatchmakingRefresh,
23    GachaLevelUp,
24    PetCaseLevelUp,
25    BundleClaim,
26    AdReward,
27    Cheat,
28}
29
30#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Tsify)]
31#[tsify(from_wasm_abi, into_wasm_abi)]
32pub enum CurrencyConsumer {
33    AbilityCaseOpen,
34    AbilityCaseSlotUpgrade,
35    ItemCaseOpen,
36    GiftSend,
37    DungeonRaid,
38    DungeonFightEnd,
39    ClassChange,
40    OfferBuy,
41    ItemCaseUpgrade,
42    CaseUpgradeSpeedUp,
43    CaseUpgradeSkip,
44    ArenaFight,
45    ArenaMatchmakingRefresh,
46    ArenaTicketBuy,
47    SkinBuy,
48    AfkInstantReward,
49    StatueRoll,
50    TalentUpgrade,
51    TalentUpgradeSkip,
52    PetCaseOpen,
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Tsify, CustomType)]
56pub struct Currency {
57    #[schemars(schema_with = "id_schema")]
58    pub id: CurrencyId,
59    #[schemars(title = "Название")]
60    pub name: i18n::I18nString,
61    #[schemars(title = "Описание")]
62    pub description: i18n::I18nString,
63    #[schemars(title = "URL картинки", schema_with = "webp_url_schema")]
64    pub icon_url: String,
65    #[schemars(title = "Иконка", schema_with = "asset_currency_icon_schema")]
66    pub icon_path: String,
67}
68
69#[derive(
70    Clone,
71    Debug,
72    Serialize,
73    Deserialize,
74    PartialEq,
75    Eq,
76    Hash,
77    JsonSchema,
78    Tsify,
79    CustomType,
80    Default,
81)]
82pub struct CurrencyUnit {
83    #[schemars(schema_with = "currency_link_id_schema")]
84    pub currency_id: CurrencyId,
85    #[schemars(title = "Количество")]
86    pub amount: i64,
87}
88
89impl PartialOrd for CurrencyUnit {
90    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
91        Some(self.cmp(other))
92    }
93}
94
95impl Ord for CurrencyUnit {
96    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
97        match self.currency_id.cmp(&other.currency_id) {
98            std::cmp::Ordering::Equal => self.amount.cmp(&other.amount),
99            ordering => ordering,
100        }
101    }
102}
103
104pub fn increase_currencies(
105    currencies_to_increase: &mut Vec<CurrencyUnit>,
106    currencies_to_add: &[CurrencyUnit],
107) {
108    for add_currency in currencies_to_add {
109        if let Some(unit) = currencies_to_increase
110            .iter_mut()
111            .find(|unit| unit.currency_id == add_currency.currency_id)
112        {
113            unit.amount += add_currency.amount;
114        } else {
115            currencies_to_increase.push(add_currency.clone());
116        }
117    }
118}
119
120pub fn decrease_currencies(
121    currencies_to_decrease: &mut [CurrencyUnit],
122    currencies_to_subtract: &[CurrencyUnit],
123) -> anyhow::Result<()> {
124    for subtract_currency in currencies_to_subtract {
125        if let Some(unit) = currencies_to_decrease
126            .iter_mut()
127            .find(|unit| unit.currency_id == subtract_currency.currency_id)
128        {
129            if unit.amount < subtract_currency.amount {
130                anyhow::bail!(
131                    "Required currency {subtract_currency:?} is bigger than available {unit:?}"
132                )
133            }
134
135            unit.amount -= subtract_currency.amount;
136        } else {
137            anyhow::bail!("Given currency {subtract_currency:?} isn't present in currencies")
138        }
139    }
140    Ok(())
141}
142
143pub fn force_decrease_currencies(
144    currencies_to_decrease: &mut Vec<CurrencyUnit>,
145    currencies_to_subtract: &[CurrencyUnit],
146) -> anyhow::Result<()> {
147    for subtract_currency in currencies_to_subtract {
148        if let Some(unit) = currencies_to_decrease
149            .iter_mut()
150            .find(|unit| unit.currency_id == subtract_currency.currency_id)
151        {
152            unit.amount -= subtract_currency.amount;
153        }
154    }
155
156    currencies_to_decrease.retain(|unit| unit.amount != 0);
157
158    Ok(())
159}
160
161pub fn check_can_decrease_currencies(
162    available_currencies: &[CurrencyUnit],
163    required_currencies: &[CurrencyUnit],
164) -> bool {
165    for subtract_currency in required_currencies {
166        if let Some(unit) = available_currencies
167            .iter()
168            .find(|unit| unit.currency_id == subtract_currency.currency_id)
169        {
170            if unit.amount < subtract_currency.amount {
171                return false;
172            }
173        } else {
174            return false;
175        }
176    }
177    true
178}
179
180pub fn from_es_currencies(es_currencies: &[ESCurrencyUnit]) -> Vec<CurrencyUnit> {
181    let mut result = vec![];
182    for es_currency in es_currencies.iter() {
183        result.push(CurrencyUnit {
184            currency_id: es_currency.currency_id,
185            amount: es_currency.amount,
186        });
187    }
188    result
189}