168 lines
5.1 KiB
Rust
Raw Normal View History

2020-03-14 10:44:27 -07:00
mod drop_table;
mod rare_drop_table;
mod generic_weapon;
mod generic_armor;
mod generic_shield;
2020-03-15 17:17:29 -07:00
mod generic_unit;
2020-03-16 18:47:30 -07:00
mod tool_table;
mod tech_table;
2020-03-14 10:44:27 -07:00
use std::collections::HashMap;
use std::fs::File;
use std::path::PathBuf;
use std::io::Read;
use serde::{Serialize, Deserialize};
use rand::{Rng, SeedableRng};
2020-03-26 00:06:28 -07:00
use crate::entity::item::ItemDetail;
2020-03-14 10:44:27 -07:00
use crate::ship::monster::MonsterType;
use crate::ship::room::{Difficulty, Episode};
use crate::ship::map::MapVariantType;
use crate::entity::character::SectionID;
2020-03-14 17:08:31 -07:00
use crate::ship::drops::generic_weapon::GenericWeaponTable;
use crate::ship::drops::generic_armor::GenericArmorTable;
2020-03-14 18:19:41 -07:00
use crate::ship::drops::generic_shield::GenericShieldTable;
2020-03-15 17:31:29 -07:00
use crate::ship::drops::generic_unit::GenericUnitTable;
2020-03-16 18:47:30 -07:00
use crate::ship::drops::tool_table::ToolTable;
2020-03-26 00:06:28 -07:00
use crate::ship::drops::rare_drop_table::RareDropTable;
2020-03-14 17:08:31 -07:00
fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf {
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(filename);
path
}
pub fn load_data_file<T: serde::de::DeserializeOwned>(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> T {
let path = data_file_path(episode, difficulty, section_id, filename);
let mut f = File::open(path).unwrap();
let mut s = String::new();
f.read_to_string(&mut s);
toml::from_str::<T>(s.as_str()).unwrap()
}
2020-03-14 10:44:27 -07:00
#[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,
}
2020-03-26 00:06:28 -07:00
enum ItemDropItem {
Weapon,
2020-03-14 10:44:27 -07:00
}
2020-03-26 00:06:28 -07:00
struct ItemDrop {
x: f32,
y: f32,
z: f32,
item: ItemDropItem,
2020-03-14 10:44:27 -07:00
}
2020-03-26 00:06:28 -07:00
impl ItemDropItem {
pub fn as_client_bytes(&self) -> u8 {
0
2020-03-14 10:44:27 -07:00
}
}
2020-03-26 00:06:28 -07:00
2020-03-14 10:44:27 -07:00
struct DropTable<R: Rng + SeedableRng> {
monster_stats: HashMap<MonsterType, MonsterDropStats>,
2020-03-26 00:06:28 -07:00
rare_table: RareDropTable,
2020-03-14 10:44:27 -07:00
weapon_table: GenericWeaponTable,
2020-03-14 17:08:31 -07:00
armor_table: GenericArmorTable,
2020-03-14 18:19:41 -07:00
shield_table: GenericShieldTable,
2020-03-15 17:31:29 -07:00
unit_table: GenericUnitTable,
2020-03-16 18:47:30 -07:00
tool_table: ToolTable,
2020-03-14 10:44:27 -07:00
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 {
monster_stats: monster_stats,
2020-03-26 00:06:28 -07:00
rare_table: RareDropTable::new(episode, difficulty, section_id),
2020-03-14 10:44:27 -07:00
weapon_table: GenericWeaponTable::new(episode, difficulty, section_id),
2020-03-14 17:08:31 -07:00
armor_table: GenericArmorTable::new(episode, difficulty, section_id),
2020-03-14 18:19:41 -07:00
shield_table: GenericShieldTable::new(episode, difficulty, section_id),
2020-03-15 17:31:29 -07:00
unit_table: GenericUnitTable::new(episode, difficulty, section_id),
2020-03-16 18:47:30 -07:00
tool_table: ToolTable::new(episode, difficulty, section_id),
2020-03-14 10:44:27 -07:00
rng: R::from_entropy(),
}
}
fn generate_meseta(&self, monster: &MonsterDropStats) -> 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),
2020-03-14 18:19:41 -07:00
MonsterDropType::Armor => self.armor_table.get_drop(map_area, &mut self.rng),
MonsterDropType::Shield => self.shield_table.get_drop(map_area, &mut self.rng),
2020-03-15 17:31:29 -07:00
MonsterDropType::Unit => self.unit_table.get_drop(map_area, &mut self.rng),
2020-03-14 10:44:27 -07:00
MonsterDropType::None => None,
}
}
fn get_drop(&mut self, map_area: &MapVariantType, monster: &MonsterType) -> Option<ItemDetail> {
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;
}
2020-03-26 00:06:28 -07:00
if let Some(item) = self.rare_table.get_drop(map_area, &monster, &mut self.rng) {
2020-03-14 10:44:27 -07:00
return Some(item);
}
let drop_type = self.rng.gen_range(0, 3);
match drop_type {
0 => {
self.generate_meseta(&monster_stat)
},
1 => {
2020-03-16 18:47:30 -07:00
self.tool_table.get_drop(map_area, &mut self.rng)
2020-03-14 10:44:27 -07:00
},
2 => {
self.generate_typed_drop(map_area, &monster_stat)
},
_ => panic!()
}
}
}