191 lines
4.8 KiB
Rust
191 lines
4.8 KiB
Rust
|
mod drop_table;
|
||
|
mod rare_drop_table;
|
||
|
mod generic_weapon;
|
||
|
mod generic_armor;
|
||
|
mod generic_shield;
|
||
|
|
||
|
|
||
|
use std::collections::HashMap;
|
||
|
use std::fs::File;
|
||
|
use std::path::PathBuf;
|
||
|
use std::io::Read;
|
||
|
use serde::{Serialize, Deserialize};
|
||
|
use rand::{Rng, SeedableRng};
|
||
|
use rand::distributions::{WeightedIndex, Distribution};
|
||
|
|
||
|
use crate::ship::monster::MonsterType;
|
||
|
use crate::ship::room::{Difficulty, Episode};
|
||
|
use crate::entity::item::ItemDetail;
|
||
|
use crate::entity::item::weapon::{WeaponType, Attribute, WeaponAttribute, WeaponSpecial};
|
||
|
use crate::entity::item::armor::ArmorType;
|
||
|
use crate::entity::item::shield::ShieldType;
|
||
|
use crate::entity::item::unit::UnitType;
|
||
|
use crate::entity::item::tool::ToolType;
|
||
|
use crate::ship::map::MapVariantType;
|
||
|
use crate::entity::character::SectionID;
|
||
|
pub use crate::ship::drops::generic_weapon::*;
|
||
|
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
|
||
|
pub enum MonsterDropType {
|
||
|
#[serde(rename = "weapon")]
|
||
|
Weapon,
|
||
|
#[serde(rename = "armor")]
|
||
|
Armor,
|
||
|
#[serde(rename = "shield")]
|
||
|
Shield,
|
||
|
#[serde(rename = "unit")]
|
||
|
Unit,
|
||
|
#[serde(rename = "none")]
|
||
|
None,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
|
||
|
pub struct MonsterDropStats {
|
||
|
pub dar: u32,
|
||
|
pub drop_type: MonsterDropType,
|
||
|
pub min_meseta: u32,
|
||
|
pub max_meseta: u32,
|
||
|
}
|
||
|
|
||
|
enum RareDropItem {
|
||
|
Weapon(WeaponType),
|
||
|
Armor(ArmorType),
|
||
|
Shield(ShieldType),
|
||
|
Unit(UnitType),
|
||
|
Tool(ToolType),
|
||
|
}
|
||
|
|
||
|
|
||
|
struct RareDrop {
|
||
|
rate: f32,
|
||
|
item: RareDropItem
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct RareDropConfigEntity {
|
||
|
pub rate: f32,
|
||
|
pub item: String,
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*#[derive(Serialize, Deserialize)]
|
||
|
pub struct MonsterDar(pub HashMap<MonsterType, MonsterDropStats>);
|
||
|
|
||
|
/*impl MonsterDar {
|
||
|
fn from_f
|
||
|
|
||
|
|
||
|
}*/*/
|
||
|
|
||
|
|
||
|
struct RareDropTable {
|
||
|
|
||
|
}
|
||
|
|
||
|
impl RareDropTable {
|
||
|
fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> RareDropTable {
|
||
|
RareDropTable {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn get_drop(&self, monster: &MonsterType) -> Option<ItemDetail> {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
struct DropTable<R: Rng + SeedableRng> {
|
||
|
rare_table: RareDropTable,
|
||
|
monster_stats: HashMap<MonsterType, MonsterDropStats>,
|
||
|
weapon_table: GenericWeaponTable,
|
||
|
rng: R,
|
||
|
}
|
||
|
|
||
|
|
||
|
impl<R: Rng + SeedableRng> DropTable<R> {
|
||
|
fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable<R> {
|
||
|
let mut path = PathBuf::from("data/drops/");
|
||
|
path.push(episode.to_string());
|
||
|
path.push(difficulty.to_string().to_lowercase());
|
||
|
path.push(section_id.to_string().to_lowercase());
|
||
|
path.push("grind_rate.toml");
|
||
|
let mut f = File::open(path).unwrap();
|
||
|
let mut s = String::new();
|
||
|
f.read_to_string(&mut s);
|
||
|
let monster_stats = toml::from_str(&s).unwrap();
|
||
|
|
||
|
DropTable {
|
||
|
rare_table: RareDropTable::new(episode, difficulty, section_id),
|
||
|
monster_stats: monster_stats,
|
||
|
weapon_table: GenericWeaponTable::new(episode, difficulty, section_id),
|
||
|
rng: R::from_entropy(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn generate_meseta(&self, monster: &MonsterDropStats) -> Option<ItemDetail> {
|
||
|
None
|
||
|
}
|
||
|
|
||
|
fn generate_tool(&self, map_area: &MapVariantType, monster: &MonsterDropStats) -> Option<ItemDetail> {
|
||
|
None
|
||
|
}
|
||
|
|
||
|
fn generate_armor(&self) -> Option<ItemDetail> {
|
||
|
None
|
||
|
}
|
||
|
|
||
|
fn generate_shield(&self) -> Option<ItemDetail> {
|
||
|
None
|
||
|
}
|
||
|
|
||
|
fn generate_unit(&self) -> Option<ItemDetail> {
|
||
|
None
|
||
|
}
|
||
|
|
||
|
fn generate_typed_drop(&mut self, map_area: &MapVariantType, monster: &MonsterDropStats) -> Option<ItemDetail> {
|
||
|
match monster.drop_type {
|
||
|
MonsterDropType::Weapon => self.weapon_table.get_drop(map_area, &mut self.rng),
|
||
|
MonsterDropType::Armor => self.generate_armor(),
|
||
|
MonsterDropType::Shield => self.generate_shield(),
|
||
|
MonsterDropType::Unit => self.generate_unit(),
|
||
|
MonsterDropType::None => None,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
fn get_drop(&mut self, map_area: &MapVariantType, monster: &MonsterType) -> Option<ItemDetail> {
|
||
|
//let mut rng = rand::thread_rng();
|
||
|
let monster_stat = *self.monster_stats.get(monster)?;
|
||
|
|
||
|
let drop_anything = self.rng.gen_range(0, 100);
|
||
|
if drop_anything > monster_stat.dar {
|
||
|
return None;
|
||
|
}
|
||
|
|
||
|
if let Some(item) = self.rare_table.get_drop(&monster) {
|
||
|
return Some(item);
|
||
|
}
|
||
|
|
||
|
let drop_type = self.rng.gen_range(0, 3);
|
||
|
|
||
|
match drop_type {
|
||
|
0 => {
|
||
|
self.generate_meseta(&monster_stat)
|
||
|
},
|
||
|
1 => {
|
||
|
self.generate_tool(map_area, &monster_stat)
|
||
|
},
|
||
|
2 => {
|
||
|
self.generate_typed_drop(map_area, &monster_stat)
|
||
|
},
|
||
|
_ => panic!()
|
||
|
}
|
||
|
}
|
||
|
}
|