diff --git a/src/ship/drops/mod.rs b/src/ship/drops/mod.rs index a768a66..8c746be 100644 --- a/src/ship/drops/mod.rs +++ b/src/ship/drops/mod.rs @@ -4,6 +4,8 @@ mod generic_weapon; mod generic_armor; mod generic_shield; mod generic_unit; +mod tool_table; +mod tech_table; use std::collections::HashMap; @@ -27,6 +29,7 @@ use crate::ship::drops::generic_weapon::GenericWeaponTable; use crate::ship::drops::generic_armor::GenericArmorTable; use crate::ship::drops::generic_shield::GenericShieldTable; use crate::ship::drops::generic_unit::GenericUnitTable; +use crate::ship::drops::tool_table::ToolTable; fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf { @@ -128,6 +131,7 @@ struct DropTable { armor_table: GenericArmorTable, shield_table: GenericShieldTable, unit_table: GenericUnitTable, + tool_table: ToolTable, rng: R, } @@ -151,6 +155,7 @@ impl DropTable { armor_table: GenericArmorTable::new(episode, difficulty, section_id), shield_table: GenericShieldTable::new(episode, difficulty, section_id), unit_table: GenericUnitTable::new(episode, difficulty, section_id), + tool_table: ToolTable::new(episode, difficulty, section_id), rng: R::from_entropy(), } } @@ -159,10 +164,6 @@ impl DropTable { None } - fn generate_tool(&self, map_area: &MapVariantType, monster: &MonsterDropStats) -> Option { - None - } - fn generate_typed_drop(&mut self, map_area: &MapVariantType, monster: &MonsterDropStats) -> Option { match monster.drop_type { MonsterDropType::Weapon => self.weapon_table.get_drop(map_area, &mut self.rng), @@ -192,7 +193,7 @@ impl DropTable { self.generate_meseta(&monster_stat) }, 1 => { - self.generate_tool(map_area, &monster_stat) + self.tool_table.get_drop(map_area, &mut self.rng) }, 2 => { self.generate_typed_drop(map_area, &monster_stat) diff --git a/src/ship/drops/tech_table.rs b/src/ship/drops/tech_table.rs new file mode 100644 index 0000000..99acc7b --- /dev/null +++ b/src/ship/drops/tech_table.rs @@ -0,0 +1,39 @@ +use std::collections::{HashMap, BTreeMap}; +use std::io::Read; +use serde::{Serialize, Deserialize}; +use rand::{Rng, SeedableRng}; +use rand::distributions::{WeightedIndex, Distribution}; + +use crate::entity::item::{ItemDetail, Tool as ToolDetail}; +use crate::entity::item::tool::{StackedTool, ToolType}; +use crate::ship::room::{Difficulty, Episode}; +use crate::ship::map::MapVariantType; +use crate::entity::character::SectionID; +use crate::ship::drops::load_data_file; + + + + + + + + + + + + + +pub struct TechniqueTable { + +} + +impl TechniqueTable { + pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> TechniqueTable { + TechniqueTable { + } + } + + pub fn get_drop(&self, map_area: &MapVariantType, rng: &mut R) -> Option { + None + } +} diff --git a/src/ship/drops/tool_table.rs b/src/ship/drops/tool_table.rs new file mode 100644 index 0000000..3757968 --- /dev/null +++ b/src/ship/drops/tool_table.rs @@ -0,0 +1,139 @@ +use std::collections::{HashMap, BTreeMap}; +use std::io::Read; +use serde::{Serialize, Deserialize}; +use rand::{Rng, SeedableRng}; +use rand::distributions::{WeightedIndex, Distribution}; + +use crate::entity::item::{ItemDetail, Tool as ToolDetail}; +use crate::entity::item::tool::{StackedTool, ToolType}; +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::drops::tech_table::TechniqueTable; + + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] +enum ToolRateType { + Monomate, + Dimate, + Trimate, + Monofluid, + Difluid, + Trifluid, + Antidote, + Antiparalysis, + SolAtomizer, + MoonAtomizer, + StarAtomizer, + Telepipe, + TrapVision, + Monogrinder, + Digrinder, + Trigrinder, + PowerMaterial, + MindMaterial, + EvadeMaterial, + HpMaterial, + TpMaterial, + DefMaterial, + LuckMaterial, + ScapeDoll, + Technique, + PhotonDrop, +} + +/*#[derive(Debug, Serialize, Deserialize, Copy, Clone)] +struct ToolRate { + tool: ToolRateType, + rate: u32, +}*/ + +#[derive(Debug, Serialize, Deserialize)] +struct ToolRates { + area1: BTreeMap, + area2: BTreeMap, + area3: BTreeMap, + area4: BTreeMap, + area5: BTreeMap, + area6: BTreeMap, + area7: BTreeMap, + area8: BTreeMap, + area9: BTreeMap, + area10: BTreeMap, +} + +impl ToolRates { + 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 ToolTable { + rates: ToolRates, + tech_table: TechniqueTable, +} + +impl ToolTable { + pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> ToolTable { + ToolTable { + rates: load_data_file(episode, difficulty, section_id, "tool_rate.toml"), + tech_table: TechniqueTable::new(episode, difficulty, section_id), + } + } + + pub fn tool_type(&self, map_area: &MapVariantType, rng: &mut R) -> ToolType { + let tool_rates = self.rates.get_by_area(map_area).iter(); + let tool_weights = WeightedIndex::new(tool_rates.clone().map(|(_, weights)| weights)).unwrap(); + + match tool_rates.map(|(ttype, _)| ttype).nth(tool_weights.sample(rng)).unwrap() { + ToolRateType::Monomate => ToolType::Monomate, + ToolRateType::Dimate => ToolType::Dimate, + ToolRateType::Trimate => ToolType::Trimate, + ToolRateType::Monofluid => ToolType::Monofluid, + ToolRateType::Difluid => ToolType::Difluid, + ToolRateType::Trifluid => ToolType::Trifluid, + ToolRateType::Antidote => ToolType::Antidote, + ToolRateType::Antiparalysis => ToolType::Antiparalysis, + ToolRateType::SolAtomizer => ToolType::SolAtomizer, + ToolRateType::MoonAtomizer => ToolType::MoonAtomizer, + ToolRateType::StarAtomizer => ToolType::StarAtomizer, + ToolRateType::Telepipe => ToolType::Telepipe, + ToolRateType::TrapVision => ToolType::TrapVision, + ToolRateType::Monogrinder => ToolType::Monogrinder, + ToolRateType::Digrinder => ToolType::Digrinder, + ToolRateType::Trigrinder => ToolType::Trigrinder, + ToolRateType::PowerMaterial => ToolType::PowerMaterial, + ToolRateType::MindMaterial => ToolType::MindMaterial, + ToolRateType::EvadeMaterial => ToolType::EvadeMaterial, + ToolRateType::HpMaterial => ToolType::HpMaterial, + ToolRateType::TpMaterial => ToolType::TpMaterial, + ToolRateType::DefMaterial => ToolType::DefMaterial, + ToolRateType::LuckMaterial => ToolType::LuckMaterial, + ToolRateType::ScapeDoll => ToolType::ScapeDoll, + ToolRateType::PhotonDrop => ToolType::PhotonDrop, + ToolRateType::Technique => todo!(), + //ToolRateType::Technique => self.tech_table.get_drop(area, rng), + } + //let attribute_weights = WeightedIndex::new(&[rates.none, rates.native, rates.abeast, rates.machine, rates.dark, rates.hit]).unwrap(); + } + + pub fn get_drop(&self, map_area: &MapVariantType, rng: &mut R) -> Option { + let tool_type = self.tool_type(map_area, rng); + + Some(ItemDetail::Tool(ToolDetail { + tool: tool_type + })) + } +}