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}