rocalc 0.2.1

一款用于计算洛克王国:世界精灵对决的Rust库
Documentation
use crate::enums::*;
use crate::models::car::*;

/// 定义六维面板
#[derive(Debug)] 
pub struct Six {
    pub hp: f32,
    pub atk: f32,
    pub dfe: f32,
    pub m_atk: f32,
    pub m_dfe: f32,
    pub spd: f32,
}

/// 定义性格、六维面板和个体值,用于计算精灵的具体面板数值
#[derive(Debug)]
pub struct Tri{
    pub car: Car, // 性格
    pub rac: Six, // 六维面板
    pub ind: Vec<(Panel, f32)>, 
}

impl Tri {
    /// 创建Tri实例
    pub fn new(car: Car, rac: Six, ind: Vec<(Panel, f32)>) -> Self {
        Self {
            car,
            rac,
            ind,
        }
    }

    /// 依次进行种族值修正、个体值修正、性格修正和常数修正,得到最终的面板数值
    pub fn cor(&mut self) {
        self.rac_cor();
        self.ind_cor();
        self.car_cor();
        self.con_cor();
    }

    /// 种族值修正
    fn rac_cor(&mut self) {
        macro_rules! apply_to_all {
            ( $($field:ident),* ) => {
                $(
                    self.rac.$field = 1.1 * self.rac.$field + 10.0; 
                )*
            };
        }

        self.rac.hp = 1.7 * self.rac.hp + 70.0; 
        apply_to_all!(atk, dfe, m_atk, m_dfe, spd);
    }

    /// 个体值修正
    fn ind_cor(&mut self) {
        for (ind_type, value) in &self.ind {
            match ind_type {
                Panel::Hp => self.rac.hp += value * 6.0 * 0.85,
                Panel::Atk => self.rac.atk += value * 6.0 * 0.55,
                Panel::MAtk => self.rac.m_atk += value * 6.0 * 0.55,
                Panel::Dfe => self.rac.dfe += value * 6.0 * 0.55,
                Panel::MDfe => self.rac.m_dfe += value * 6.0 * 0.55,
                Panel::Spd => self.rac.spd += value * 6.0 * 0.55,
            }
        }
    }

    /// 性格修正
    fn car_cor(&mut self) {
        let keys = get_key(&self.car);
        {
            let plus = get_field_mut(&mut self.rac, keys[0]);
            if let Some(p) = plus {
                *p *= 1.2;
            }
        }

        let sub = get_field_mut(&mut self.rac, keys[1]);
            if let Some(s) = sub {
                *s *= 0.9;
            }
    }

    /// 常数修正
    fn con_cor(&mut self) {
       macro_rules! apply_to_all {
           ( $($field:ident),* ) => {
               $(
                   self.rac.$field += 50.0; 
               )*
           };
       }
        self.rac.hp += 100.0;
        apply_to_all!(atk, dfe, m_atk, m_dfe, spd);
    }

}


/// 简单公式(Simple formula)所需的攻击力、防御值和技能威力
#[derive(Debug)]
pub struct Sfor {
    pub atk: f32,
    pub dfe: f32,
    pub pow: f32,
}

impl Sfor {

    /// 简易公式计算伤害
    pub fn simple_dmg(&self) -> f32 {
        let dmg = (37.0 * self.atk * self.pow / 41.0).round() / self.dfe;
        return dmg;
    }
}

/// 复杂公式(Complex formula)
#[derive(Debug)]
pub struct Cfor {
    pub atk: f32, // 攻击力
    pub dfe: f32, // 防御力
    pub pow: f32, // 技能威力
    pub deal: f32, // 应对倍率(技能效果)
    pub pow_appd: f32, // 技能威力附加(技能效果)
    pub atk_buff: f32, // 攻击加成
    pub dfe_buff: f32, // 防御加成
    pub pow_buff: f32, // 技能威力加成
    pub prop: f32, // 本系加成,若有取1.25
    pub count: f32, // 克制加成,若有取2.0或3.0 
    pub reduce: f32, // 减伤
}

impl Cfor {
    /// 创建复杂公式,输入攻击值、防御值和技能威力,剩余值为默认
    pub fn new(atk: f32, dfe:f32, pow:f32) -> Self {
        Self {
            atk,
            dfe,
            pow,
            deal: 1.0,
            pow_appd: 0.0,
            atk_buff: 1.0,
            dfe_buff: 1.0,
            pow_buff: 1.0,
            prop: 1.0,
            count: 1.0,
            reduce: 0.0,
        }
    }

    /// 计算伤害
    pub fn cal(&self) -> f32 {
        (37.0 * (self.atk * self.atk_buff) * (self.pow * self.deal + self.pow_appd) * self.pow_buff * self.prop * self.count * (1.0 - self.reduce)).round() / 41.0 / (self.dfe * self.dfe_buff)
    }

}