diff --git a/src/ship/drops/generic_armor.rs b/src/ship/drops/generic_armor.rs index 96ab323..7ade196 100644 --- a/src/ship/drops/generic_armor.rs +++ b/src/ship/drops/generic_armor.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use serde::{Serialize, Deserialize}; use rand::{Rng, SeedableRng}; use rand::distributions::{WeightedIndex, Distribution}; @@ -8,6 +9,7 @@ use crate::ship::room::{Difficulty, Episode}; use crate::ship::map::MapVariantType; use crate::entity::character::SectionID; use crate::ship::drops::load_data_file; +use crate::ship::item_stats::{armor_stats, ArmorStats}; #[derive(Debug, Serialize, Deserialize)] @@ -33,11 +35,15 @@ pub struct GenericArmorTable { rank_rates: ArmorRankRates, slot_rates: ArmorSlotRanks, armor_set: u32, + #[serde(skip)] + armor_stats: HashMap, } impl GenericArmorTable { pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> GenericArmorTable { - load_data_file(episode, difficulty, section_id, "armor_rate.toml") + let mut gat: GenericArmorTable = load_data_file(episode, difficulty, section_id, "armor_rate.toml"); + gat.armor_stats = armor_stats(); + gat } fn armor_type(&self, area_map: &MapVariantType, rng: &mut R) -> ArmorType { @@ -81,13 +87,15 @@ impl GenericArmorTable { } // TODO: this needs the pmt file - fn dfp_modifier(&self, armor_type: &ArmorType, rng: &mut R) -> usize { - 0 + fn dfp_modifier(&self, armor_type: &ArmorType, rng: &mut R) -> u32 { + let stats = self.armor_stats.get(armor_type).unwrap(); + rng.gen_range(0, stats.dfp_modifier) } // TODO: this needs the pmt file - fn evp_modifier(&self, armor_type: &ArmorType, rng: &mut R) -> usize { - 0 + fn evp_modifier(&self, armor_type: &ArmorType, rng: &mut R) -> u32 { + let stats = self.armor_stats.get(armor_type).unwrap(); + rng.gen_range(0, stats.evp_modifier) } pub fn get_drop(&self, area_map: &MapVariantType, rng: &mut R) -> Option { @@ -109,3 +117,50 @@ impl GenericArmorTable { } } + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_armor_generation() { + let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]); + + let gat = GenericArmorTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly); + assert!(gat.get_drop(&MapVariantType::Mines1, &mut rng) == Some(ItemDetail::Armor(ArmorDetail { + equipped: false, + armor: Armor { + armor: ArmorType::GeneralArmor, + dfp: 0, + evp: 0, + slots: 1, + } + }))); + assert!(gat.get_drop(&MapVariantType::Caves3, &mut rng) == Some(ItemDetail::Armor(ArmorDetail { + equipped: false, + armor: Armor { + armor: ArmorType::AbsorbArmor, + dfp: 1, + evp: 1, + slots: 1, + } + }))); + assert!(gat.get_drop(&MapVariantType::Forest2, &mut rng) == Some(ItemDetail::Armor(ArmorDetail { + equipped: false, + armor: Armor { + armor: ArmorType::HyperFrame, + dfp: 0, + evp: 0, + slots: 0, + } + }))); + assert!(gat.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDetail::Armor(ArmorDetail { + equipped: false, + armor: Armor { + armor: ArmorType::ImperialArmor, + dfp: 2, + evp: 1, + slots: 0, + } + }))); + } +} diff --git a/src/ship/drops/generic_shield.rs b/src/ship/drops/generic_shield.rs index a9851c7..0169626 100644 --- a/src/ship/drops/generic_shield.rs +++ b/src/ship/drops/generic_shield.rs @@ -1,4 +1,4 @@ - +use std::collections::HashMap; use serde::{Serialize, Deserialize}; use rand::{Rng, SeedableRng}; use rand::distributions::{WeightedIndex, Distribution}; @@ -9,6 +9,7 @@ use crate::ship::room::{Difficulty, Episode}; use crate::ship::map::MapVariantType; use crate::entity::character::SectionID; use crate::ship::drops::load_data_file; +use crate::ship::item_stats::{shield_stats, ShieldStats}; #[derive(Debug, Serialize, Deserialize)] @@ -24,11 +25,15 @@ struct ShieldRankRates { pub struct GenericShieldTable { rank_rates: ShieldRankRates, shield_set: u32, + #[serde(skip)] + shield_stats: HashMap, } impl GenericShieldTable { pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> GenericShieldTable { - load_data_file(episode, difficulty, section_id, "shield_rate.toml") + let mut gst: GenericShieldTable = load_data_file(episode, difficulty, section_id, "shield_rate.toml"); + gst.shield_stats = shield_stats(); + gst } fn shield_type(&self, area_map: &MapVariantType, rng: &mut R) -> ShieldType { @@ -63,13 +68,15 @@ impl GenericShieldTable { } // TODO: this needs the pmt file - fn dfp_modifier(&self, shield_type: &ShieldType, rng: &mut R) -> usize { - 0 + fn dfp_modifier(&self, shield_type: &ShieldType, rng: &mut R) -> u32 { + let stats = self.shield_stats.get(shield_type).unwrap(); + rng.gen_range(0, stats.dfp_modifier) } // TODO: this needs the pmt file - fn evp_modifier(&self, shield_type: &ShieldType, rng: &mut R) -> usize { - 0 + fn evp_modifier(&self, shield_type: &ShieldType, rng: &mut R) -> u32 { + let stats = self.shield_stats.get(shield_type).unwrap(); + rng.gen_range(0, stats.evp_modifier) } pub fn get_drop(&self, area_map: &MapVariantType, rng: &mut R) -> Option { @@ -88,3 +95,52 @@ impl GenericShieldTable { })) } } + + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_shield_generation() { + let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]); + + let gst = GenericShieldTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly); + //println!("{:?}", gst.get_drop(&MapVariantType::Forest1, &mut rng)); + //println!("{:?}", gst.get_drop(&MapVariantType::Caves3, &mut rng)); + //println!("{:?}", gst.get_drop(&MapVariantType::Mines2, &mut rng)); + //println!("{:?}", gst.get_drop(&MapVariantType::DarkFalz, &mut rng)); + + assert!(gst.get_drop(&MapVariantType::Forest1, &mut rng) == Some(ItemDetail::Shield(ShieldDetail { + equipped: false, + shield: Shield { + shield: ShieldType::FreezeBarrier, + dfp: 4, + evp: 1, + } + }))); + assert!(gst.get_drop(&MapVariantType::Caves3, &mut rng) == Some(ItemDetail::Shield(ShieldDetail { + equipped: false, + shield: Shield { + shield: ShieldType::PsychicBarrier, + dfp: 3, + evp: 2, + } + }))); + assert!(gst.get_drop(&MapVariantType::Mines2, &mut rng) == Some(ItemDetail::Shield(ShieldDetail { + equipped: false, + shield: Shield { + shield: ShieldType::ImperialBarrier, + dfp: 0, + evp: 4, + } + }))); + assert!(gst.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDetail::Shield(ShieldDetail { + equipped: false, + shield: Shield { + shield: ShieldType::DivinityBarrier, + dfp: 1, + evp: 0, + } + }))); + } +} diff --git a/src/ship/item_stats.rs b/src/ship/item_stats.rs index 9bcb49b..f7744d3 100644 --- a/src/ship/item_stats.rs +++ b/src/ship/item_stats.rs @@ -22,35 +22,35 @@ struct WeaponStats { } #[derive(Debug, Copy, Clone, Serialize, Deserialize)] -struct ArmorStats { - stars: u32, - dfp: i32, - evp: i32, - dfp_modifier: u32, - evp_modifier: u32, - team_points: u32, - level_req: u32, - efr: i32, - eic: i32, - eth: i32, - elt: i32, - edk: i32, +pub struct ArmorStats { + pub stars: u32, + pub dfp: i32, + pub evp: i32, + pub dfp_modifier: u32, + pub evp_modifier: u32, + pub team_points: u32, + pub level_req: u32, + pub efr: i32, + pub eic: i32, + pub eth: i32, + pub elt: i32, + pub edk: i32, } #[derive(Debug, Copy, Clone, Serialize, Deserialize)] -struct ShieldStats { - stars: u32, - dfp: i32, - evp: i32, - dfp_modifier: u32, - evp_modifier: u32, - team_points: u32, - level_req: u32, - efr: i32, - eic: i32, - eth: i32, - elt: i32, - edk: i32, +pub struct ShieldStats { + pub stars: u32, + pub dfp: i32, + pub evp: i32, + pub dfp_modifier: u32, + pub evp_modifier: u32, + pub team_points: u32, + pub level_req: u32, + pub efr: i32, + pub eic: i32, + pub eth: i32, + pub elt: i32, + pub edk: i32, } #[derive(Debug, Copy, Clone, Serialize, Deserialize)] @@ -63,7 +63,7 @@ struct UnitStats { } -fn armor_stats() -> HashMap { +pub fn armor_stats() -> HashMap { let armor_stats: HashMap = load_data_file("data/item_stats/armor_stats.toml"); armor_stats.iter() .map(|(name, stats)| { @@ -71,7 +71,7 @@ fn armor_stats() -> HashMap { }).collect() } -fn shield_stats() -> HashMap { +pub fn shield_stats() -> HashMap { let shield_stats: HashMap = load_data_file("data/item_stats/shield_stats.toml"); shield_stats.iter() .map(|(name, stats)| {