configs/
game_settings.rs

1use essences::{
2    currency::CurrencyId, fighting::FightTemplateId, items::AttributeId, offers::ShopTab,
3};
4use schema_loader::{
5    attribute_link_id_array_schema, attribute_link_id_schema, class_id_schema,
6    currency_link_id_array_schema, currency_link_id_schema, fight_template_link_id_schema,
7    script_schema, vassal_task_id_schema,
8};
9use schemars::JsonSchema;
10
11use serde::{Deserialize, Serialize};
12use tsify_next::Tsify;
13
14use crate::validated_types::{PositiveI64, WeightMultiplier};
15
16#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, Tsify)]
17pub struct GameSettings {
18    #[schemars(
19        title = "Скрипт подсчета общей мощи персонажа",
20        schema_with = "script_schema"
21    )]
22    pub character_power_calculate_script: String,
23
24    #[schemars(title = "Скрипт подсчета мощи предмета", schema_with = "script_schema")]
25    pub item_power_calculate_script: String,
26
27    #[schemars(
28        title = "Выражение пассивного понижения лояльности",
29        description = "TimePassedSec - время прошеднее с последнего обновления (сек.)",
30        schema_with = "script_schema"
31    )]
32    pub loyalty_decrease_script: String,
33
34    #[schemars(
35        title = "Выражение вычисления цены предмета",
36        schema_with = "script_schema"
37    )]
38    pub item_price_calculation_expression: String,
39
40    #[schemars(
41        title = "Выражение вычисления опыта предмета",
42        schema_with = "script_schema"
43    )]
44    pub item_experience_calculation_expression: String,
45
46    #[schemars(
47        title = "Обязательные атрибуты предметов",
48        description = "Атрибуты, которые обязательно будут на предметах их сундука",
49        schema_with = "attribute_link_id_array_schema"
50    )]
51    pub required_attributes: Vec<AttributeId>,
52
53    #[schemars(
54        title = "Id вассальной таски брыкания",
55        schema_with = "vassal_task_id_schema"
56    )]
57    pub resist_task_id: uuid::Uuid,
58
59    #[schemars(title = "Id аттрибута хп", schema_with = "attribute_link_id_schema")]
60    pub hp_attribute_id: uuid::Uuid,
61
62    #[schemars(
63        title = "Id тайм скип билетика",
64        schema_with = "currency_link_id_schema"
65    )]
66    pub time_skip_ticket_currency_id: CurrencyId,
67
68    #[schemars(title = "Сколько секунд апгрейда сундука скипает тайм скип билетик")]
69    pub chest_upgrade_skip_ticket_skips_sec: u64,
70
71    #[schemars(
72        title = "Id валюты для скипа прокачки сундука",
73        schema_with = "currency_link_id_schema"
74    )]
75    pub chest_upgrade_skip_currency_id: CurrencyId,
76
77    #[schemars(title = "Сколько секунд апгрейда сундука скипает одна единица валюты")]
78    pub chest_upgrade_skip_currency_skips_sec: u64,
79
80    #[schemars(
81        title = "Выражение получения текущего повторяющегося квеста",
82        schema_with = "script_schema"
83    )]
84    pub get_default_loop_task_id: String,
85
86    // #[schemars(title = "Ключ значения для повторяющихся квестов в custom_values")]
87    // pub loop_tasks_custom_values_key: String,
88
89    // #[schemars(title = "Дефолтное значение для повторяющихся квестов в custom_values")]
90    // pub loop_tasks_custom_values_default_value: i64,
91    #[schemars(
92        title = "Скрипт быстрого эквипа абилок",
93        description = "Скрипт, выбирающий из массива абилок самые эффективные",
94        schema_with = "script_schema"
95    )]
96    pub fast_equip_abilities_script: String,
97
98    #[schemars(
99        title = "Скрипт быстрого эквипа петов",
100        description = "Скрипт, выбирающий из массива петов самых эффективных",
101        schema_with = "script_schema"
102    )]
103    pub fast_equip_pets_script: String,
104
105    #[schemars(title = "Настройки гачи способностей")]
106    pub ability_gacha: AbilityGachaSettings,
107
108    #[schemars(
109        title = "Id валюты для открытия сундука предметов",
110        schema_with = "currency_link_id_schema"
111    )]
112    pub item_case_currency_id: CurrencyId,
113
114    #[schemars(
115        title = "Id изначального класса персонажа",
116        schema_with = "class_id_schema"
117    )]
118    pub initial_class_id: uuid::Uuid,
119
120    #[schemars(title = "Длительность хранения сообщения в часах")]
121    pub chat_message_ttl_secs: u64,
122
123    #[schemars(
124        title = "Id валют для отрисовки на главном экране",
125        schema_with = "currency_link_id_array_schema"
126    )]
127    pub currency_ids_to_show: Vec<CurrencyId>,
128
129    #[schemars(title = "Настройки гачи петов")]
130    pub pet_gacha: PetGachaSettings,
131
132    #[schemars(title = "Длительность паузы между открытиями сундука")]
133    pub auto_chest_pause_duration_ticks: u64,
134
135    #[schemars(
136        title = "Id битвы для арены",
137        schema_with = "fight_template_link_id_schema"
138    )]
139    pub arena_fight_template_id: FightTemplateId,
140
141    #[schemars(
142        title = "Id битвы для вассального pvp",
143        schema_with = "fight_template_link_id_schema"
144    )]
145    pub vassal_fight_id: FightTemplateId,
146
147    #[schemars(title = "Как часто срабатывает эвент fight_progress_tick")]
148    pub fight_progress_tick: u64,
149
150    #[schemars(title = "Частота обновления мощи персонажа в базе")]
151    pub db_power_update_frequency: u64,
152
153    #[schemars(title = "Юзернейм подставляющийся игроку удалившему аккаунт")]
154    pub deleted_user_username: String,
155
156    #[schemars(
157        title = "Id валюты бриллиантов",
158        schema_with = "currency_link_id_schema"
159    )]
160    pub diamond_currency_id: CurrencyId,
161
162    #[schemars(title = "Минимальный интервал между сменами username (секунды)")]
163    pub username_change_cooldown_sec: u64,
164
165    #[schemars(title = "Минимальная длина username")]
166    pub username_min_length: usize,
167
168    #[schemars(title = "Максимальная длина username")]
169    pub username_max_length: usize,
170
171    #[schemars(title = "До какого числа обновлять кол-во ключей у пользователя")]
172    pub dungeons_keys_reset_amount: i64,
173
174    #[schemars(title = "Настройки ежедневного ресета валют")]
175    pub daily_currency_resets: Vec<DailyCurrencyReset>,
176
177    #[schemars(title = "Вкладка магазина, открываемая по умолчанию")]
178    pub default_shop_tab: ShopTab,
179
180    #[schemars(
181        title = "Скрипт выбирающий предмет для выдачи из сундука",
182        schema_with = "script_schema"
183    )]
184    pub chest_item_choose_script: String,
185}
186
187#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, Tsify)]
188pub struct AbilityGachaSettings {
189    #[schemars(
190        title = "Id валюты для открытия гачи скиллов",
191        schema_with = "currency_link_id_schema"
192    )]
193    pub currency_id: CurrencyId,
194
195    #[schemars(title = "Цена 1 крутки в бриллиантах")]
196    pub roll_price_in_diamonds: PositiveI64,
197
198    /// Стоимость маленькой крутки в gacha-билетах.
199    /// Она же — количество дропов и очки прогресса (тикеты = поинты = дропы).
200    #[schemars(title = "Стоимость маленькой крутки")]
201    pub small_roll_cost: PositiveI64,
202
203    /// Стоимость большой крутки в gacha-билетах (она же — очки прогресса).
204    #[schemars(title = "Стоимость большой крутки")]
205    pub big_roll_cost: PositiveI64,
206
207    /// Бонусные дропы в большой крутке сверх стоимости. Итого дропов = cost + bonus.
208    #[schemars(title = "Бонусные дропы в большой крутке")]
209    pub big_roll_bonus_drops: u8,
210
211    /// Максимальное число слотов вишлиста.
212    #[schemars(title = "Количество слотов вишлиста")]
213    pub wishlist_slots: u8,
214
215    /// Множитель веса для способностей из вишлиста при розыгрыше.
216    /// Значение `2.0` означает, что вишлист-абилка выпадает вдвое чаще обычной.
217    #[schemars(title = "Множитель веса вишлиста")]
218    pub wishlist_weight_multiplier: WeightMultiplier,
219
220    /// Валюта для прокачки уровней слотов способностей (Stardust).
221    #[schemars(
222        title = "Валюта прокачки слотов способностей",
223        schema_with = "currency_link_id_schema"
224    )]
225    pub slot_upgrade_currency_id: CurrencyId,
226
227    /// Максимальный уровень слота способности.
228    #[schemars(title = "Максимальный уровень слота способности")]
229    pub slot_max_level: PositiveI64,
230
231    /// Стоимость повышения слота до каждого уровня.
232    /// Индекс `0` соответствует прокачке на уровень `1`.
233    #[schemars(title = "Стоимости уровней слотов способностей")]
234    pub slot_level_costs: Vec<PositiveI64>,
235
236    /// Бонус к `AbilityLevel` по уровню слота.
237    /// Индекс = уровень слота, значение = дополнительный уровень способности.
238    #[schemars(title = "Бонус уровня способности от уровня слота")]
239    pub slot_level_bonus_levels: Vec<i64>,
240}
241
242#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, Tsify)]
243pub struct PetGachaSettings {
244    #[schemars(
245        title = "Id валюты для открытия гачи петов",
246        schema_with = "currency_link_id_schema"
247    )]
248    pub currency_id: CurrencyId,
249
250    #[schemars(title = "Цена 1 крутки в бриллиантах")]
251    pub roll_price_in_diamonds: PositiveI64,
252
253    /// Стоимость маленькой крутки в gacha-билетах.
254    /// Она же — количество дропов и очки прогресса (тикеты = поинты = дропы).
255    #[schemars(title = "Стоимость маленькой крутки")]
256    pub small_roll_cost: PositiveI64,
257
258    /// Стоимость большой крутки в gacha-билетах (она же — очки прогресса).
259    #[schemars(title = "Стоимость большой крутки")]
260    pub big_roll_cost: PositiveI64,
261
262    /// Бонусные дропы в большой крутке сверх стоимости. Итого дропов = cost + bonus.
263    #[schemars(title = "Бонусные дропы в большой крутке")]
264    pub big_roll_bonus_drops: u8,
265
266    /// Максимальное число слотов вишлиста.
267    #[schemars(title = "Количество слотов вишлиста")]
268    pub wishlist_slots: u8,
269
270    /// Множитель веса для петов из вишлиста при розыгрыше.
271    /// Значение `2.0` означает, что вишлист-пет выпадает вдвое чаще обычного.
272    #[schemars(title = "Множитель веса вишлиста")]
273    pub wishlist_weight_multiplier: WeightMultiplier,
274}
275
276#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, Tsify)]
277pub struct DailyCurrencyReset {
278    #[schemars(
279        title = "ID валюты для ресета",
280        schema_with = "currency_link_id_schema"
281    )]
282    pub currency_id: CurrencyId,
283
284    #[schemars(title = "Значение, до которого ресетить валюту")]
285    pub reset_amount: i64,
286}
287
288impl GameSettings {
289    pub fn get_daily_currency_reset_amount(&self, currency_id: CurrencyId) -> anyhow::Result<i64> {
290        self.daily_currency_resets
291            .iter()
292            .find(|reset| reset.currency_id == currency_id)
293            .map(|reset| reset.reset_amount)
294            .ok_or_else(|| {
295                anyhow::anyhow!(
296                    "Currency {} not found in daily_currency_resets",
297                    currency_id
298                )
299            })
300    }
301}