essences/
effect.rs

1use crate::prelude::*;
2
3use crate::entity::EntityAttributes;
4
5#[declare]
6pub type EffectId = Uuid;
7
8#[derive(
9    Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Tsify, JsonSchema, i18n::Translate,
10)]
11pub struct Effect {
12    #[schemars(schema_with = "id_schema")]
13    pub id: EffectId,
14    #[schemars(title = "Имя эффекта")]
15    #[translate]
16    pub name: i18n::I18nString,
17    #[schemars(
18        title = "Нативная функция эффекта",
19        description = "Имя нативной функции категории event, выполняющей эффект.",
20        schema_with = "event_ref_schema"
21    )]
22    #[serde(default)]
23    pub behavior: Option<String>,
24    #[schemars(title = "Ссылка на иконку эффекта", schema_with = "webp_url_schema")]
25    pub icon_url: String,
26    #[schemars(title = "Иконка", schema_with = "asset_ui_status_icon_schema")]
27    pub icon_path: String,
28    #[schemars(title = "Код эффекта")]
29    pub code: String,
30    #[schemars(
31        title = "Опциональный интервал в тиках",
32        description = "Если указан – эффект будет выполняться в кроне с заданным интервалом"
33    )]
34    pub interval_ticks: Option<u64>,
35    #[schemars(
36        title = "Необходимые для эффекта аттрибуты",
37        description = "Эффект остановится при отсутствии перечисленных аттрибутов на Entity"
38    )]
39    pub required_attributes: Option<Vec<String>>,
40    #[schemars(title = "Опциональная подписка на ивенты")]
41    pub events_subscribe: Option<Vec<String>>,
42    #[schemars(title = "Является ли эффект позитивным/негативным")]
43    pub positive: bool,
44    #[schemars(
45        title = "Боевой VFX эффекта",
46        description = "Путь к VFX, проигрывающемуся однократно при наложении эффекта"
47    )]
48    pub vfx_path: String,
49
50    #[schemars(
51        title = "Максимальная длительность (сек)",
52        description = "Потолок длительности эффекта в секундах. Конвертируется в max_duration_ticks (мс) = duration * 1000. null = дефолт 5 сек."
53    )]
54    #[serde(default)]
55    pub duration: Option<i64>,
56}
57
58impl Effect {
59    pub fn has_at_least_one_required_attribute(&self, attributes: &EntityAttributes) -> bool {
60        if let Some(required_attributes) = &self.required_attributes {
61            let contains_at_least_one = required_attributes
62                .iter()
63                .any(|attr| attributes.0.contains_key(attr));
64            return contains_at_least_one;
65        }
66        true
67    }
68}