add armor drop table
This commit is contained in:
		
							parent
							
								
									e2bc7a0de5
								
							
						
					
					
						commit
						6370a11615
					
				@ -0,0 +1,125 @@
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
use rand::{Rng, SeedableRng};
 | 
			
		||||
use rand::distributions::{WeightedIndex, Distribution};
 | 
			
		||||
 | 
			
		||||
use crate::entity::item::{ItemDetail, Armor as ArmorDetail};
 | 
			
		||||
use crate::entity::item::armor::{ArmorType, Armor};
 | 
			
		||||
use crate::ship::room::{Difficulty, Episode};
 | 
			
		||||
use crate::ship::map::MapVariantType;
 | 
			
		||||
use crate::entity::character::SectionID;
 | 
			
		||||
use crate::ship::drops::load_data_file;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize)]
 | 
			
		||||
struct ArmorRankRates {
 | 
			
		||||
    rank0: u32,
 | 
			
		||||
    rank1: u32,
 | 
			
		||||
    rank2: u32,
 | 
			
		||||
    rank3: u32,
 | 
			
		||||
    rank4: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize)]
 | 
			
		||||
struct ArmorSlotRanks {
 | 
			
		||||
    slot0: u32,
 | 
			
		||||
    slot1: u32,
 | 
			
		||||
    slot2: u32,
 | 
			
		||||
    slot3: u32,
 | 
			
		||||
    slot4: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize)]
 | 
			
		||||
pub struct GenericArmorTable {
 | 
			
		||||
    rank_rates: ArmorRankRates,
 | 
			
		||||
    slot_rates: ArmorSlotRanks,
 | 
			
		||||
    armor_set: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
impl GenericArmorTable {
 | 
			
		||||
    pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> GenericArmorTable {
 | 
			
		||||
        load_data_file(episode, difficulty, section_id, "armor_rate.toml")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn armor_type<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> ArmorType {
 | 
			
		||||
        let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
 | 
			
		||||
                                                self.rank_rates.rank3, self.rank_rates.rank4]).unwrap();
 | 
			
		||||
        let rank = rank_weights.sample(rng) as i32;
 | 
			
		||||
        let armor_level = std::cmp::max(0i32, self.armor_set as i32 - 3i32 + rank + area_map.area_value().unwrap_or(0) as i32);
 | 
			
		||||
        match armor_level {
 | 
			
		||||
            0x00 => ArmorType::Frame,
 | 
			
		||||
            0x01 => ArmorType::Armor,
 | 
			
		||||
            0x02 => ArmorType::PsyArmor,
 | 
			
		||||
            0x03 => ArmorType::GigaFrame,
 | 
			
		||||
            0x04 => ArmorType::SoulFrame,
 | 
			
		||||
            0x05 => ArmorType::CrossArmor,
 | 
			
		||||
            0x06 => ArmorType::SolidFrame,
 | 
			
		||||
            0x07 => ArmorType::BraveArmor,
 | 
			
		||||
            0x08 => ArmorType::HyperFrame,
 | 
			
		||||
            0x09 => ArmorType::GrandArmor,
 | 
			
		||||
            0x0A => ArmorType::ShockFrame,
 | 
			
		||||
            0x0B => ArmorType::KingsFrame,
 | 
			
		||||
            0x0C => ArmorType::DragonFrame,
 | 
			
		||||
            0x0D => ArmorType::AbsorbArmor,
 | 
			
		||||
            0x0E => ArmorType::ProtectFrame,
 | 
			
		||||
            0x0F => ArmorType::GeneralArmor,
 | 
			
		||||
            0x10 => ArmorType::PerfectFrame,
 | 
			
		||||
            0x11 => ArmorType::ValiantFrame,
 | 
			
		||||
            0x12 => ArmorType::ImperialArmor,
 | 
			
		||||
            0x13 => ArmorType::HolinessArmor,
 | 
			
		||||
            0x14 => ArmorType::GuardianArmor,
 | 
			
		||||
            0x15 => ArmorType::DivinityArmor,
 | 
			
		||||
            0x16 => ArmorType::UltimateFrame,
 | 
			
		||||
            0x17 => ArmorType::CelestialArmor,
 | 
			
		||||
            _ => panic!()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn slots<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> usize {
 | 
			
		||||
        let slot_weights = WeightedIndex::new(&[self.slot_rates.slot0, self.slot_rates.slot1, self.slot_rates.slot2,
 | 
			
		||||
                                                self.slot_rates.slot3, self.slot_rates.slot4]).unwrap();
 | 
			
		||||
        slot_weights.sample(rng)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: this needs the pmt file
 | 
			
		||||
    fn dfp_modifier<R: Rng>(&self, armor_type: &ArmorType, rng: &mut R) -> usize {
 | 
			
		||||
        0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: this needs the pmt file
 | 
			
		||||
    fn evp_modifier<R: Rng>(&self, armor_type: &ArmorType, rng: &mut R) -> usize {
 | 
			
		||||
        0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
 | 
			
		||||
        let armor_type = self.armor_type(area_map, rng);
 | 
			
		||||
        let slots = self.slots(area_map, rng);
 | 
			
		||||
        let dfp_modifier = self.dfp_modifier(&armor_type, rng);
 | 
			
		||||
        let evp_modifier = self.dfp_modifier(&armor_type, rng);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Some(ItemDetail::Armor(ArmorDetail {
 | 
			
		||||
            equipped: false,
 | 
			
		||||
            armor: Armor {
 | 
			
		||||
                armor: armor_type,
 | 
			
		||||
                dfp: dfp_modifier as u8,
 | 
			
		||||
                evp: evp_modifier as u8,
 | 
			
		||||
                slots: slots as u8
 | 
			
		||||
            }
 | 
			
		||||
        }))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,4 @@
 | 
			
		||||
use std::collections::{HashMap, BTreeMap};
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
use std::io::Read;
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
use rand::{Rng, SeedableRng};
 | 
			
		||||
@ -13,25 +11,9 @@ use crate::ship::monster::MonsterType;
 | 
			
		||||
use crate::ship::room::{Difficulty, Episode};
 | 
			
		||||
use crate::ship::map::MapVariantType;
 | 
			
		||||
use crate::entity::character::SectionID;
 | 
			
		||||
use crate::ship::drops::load_data_file;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Hash, Copy, Clone, Ord, PartialOrd)]
 | 
			
		||||
pub enum WeaponDropType {
 | 
			
		||||
@ -56,7 +38,6 @@ pub struct WeaponRatio {
 | 
			
		||||
    inc: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
 | 
			
		||||
pub struct WeaponRatios {
 | 
			
		||||
    saber: WeaponRatio,
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,27 @@ 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::*;
 | 
			
		||||
use crate::ship::drops::generic_weapon::GenericWeaponTable;
 | 
			
		||||
use crate::ship::drops::generic_armor::GenericArmorTable;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
 | 
			
		||||
@ -72,7 +92,6 @@ pub struct RareDropConfigEntity {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*#[derive(Serialize, Deserialize)]
 | 
			
		||||
pub struct MonsterDar(pub HashMap<MonsterType, MonsterDropStats>);
 | 
			
		||||
 | 
			
		||||
@ -104,6 +123,7 @@ struct DropTable<R: Rng + SeedableRng> {
 | 
			
		||||
    rare_table: RareDropTable,
 | 
			
		||||
    monster_stats: HashMap<MonsterType, MonsterDropStats>,
 | 
			
		||||
    weapon_table: GenericWeaponTable,
 | 
			
		||||
    armor_table: GenericArmorTable,
 | 
			
		||||
    rng: R,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -124,6 +144,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
 | 
			
		||||
            rare_table: RareDropTable::new(episode, difficulty, section_id),
 | 
			
		||||
            monster_stats: monster_stats,
 | 
			
		||||
            weapon_table: GenericWeaponTable::new(episode, difficulty, section_id),
 | 
			
		||||
            armor_table: GenericArmorTable::new(episode, difficulty, section_id),
 | 
			
		||||
            rng: R::from_entropy(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user