Skip to main content

esf_dogma_engine/
projection.rs

1//! Projection of buffs and effects.
2
3use std::collections::BTreeMap;
4
5use serde::{Deserialize, Serialize};
6
7#[cfg(feature = "typescript")]
8use tsify::Tsify;
9
10use crate::fit::id_map;
11
12/// The external buffs and effects that can be applied to another ship.
13///
14/// A calculation reports what the fit hands out; put that in
15/// [`Fit::incoming`](crate::Fit::incoming) of another fit to have it applied.
16#[cfg_attr(feature = "typescript", derive(Tsify))]
17#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
18pub struct Projection {
19    /// Buffs, like command burst hands.
20    #[serde(default, skip_serializing_if = "Vec::is_empty")]
21    pub buffs: Vec<ProjectedBuff>,
22    /// Effects, like webifiers, remote reps, etc.
23    #[serde(default, skip_serializing_if = "Vec::is_empty")]
24    pub effects: Vec<ProjectedEffect>,
25}
26
27/// A projected buff (like command bursts).
28#[cfg_attr(feature = "typescript", derive(Tsify))]
29#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
30pub struct ProjectedBuff {
31    /// Which buff, as `dbuffCollections` in the SDE numbers them.
32    pub id: i32,
33    /// How strong it is, in whatever the buff's operation reads.
34    pub value: f64,
35}
36
37/// A projected dogma effect.
38#[cfg_attr(feature = "typescript", derive(Tsify))]
39#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
40pub struct ProjectedEffect {
41    /// The type the effect belongs to.
42    pub type_id: i32,
43    /// Which effect, as `dogmaEffects` in the SDE numbers them.
44    pub effect_id: i32,
45    /// Every attribute and its value the effect reads.
46    #[serde(default, deserialize_with = "id_map")]
47    #[cfg_attr(
48        feature = "typescript",
49        tsify(type = "Map<number, number> | Record<number, number>")
50    )]
51    pub attributes: BTreeMap<i32, f64>,
52}
53
54impl Projection {
55    /// Whether nothing is projected.
56    pub fn is_empty(&self) -> bool {
57        self.buffs.is_empty() && self.effects.is_empty()
58    }
59
60    /// Take everything from another projection.
61    pub fn extend(&mut self, other: Projection) {
62        self.buffs.extend(other.buffs);
63        self.effects.extend(other.effects);
64    }
65}