Skip to main content

genshin_calc_core/
lib.rs

1//! # genshin-calc-core
2//!
3//! Damage and elemental reaction calculation engine for Genshin Impact.
4//!
5//! ## Calculation Pipelines
6//!
7//! | Pipeline | Function | Reactions |
8//! |----------|----------|-----------|
9//! | Standard | [`calculate_damage`] | Amplifying (vaporize/melt), Catalyze (spread/aggravate), or none |
10//! | Transformative | [`calculate_transformative`] | Overloaded, superconduct, electro-charged, swirl, bloom, etc. |
11//! | Lunar | [`calculate_lunar`] | Lunar electro-charged, lunar bloom, lunar crystallize |
12//!
13//! Standard damage passes through ATK/HP/DEF scaling, crit, defense, and resistance.
14//! Transformative damage scales with character level and elemental mastery only (no crit, no defense).
15//! Lunar damage scales like transformative but can crit.
16//!
17//! ## Team Composition
18//!
19//! Build teams with [`TeamMember`] and resolve buffs with [`resolve_team_stats`]:
20//!
21//! ```
22//! use genshin_calc_core::*;
23//!
24//! let dps = TeamMember {
25//!     element: Element::Pyro,
26//!     weapon_type: WeaponType::Claymore,
27//!     stats: StatProfile {
28//!         base_atk: 900.0,
29//!         crit_rate: 0.60,
30//!         crit_dmg: 1.50,
31//!         energy_recharge: 1.0,
32//!         ..Default::default()
33//!     },
34//!     buffs_provided: vec![],
35//!     is_moonsign: false,
36//!     can_nightsoul: false,
37//! };
38//! let support = TeamMember {
39//!     element: Element::Pyro,
40//!     weapon_type: WeaponType::Sword,
41//!     stats: StatProfile {
42//!         base_atk: 800.0,
43//!         energy_recharge: 1.0,
44//!         ..Default::default()
45//!     },
46//!     buffs_provided: vec![ResolvedBuff {
47//!         source: "Bennett Burst".into(),
48//!         stat: BuffableStat::AtkFlat,
49//!         value: 1000.0,
50//!         target: BuffTarget::Team,
51//!         origin: None,
52//!     }],
53//!     is_moonsign: false,
54//!     can_nightsoul: false,
55//! };
56//! let result = resolve_team_stats(&[dps, support], 0, &[]).unwrap();
57//! assert!(result.final_stats.atk > 900.0); // DPS gets Bennett's ATK buff
58//! ```
59//!
60//! ## Example
61//!
62//! ```
63//! use genshin_calc_core::*;
64//!
65//! let input = DamageInput {
66//!     character_level: 90,
67//!     stats: Stats {
68//!         atk: 2000.0,
69//!         crit_rate: 0.75,
70//!         crit_dmg: 1.50,
71//!         dmg_bonus: 0.466,
72//!         ..Default::default()
73//!     },
74//!     talent_multiplier: 1.76,
75//!     scaling_stat: ScalingStat::Atk,
76//!     damage_type: DamageType::Skill,
77//!     element: Some(Element::Pyro),
78//!     reaction: None,
79//!     reaction_bonus: 0.0,
80//!     flat_dmg: 0.0,
81//! };
82//! let enemy = Enemy {
83//!     level: 90,
84//!     resistance: 0.10,
85//!     def_reduction: 0.0,
86//!     def_ignore: 0.0,
87//! };
88//! let result = calculate_damage(&input, &enemy).unwrap();
89//! assert!(result.average > 0.0);
90//! ```
91
92#![deny(missing_docs)]
93
94/// Buffable stat types for team buffs.
95pub mod buff_types;
96/// Standard damage calculation pipeline.
97pub mod damage;
98/// Elemental mastery bonus formulas.
99pub mod em;
100/// Enemy parameters and debuff application.
101pub mod enemy;
102/// Error types for calculation failures.
103pub mod error;
104/// Character level to reaction base value table.
105pub mod level_table;
106/// Lunar reaction damage calculation pipeline.
107pub mod lunar;
108/// Moonsign character system types and calculations.
109pub mod moonsign;
110/// Elemental reaction types and properties.
111pub mod reaction;
112/// Elemental resonance system.
113pub mod resonance;
114/// Stat profile (base/percent/flat breakdown) and combination.
115pub mod stat_profile;
116/// Final combined character stats.
117pub mod stats;
118/// Team composition and buff resolution.
119pub mod team;
120/// Transformative reaction damage calculation pipeline.
121pub mod transformative;
122/// Core type enums: Element, DamageType, ScalingStat, WeaponType.
123pub mod types;
124
125pub use buff_types::BuffableStat;
126pub use damage::{DamageInput, DamageResult, calculate_damage, collect_flat_dmg};
127pub use em::{amplifying_em_bonus, catalyze_em_bonus, lunar_em_bonus, transformative_em_bonus};
128pub use enemy::{
129    Enemy, EnemyDebuffs, apply_debuffs_to_enemy, apply_enemy_debuffs, superconduct_debuff,
130};
131pub use error::CalcError;
132pub use level_table::reaction_base_value;
133pub use lunar::{LunarInput, LunarResult, calculate_lunar};
134pub use moonsign::{
135    LunarContribution, MoonsignBenediction, MoonsignContext, MoonsignLevel, MoonsignTalentEffect,
136    MoonsignTalentEnhancement, NonMoonsignLunarBuff, apply_moonsign_enhancements,
137    calculate_lunar_team, calculate_non_moonsign_bonus, determine_moonsign_level,
138    non_moonsign_scaling, resolve_moonsign_context, select_non_moonsign_buff,
139};
140pub use reaction::{Reaction, ReactionCategory, determine_reaction};
141pub use resonance::{
142    ElementalResonance, determine_resonances, resonance_buffs, resonance_conditional_buffs,
143};
144pub use stat_profile::{StatProfile, combine_stats};
145pub use stats::Stats;
146pub use team::{
147    BuffTarget, DamageContext, ResolvedBuff, TeamMember, TeamResolveResult, apply_buffs_to_profile,
148    resolve_team_stats, resolve_team_stats_detailed,
149};
150pub use transformative::{TransformativeInput, TransformativeResult, calculate_transformative};
151pub use types::{DamageType, Element, ScalingStat, WeaponType};
152
153#[cfg(test)]
154mod tests {
155    use super::*;
156
157    #[test]
158    fn test_public_api_usage_example() {
159        let stats = Stats {
160            hp: 20000.0,
161            atk: 2000.0,
162            def: 800.0,
163            elemental_mastery: 100.0,
164            crit_rate: 0.75,
165            crit_dmg: 1.50,
166            energy_recharge: 1.20,
167            dmg_bonus: 0.466,
168            ..Default::default()
169        };
170
171        let input = DamageInput {
172            character_level: 90,
173            stats,
174            talent_multiplier: 1.76,
175            scaling_stat: ScalingStat::Atk,
176            damage_type: DamageType::Skill,
177            element: Some(Element::Pyro),
178            reaction: None,
179            reaction_bonus: 0.0,
180            flat_dmg: 0.0,
181        };
182
183        let enemy = Enemy {
184            level: 90,
185            resistance: 0.10,
186            def_reduction: 0.0,
187            def_ignore: 0.0,
188        };
189
190        let result = calculate_damage(&input, &enemy).unwrap();
191        assert!(result.non_crit > 0.0);
192        assert!(result.crit > result.non_crit);
193        assert!(result.average > result.non_crit);
194        assert!(result.average < result.crit);
195    }
196}