You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
5.9 KiB

use std::collections::BTreeMap;
use serde::{Serialize, Deserialize};
use rand::Rng;
use rand::distributions::{WeightedIndex, Distribution};
use entity::item::tool::{Tool, ToolType};
use maps::room::{Difficulty, Episode};
use maps::area::MapArea;
use entity::character::SectionID;
use crate::{ItemDropType, load_data_file};
use crate::tech_table::TechniqueTable;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, enum_utils::FromStr)]
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 ToolRatesRaw {
area1: BTreeMap<String, u32>,
area2: BTreeMap<String, u32>,
area3: BTreeMap<String, u32>,
area4: BTreeMap<String, u32>,
area5: BTreeMap<String, u32>,
area6: BTreeMap<String, u32>,
area7: BTreeMap<String, u32>,
area8: BTreeMap<String, u32>,
area9: BTreeMap<String, u32>,
area10: BTreeMap<String, u32>,
}
struct ToolRates {
area1: BTreeMap<ToolRateType, u32>,
area2: BTreeMap<ToolRateType, u32>,
area3: BTreeMap<ToolRateType, u32>,
area4: BTreeMap<ToolRateType, u32>,
area5: BTreeMap<ToolRateType, u32>,
area6: BTreeMap<ToolRateType, u32>,
area7: BTreeMap<ToolRateType, u32>,
area8: BTreeMap<ToolRateType, u32>,
area9: BTreeMap<ToolRateType, u32>,
area10: BTreeMap<ToolRateType, u32>,
}
impl ToolRates {
fn new(raw: ToolRatesRaw) -> ToolRates {
ToolRates {
area1: raw.area1.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area2: raw.area2.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area3: raw.area3.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area4: raw.area4.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area5: raw.area5.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area6: raw.area6.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area7: raw.area7.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area8: raw.area8.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area9: raw.area9.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
area10: raw.area10.into_iter().map(|(name, rate)| (name.parse().unwrap(), rate)).collect(),
}
}
}
impl ToolRates {
fn get_by_area<'a>(&'a self, map_area: &MapArea) -> &'a BTreeMap<ToolRateType, u32> {
match map_area.drop_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 {
let rates = load_data_file(episode, difficulty, section_id, "tool_rate.toml");
ToolTable {
rates: ToolRates::new(rates),
tech_table: TechniqueTable::new(episode, difficulty, section_id),
}
}
pub fn get_drop<R: Rng>(&self, map_area: &MapArea, rng: &mut R) -> Option<ItemDropType> {
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();
let tool_type = match tool {
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 => return self.tech_table.get_drop(map_area, rng),
};
Some(ItemDropType::Tool(Tool {
tool: tool_type
}))
}
}