use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::Stat;
use crate::error::{DeepError, Result};
use crate::model::enums::{EquipmentSlot, ItemRarity, MantraType, RangeType, TalentRarity, WeaponType};
use crate::model::req::Requirement;
use crate::util::name_to_identifier;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AspectVariantInfo {
name: String,
unlock: Option<String>,
colors: HashMap<String, String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Aspect {
pub name: String,
pub desc: String,
pub innate: HashMap<Stat, i64>,
pub is_pathfinder: bool,
pub variants: HashMap<String, AspectVariantInfo>,
#[serde(default)]
pub talent: Vec<String>,
#[serde(default)]
pub exclude_cosmetics: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct StatValue {
pub value: f64,
pub percentage: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Outfit {
pub name: String,
#[serde(default)]
pub pants_id: Option<String>,
#[serde(default)]
pub shirt_id: Option<String>,
pub category: String,
pub durability: i64,
pub resistances: HashMap<String, f64>,
pub extra_percents: HashMap<String, i64>,
pub talent: Option<String>,
#[serde(default)]
pub variants: Vec<String>,
pub reqs: Requirement,
pub mats: HashMap<String, i64>,
pub notes: i64,
#[serde(default)]
pub voi: bool,
#[serde(default)]
pub voi_only: bool,
pub desc: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Equipment {
pub name: String,
pub equippable: bool,
#[serde(rename = "type")]
pub equipment_type: EquipmentSlot,
pub rarity: ItemRarity,
pub set: Option<String>,
#[serde(default)]
pub variants: Vec<String>,
#[serde(default)]
pub talents: Vec<String>,
#[serde(default)]
pub innates: HashMap<String, StatValue>,
#[serde(default)]
pub pips: HashMap<String, i64>,
pub reqs: Requirement,
pub voi: bool,
#[serde(default)]
pub voi_only: bool,
pub desc: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Talent {
pub name: String,
pub desc: String,
pub rarity: TalentRarity,
pub category: String,
pub reqs: Requirement,
pub count_towards_talent_total: bool,
pub vaulted: bool,
pub voi: bool,
#[serde(default)]
pub voi_only: bool,
#[serde(default)]
pub implicit: bool,
#[serde(default)]
pub exclusive: Vec<String>,
#[serde(default)]
pub stats: HashMap<String, f64>,
#[serde(default)]
pub additional_info: Option<String>,
#[serde(default)]
pub icon: Option<String>,
#[serde(default)]
pub roll2able: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Weapon {
pub name: String,
#[serde(rename = "type")]
pub weapon_type: WeaponType,
pub rarity: ItemRarity,
pub damage: Option<f64>,
pub posture_damage: Option<f64>,
pub range: Option<f64>,
pub reqs: Requirement,
pub enchantable: bool,
pub equip_motifs: bool,
pub voi: bool,
#[serde(default)]
pub voi_only: bool,
pub desc: String,
#[serde(default)]
pub damage_types: Vec<String>,
#[serde(default)]
pub range_type: Option<RangeType>,
#[serde(default)]
pub attack_duration: Option<f64>,
#[serde(default)]
pub endlag: Option<f64>,
#[serde(default)]
pub swing_speed: Option<f64>,
#[serde(default)]
pub scaling: HashMap<String, f64>,
#[serde(default)]
pub bleed_damage: Option<f64>,
#[serde(default)]
pub chip_damage: Option<f64>,
#[serde(default)]
pub penetration: Option<f64>,
#[serde(default)]
pub posture_max: Option<f64>,
#[serde(default)]
pub posture_restoration: Option<f64>,
#[serde(default)]
pub talents: Vec<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MantraDamageLevel {
pub level: String,
pub damage: f64,
pub posture_damage: Option<f64>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MantraDamageVariant {
pub variant: Option<String>,
pub levels: Vec<MantraDamageLevel>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Mantra {
pub name: String,
pub desc: String,
pub stars: i64,
pub category: String,
#[serde(rename = "type")]
pub mantra_type: MantraType,
pub attributes: Vec<String>,
pub reqs: Requirement,
pub vaulted: bool,
pub voi: bool,
#[serde(default)]
pub voi_only: bool,
#[serde(default)]
pub damage: Vec<MantraDamageVariant>,
#[serde(default)]
pub scaling: HashMap<String, f64>,
#[serde(default)]
pub modifiers: Vec<String>,
#[serde(default)]
pub sparks: Vec<String>,
#[serde(default)]
pub related_talents: Vec<String>,
#[serde(default)]
pub shared_cooldowns: Vec<String>,
#[serde(default)]
pub miscellaneous: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Enchant {
pub name: String,
pub category: String,
pub info: String,
#[serde(default)]
pub in_game_desc: Option<String>,
#[serde(default)]
pub obtainable_in: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Preset {
pub name: String,
pub desc: String,
pub opts: String,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct DeepData {
aspects: HashMap<String, Aspect>,
talents: HashMap<String, Talent>,
mantras: HashMap<String, Mantra>,
weapons: HashMap<String, Weapon>,
outfits: HashMap<String, Outfit>,
equipment: HashMap<String, Equipment>,
enchants: HashMap<String, Enchant>,
presets: HashMap<String, Preset>,
#[serde(skip, default)]
raw: String,
}
impl DeepData {
pub fn from_json(json: &str) -> Result<DeepData> {
let mut ret: DeepData = serde_json::from_str(json).map_err(DeepError::from)?;
ret.raw = json.to_string();
Ok(ret)
}
#[cfg(feature = "static")]
pub fn bundled() -> DeepData {
DeepData::from_json(include_str!("../../assets/all.json"))
.expect("bundled all.json failed to parse")
}
pub fn raw(&self) -> &String {
&self.raw
}
#[must_use]
pub fn get_talent(&self, name: &str) -> Option<&Talent> {
self.talents.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_mantra(&self, name: &str) -> Option<&Mantra> {
self.mantras.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_weapon(&self, name: &str) -> Option<&Weapon> {
self.weapons.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_outfit(&self, name: &str) -> Option<&Outfit> {
self.outfits.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_equipment(&self, name: &str) -> Option<&Equipment> {
self.equipment.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_aspect(&self, name: &str) -> Option<&Aspect> {
self.aspects.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_enchant(&self, name: &str) -> Option<&Enchant> {
self.enchants.get(&name_to_identifier(name))
}
#[must_use]
pub fn get_preset(&self, name: &str) -> Option<&Preset> {
self.presets.get(&name_to_identifier(name))
}
pub fn talents(&self) -> impl Iterator<Item = &Talent> {
self.talents.values()
}
pub fn mantras(&self) -> impl Iterator<Item = &Mantra> {
self.mantras.values()
}
pub fn weapons(&self) -> impl Iterator<Item = &Weapon> {
self.weapons.values()
}
pub fn outfits(&self) -> impl Iterator<Item = &Outfit> {
self.outfits.values()
}
pub fn equipment(&self) -> impl Iterator<Item = &Equipment> {
self.equipment.values()
}
pub fn aspects(&self) -> impl Iterator<Item = &Aspect> {
self.aspects.values()
}
pub fn enchants(&self) -> impl Iterator<Item = &Enchant> {
self.enchants.values()
}
pub fn presets(&self) -> impl Iterator<Item = &Preset> {
self.presets.values()
}
}