From e41f79f41ad1c0b351fc8c8299ed6b289020363b Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 22 Mar 2020 00:13:31 -0700 Subject: [PATCH] tech drops --- src/entity/item/tech.rs | 2 +- src/login/character.rs | 2 +- src/ship/drops/tech_table.rs | 148 ++++++++++++++++++++++------------- src/ship/drops/tool_table.rs | 13 +-- 4 files changed, 99 insertions(+), 66 deletions(-) diff --git a/src/entity/item/tech.rs b/src/entity/item/tech.rs index c2e3f85..8976904 100644 --- a/src/entity/item/tech.rs +++ b/src/entity/item/tech.rs @@ -1,7 +1,7 @@ use serde::{Serialize, Deserialize}; -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display)] pub enum Technique { Foie, Gifoie, diff --git a/src/login/character.rs b/src/login/character.rs index fe346dd..ce8bbd4 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -22,7 +22,7 @@ use crate::entity::item::weapon::Weapon; use crate::entity::item::armor::Armor; use crate::entity::item::tech::Technique; use crate::entity::item::tool::Tool; -use crate::entity::item::mag::{Mag, MagType, PhotonBlast}; +use crate::entity::item::mag::{Mag, MagType}; use crate::entity::character::{Character, CharacterClass, TechLevel}; use crate::login::login::get_login_status; diff --git a/src/ship/drops/tech_table.rs b/src/ship/drops/tech_table.rs index f739e78..1c5f4df 100644 --- a/src/ship/drops/tech_table.rs +++ b/src/ship/drops/tech_table.rs @@ -20,65 +20,67 @@ struct TechniqueRateStat { max: i32, } - #[derive(Debug, Serialize, Deserialize)] -struct TechniqueRate { - #[serde(rename = "Foie")] - foie: TechniqueRateStat, - #[serde(rename = "Gifoie")] - gifoie: TechniqueRateStat, - #[serde(rename = "Rafoie")] - rafoie: TechniqueRateStat, - #[serde(rename = "Zonde")] - zonde: TechniqueRateStat, - #[serde(rename = "Gizonde")] - gizonde: TechniqueRateStat, - #[serde(rename = "Razonde")] - razonde: TechniqueRateStat, - #[serde(rename = "Barta")] - barta: TechniqueRateStat, - #[serde(rename = "Gibarta")] - gibarta: TechniqueRateStat, - #[serde(rename = "Rabarta")] - rabarta: TechniqueRateStat, - #[serde(rename = "Grants")] - grants: TechniqueRateStat, - #[serde(rename = "Deband")] - deband: TechniqueRateStat, - #[serde(rename = "Jellen")] - jellen: TechniqueRateStat, - #[serde(rename = "Zalure")] - zalure: TechniqueRateStat, - #[serde(rename = "Shifta")] - shifta: TechniqueRateStat, - #[serde(rename = "Ryuker")] - ryuker: TechniqueRateStat, - #[serde(rename = "Resta")] - resta: TechniqueRateStat, - #[serde(rename = "Anti")] - anti: TechniqueRateStat, - #[serde(rename = "Reverser")] - reverser: TechniqueRateStat, - #[serde(rename = "Megid")] - megid: TechniqueRateStat, +struct TechniqueRatesRaw { + area1: BTreeMap, + area2: BTreeMap, + area3: BTreeMap, + area4: BTreeMap, + area5: BTreeMap, + area6: BTreeMap, + area7: BTreeMap, + area8: BTreeMap, + area9: BTreeMap, + area10: BTreeMap, } - - #[derive(Debug, Serialize, Deserialize)] struct TechniqueRates { - area1: TechniqueRate, - area2: TechniqueRate, - area3: TechniqueRate, - area4: TechniqueRate, - area5: TechniqueRate, - area6: TechniqueRate, - area7: TechniqueRate, - area8: TechniqueRate, - area9: TechniqueRate, - area10: TechniqueRate, + area1: BTreeMap, + area2: BTreeMap, + area3: BTreeMap, + area4: BTreeMap, + area5: BTreeMap, + area6: BTreeMap, + area7: BTreeMap, + area8: BTreeMap, + area9: BTreeMap, + area10: BTreeMap, } +impl TechniqueRates { + fn new(rates: TechniqueRatesRaw) -> TechniqueRates { + TechniqueRates { + area1: rates.area1.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area2: rates.area2.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area3: rates.area3.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area4: rates.area4.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area5: rates.area5.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area6: rates.area6.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area7: rates.area7.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area8: rates.area8.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area9: rates.area9.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + area10: rates.area10.into_iter().map(|(tech, rate)| (tech.parse().unwrap(), rate)).collect(), + } + } +} + +impl TechniqueRates { + fn get_by_area<'a>(&'a self, map_area: &MapVariantType) -> &'a BTreeMap { + match map_area.area_value().unwrap() { + 0 => &self.area1, + 1 => &self.area2, + 2 => &self.area3, + 3 => &self.area4, + 4 => &self.area5, + 5 => &self.area6, + 6 => &self.area7, + 7 => &self.area8, + 8 => &self.area9, + _ => &self.area10, + } + } +} pub struct TechniqueTable { rates: TechniqueRates @@ -86,12 +88,48 @@ pub struct TechniqueTable { impl TechniqueTable { pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> TechniqueTable { + let rates: TechniqueRatesRaw = load_data_file(episode, difficulty, section_id, "tech_rate.toml"); + TechniqueTable { - rates: load_data_file(episode, difficulty, section_id, "tech_rate.toml") + rates: TechniqueRates::new(rates), } } - + + pub fn get_drop(&self, map_area: &MapVariantType, rng: &mut R) -> Option { - None + let mut tech_rates = self.rates.get_by_area(map_area).iter(); + let tech_weights = WeightedIndex::new(tech_rates.clone().map(|(_, stat)| stat.rate)).unwrap(); + + let (tech, stat) = tech_rates.nth(tech_weights.sample(rng)).unwrap(); + let level = rng.gen_range(stat.min, stat.max+1); + + Some(ItemDetail::TechniqueDisk(TechniqueDisk { + tech: *tech, + level: level as u32 + })) + } +} + + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_tech_drops() { + let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]); + let tt = TechniqueTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly); + + let tech_tests = vec![(MapVariantType::Forest1, Technique::Resta, 13), + (MapVariantType::Caves3, Technique::Foie, 24), + (MapVariantType::Mines2, Technique::Gibarta, 20), + (MapVariantType::DarkFalz, Technique::Razonde, 22)]; + + for (area, tech, level) in tech_tests { + assert!(tt.get_drop(&area, &mut rng) == Some(ItemDetail::TechniqueDisk( + TechniqueDisk { + tech: tech, + level: level + }))); + } } } diff --git a/src/ship/drops/tool_table.rs b/src/ship/drops/tool_table.rs index 073cb77..b0147c4 100644 --- a/src/ship/drops/tool_table.rs +++ b/src/ship/drops/tool_table.rs @@ -93,12 +93,12 @@ impl ToolTable { } } - pub fn tool_type(&self, map_area: &MapVariantType, rng: &mut R) -> ToolType { + pub fn get_drop(&self, map_area: &MapVariantType, rng: &mut R) -> Option { let tool_rates = self.rates.get_by_area(map_area).iter(); let tool_weights = WeightedIndex::new(tool_rates.clone().map(|(_, weights)| weights)).unwrap(); let tool = tool_rates.map(|(ttype, _)| ttype).nth(tool_weights.sample(rng)).unwrap(); - match tool { + let tool_type = match tool { ToolRateType::Monomate => ToolType::Monomate, ToolRateType::Dimate => ToolType::Dimate, ToolRateType::Trimate => ToolType::Trimate, @@ -124,13 +124,8 @@ impl ToolTable { ToolRateType::LuckMaterial => ToolType::LuckMaterial, ToolRateType::ScapeDoll => ToolType::ScapeDoll, ToolRateType::PhotonDrop => ToolType::PhotonDrop, - ToolRateType::Technique => todo!(), - //ToolRateType::Technique => self.tech_table.get_drop(map_area, rng), - } - } - - pub fn get_drop(&self, map_area: &MapVariantType, rng: &mut R) -> Option { - let tool_type = self.tool_type(map_area, rng); + ToolRateType::Technique => return self.tech_table.get_drop(map_area, rng), + }; Some(ItemDetail::Tool(Tool { tool: tool_type