rare drops
This commit is contained in:
		
							parent
							
								
									e41f79f41a
								
							
						
					
					
						commit
						cfa31736c6
					
				@ -80,20 +80,18 @@ impl GenericArmorTable {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn slots<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> usize {
 | 
			
		||||
    pub 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) -> u32 {
 | 
			
		||||
    pub fn dfp_modifier<R: Rng>(&self, armor_type: &ArmorType, rng: &mut R) -> u32 {
 | 
			
		||||
        let stats = self.armor_stats.get(armor_type).unwrap();
 | 
			
		||||
        rng.gen_range(0, stats.dfp_modifier)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: this needs the pmt file
 | 
			
		||||
    fn evp_modifier<R: Rng>(&self, armor_type: &ArmorType, rng: &mut R) -> u32 {
 | 
			
		||||
    pub fn evp_modifier<R: Rng>(&self, armor_type: &ArmorType, rng: &mut R) -> u32 {
 | 
			
		||||
        let stats = self.armor_stats.get(armor_type).unwrap();
 | 
			
		||||
        rng.gen_range(0, stats.evp_modifier)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -67,14 +67,12 @@ impl GenericShieldTable {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: this needs the pmt file
 | 
			
		||||
    fn dfp_modifier<R: Rng>(&self, shield_type: &ShieldType, rng: &mut R) -> u32 {
 | 
			
		||||
    pub fn dfp_modifier<R: Rng>(&self, shield_type: &ShieldType, rng: &mut R) -> u32 {
 | 
			
		||||
        let stats = self.shield_stats.get(shield_type).unwrap();
 | 
			
		||||
        rng.gen_range(0, stats.dfp_modifier)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: this needs the pmt file
 | 
			
		||||
    fn evp_modifier<R: Rng>(&self, shield_type: &ShieldType, rng: &mut R) -> u32 {
 | 
			
		||||
    pub fn evp_modifier<R: Rng>(&self, shield_type: &ShieldType, rng: &mut R) -> u32 {
 | 
			
		||||
        let stats = self.shield_stats.get(shield_type).unwrap();
 | 
			
		||||
        rng.gen_range(0, stats.evp_modifier)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -220,7 +220,7 @@ impl PercentRatePatterns {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct AttributeTable {
 | 
			
		||||
pub struct AttributeTable {
 | 
			
		||||
    attribute_rates: AttributeRates,
 | 
			
		||||
    percent_rates: PercentRatePatterns,
 | 
			
		||||
    area_percent_patterns: AreaPercentPatterns,
 | 
			
		||||
@ -228,7 +228,7 @@ struct AttributeTable {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
impl AttributeTable {
 | 
			
		||||
    fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> AttributeTable {
 | 
			
		||||
    pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> AttributeTable {
 | 
			
		||||
        // TODO: new these
 | 
			
		||||
        let attribute_rates: AttributeRates = load_data_file(episode, difficulty, section_id, "attribute_rate.toml");
 | 
			
		||||
        let percent_rates: PercentRatePatterns = load_data_file(episode, difficulty, section_id, "percent_rate.toml");
 | 
			
		||||
@ -255,7 +255,7 @@ impl AttributeTable {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let percents = self.percent_rates.get_by_pattern(pattern);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        let value_weights = WeightedIndex::new(&percents.as_array()).unwrap();
 | 
			
		||||
        let value = value_weights.sample(rng);
 | 
			
		||||
        let percent = ((value + 1) * 5) as i8;
 | 
			
		||||
@ -265,11 +265,8 @@ impl AttributeTable {
 | 
			
		||||
            value: percent
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    fn generate_attributes<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
 | 
			
		||||
        let percent_pattern = self.area_percent_patterns.get_by_area(map_area);
 | 
			
		||||
        let attribute_rate = self.attribute_rates.get_by_area(map_area);
 | 
			
		||||
 | 
			
		||||
    fn attributes<R: Rng>(&self, percent_pattern: &AttributePercentPattern, attribute_rate: &AttributeRate, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
 | 
			
		||||
        let mut percents = vec![
 | 
			
		||||
            percent_pattern.attribute1.and_then(|pattern_type| {
 | 
			
		||||
                self.generate_attribute(&pattern_type, &attribute_rate, rng)
 | 
			
		||||
@ -304,6 +301,22 @@ impl AttributeTable {
 | 
			
		||||
                }
 | 
			
		||||
            }).0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn generate_attributes<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
 | 
			
		||||
        let percent_pattern = self.area_percent_patterns.get_by_area(map_area);
 | 
			
		||||
        let attribute_rate = self.attribute_rates.get_by_area(map_area);
 | 
			
		||||
        self.attributes(&percent_pattern, &attribute_rate, rng)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn generate_rare_attributes<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
 | 
			
		||||
        let percent_pattern = AttributePercentPattern {
 | 
			
		||||
            attribute1: Some(PercentPatternType::Pattern6),
 | 
			
		||||
            attribute2: Some(PercentPatternType::Pattern6),
 | 
			
		||||
            attribute3: Some(PercentPatternType::Pattern6),
 | 
			
		||||
        };
 | 
			
		||||
        let attribute_rate = self.attribute_rates.get_by_area(map_area);
 | 
			
		||||
        self.attributes(&percent_pattern, &attribute_rate, rng)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -347,23 +360,23 @@ impl SpecialRates {
 | 
			
		||||
            _ => self.area10,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    fn random_special_by_rank<R: Rng>(&self, rank: u32, rng: &mut R) -> WeaponSpecial {
 | 
			
		||||
        let specials = match rank {
 | 
			
		||||
            1 => vec![WeaponSpecial::Draw, WeaponSpecial::Heart, WeaponSpecial::Ice, WeaponSpecial::Bind, WeaponSpecial::Heat, WeaponSpecial::Shock,
 | 
			
		||||
                      WeaponSpecial::Dim, WeaponSpecial::Panic],
 | 
			
		||||
            2 => vec![WeaponSpecial::Drain, WeaponSpecial::Mind, WeaponSpecial::Frost, WeaponSpecial::Hold, WeaponSpecial::Fire, WeaponSpecial::Thunder, 
 | 
			
		||||
            2 => vec![WeaponSpecial::Drain, WeaponSpecial::Mind, WeaponSpecial::Frost, WeaponSpecial::Hold, WeaponSpecial::Fire, WeaponSpecial::Thunder,
 | 
			
		||||
                      WeaponSpecial::Shadow, WeaponSpecial::Riot, WeaponSpecial::Masters,  WeaponSpecial::Charge],
 | 
			
		||||
            3 => vec![WeaponSpecial::Fill, WeaponSpecial::Soul, WeaponSpecial::Freeze, WeaponSpecial::Seize, WeaponSpecial::Flame, WeaponSpecial::Storm, 
 | 
			
		||||
            3 => vec![WeaponSpecial::Fill, WeaponSpecial::Soul, WeaponSpecial::Freeze, WeaponSpecial::Seize, WeaponSpecial::Flame, WeaponSpecial::Storm,
 | 
			
		||||
                      WeaponSpecial::Dark, WeaponSpecial::Havoc, WeaponSpecial::Lords, WeaponSpecial::Charge, WeaponSpecial::Spirit,  WeaponSpecial::Devils],
 | 
			
		||||
            4 => vec![WeaponSpecial::Gush, WeaponSpecial::Geist, WeaponSpecial::Blizzard, WeaponSpecial::Arrest, WeaponSpecial::Burning, WeaponSpecial::Tempest, 
 | 
			
		||||
            4 => vec![WeaponSpecial::Gush, WeaponSpecial::Geist, WeaponSpecial::Blizzard, WeaponSpecial::Arrest, WeaponSpecial::Burning, WeaponSpecial::Tempest,
 | 
			
		||||
                      WeaponSpecial::Hell, WeaponSpecial::Chaos, WeaponSpecial::Kings, WeaponSpecial::Charge, WeaponSpecial::Berserk,  WeaponSpecial::Demons],
 | 
			
		||||
            _ => panic!(),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        *specials.choose(rng).unwrap()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    fn get_special<R: Rng>(&self, map_area:  &MapVariantType, rng: &mut R) -> Option<WeaponSpecial> {
 | 
			
		||||
        let rate = self.rate_by_area(map_area);
 | 
			
		||||
        if rng.gen_range(0, 100) < rate.rate {
 | 
			
		||||
@ -400,7 +413,7 @@ impl GenericWeaponTable {
 | 
			
		||||
        rank_table.insert(WeaponDropType::Cane, vec![WeaponType::Cane, WeaponType::Stick, WeaponType::Mace, WeaponType::Club]);
 | 
			
		||||
        rank_table.insert(WeaponDropType::Rod, vec![WeaponType::Rod, WeaponType::Pole, WeaponType::Pillar, WeaponType::Striker]);
 | 
			
		||||
        rank_table.insert(WeaponDropType::Wand, vec![WeaponType::Wand, WeaponType::Staff, WeaponType::Baton, WeaponType::Scepter]);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        GenericWeaponTable {
 | 
			
		||||
            rank_table: rank_table,
 | 
			
		||||
            weapon_ratio: WeaponRatios::new(episode, difficulty, section_id),
 | 
			
		||||
@ -445,7 +458,7 @@ impl GenericWeaponTable {
 | 
			
		||||
 | 
			
		||||
        valid_weapons
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    fn weapon_type<R: Rng>(&self, possible_weapon_types: &BTreeMap<WeaponDropType, WeaponRatio>, map_area: &MapVariantType, rng: &mut R) -> WeaponDropType {
 | 
			
		||||
        let mut weapon_rates = possible_weapon_types.iter()
 | 
			
		||||
            .map(|(weapon, stat)| {
 | 
			
		||||
@ -536,7 +549,7 @@ mod test {
 | 
			
		||||
            equipped: false,
 | 
			
		||||
            tekked: false,
 | 
			
		||||
        })));
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
 | 
			
		||||
        assert!(gwt.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDetail::Weapon(Weapon {
 | 
			
		||||
            weapon: WeaponType::Vulcan,
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@ mod generic_unit;
 | 
			
		||||
mod tool_table;
 | 
			
		||||
mod tech_table;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
@ -15,14 +14,9 @@ use std::io::Read;
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
use rand::{Rng, SeedableRng};
 | 
			
		||||
 | 
			
		||||
use crate::entity::item::ItemDetail;
 | 
			
		||||
use crate::ship::monster::MonsterType;
 | 
			
		||||
use crate::ship::room::{Difficulty, Episode};
 | 
			
		||||
use crate::entity::item::ItemDetail;
 | 
			
		||||
use crate::entity::item::weapon::WeaponType;
 | 
			
		||||
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;
 | 
			
		||||
use crate::ship::drops::generic_weapon::GenericWeaponTable;
 | 
			
		||||
@ -30,6 +24,7 @@ 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;
 | 
			
		||||
use crate::ship::drops::rare_drop_table::RareDropTable;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf {
 | 
			
		||||
@ -73,60 +68,28 @@ pub struct MonsterDropStats {
 | 
			
		||||
    pub max_meseta: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum RareDropItem {
 | 
			
		||||
    Weapon(WeaponType),
 | 
			
		||||
    Armor(ArmorType),
 | 
			
		||||
    Shield(ShieldType),
 | 
			
		||||
    Unit(UnitType),
 | 
			
		||||
    Tool(ToolType),
 | 
			
		||||
enum ItemDropItem {
 | 
			
		||||
    Weapon,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct RareDrop {
 | 
			
		||||
    rate: f32,
 | 
			
		||||
    item: RareDropItem
 | 
			
		||||
struct ItemDrop {
 | 
			
		||||
    x: f32,
 | 
			
		||||
    y: f32,
 | 
			
		||||
    z: f32,
 | 
			
		||||
    item: ItemDropItem,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[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
 | 
			
		||||
impl ItemDropItem {
 | 
			
		||||
    pub fn as_client_bytes(&self) -> u8 {
 | 
			
		||||
        0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct DropTable<R: Rng + SeedableRng> {
 | 
			
		||||
    rare_table: RareDropTable,
 | 
			
		||||
    monster_stats: HashMap<MonsterType, MonsterDropStats>,
 | 
			
		||||
    rare_table: RareDropTable,
 | 
			
		||||
    weapon_table: GenericWeaponTable,
 | 
			
		||||
    armor_table: GenericArmorTable,
 | 
			
		||||
    shield_table: GenericShieldTable,
 | 
			
		||||
@ -149,8 +112,8 @@ impl<R: Rng + SeedableRng> DropTable<R> {
 | 
			
		||||
        let monster_stats = toml::from_str(&s).unwrap();
 | 
			
		||||
        
 | 
			
		||||
        DropTable {
 | 
			
		||||
            rare_table: RareDropTable::new(episode, difficulty, section_id),
 | 
			
		||||
            monster_stats: monster_stats,
 | 
			
		||||
            rare_table: RareDropTable::new(episode, difficulty, section_id),
 | 
			
		||||
            weapon_table: GenericWeaponTable::new(episode, difficulty, section_id),
 | 
			
		||||
            armor_table: GenericArmorTable::new(episode, difficulty, section_id),
 | 
			
		||||
            shield_table: GenericShieldTable::new(episode, difficulty, section_id),
 | 
			
		||||
@ -182,7 +145,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let Some(item) = self.rare_table.get_drop(&monster) {
 | 
			
		||||
        if let Some(item) = self.rare_table.get_drop(map_area, &monster, &mut self.rng) {
 | 
			
		||||
            return Some(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,155 @@
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use rand::Rng;
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
use crate::entity::item::ItemDetail;
 | 
			
		||||
use crate::entity::item::weapon::{Weapon, WeaponType};
 | 
			
		||||
use crate::entity::item::armor::{Armor, ArmorType};
 | 
			
		||||
use crate::entity::item::shield::{Shield, ShieldType};
 | 
			
		||||
use crate::entity::item::unit::{Unit, UnitType};
 | 
			
		||||
use crate::entity::item::tool::{Tool, ToolType};
 | 
			
		||||
use crate::entity::character::SectionID;
 | 
			
		||||
use crate::ship::monster::MonsterType;
 | 
			
		||||
use crate::ship::room::{Difficulty, Episode};
 | 
			
		||||
use crate::ship::map::MapVariantType;
 | 
			
		||||
use crate::ship::drops::load_data_file;
 | 
			
		||||
use crate::ship::drops::generic_weapon::AttributeTable;
 | 
			
		||||
use crate::ship::drops::generic_armor::GenericArmorTable;
 | 
			
		||||
use crate::ship::drops::generic_shield::GenericShieldTable;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Copy, Clone)]
 | 
			
		||||
enum RareDropItem {
 | 
			
		||||
    Weapon(WeaponType),
 | 
			
		||||
    Armor(ArmorType),
 | 
			
		||||
    Shield(ShieldType),
 | 
			
		||||
    Unit(UnitType),
 | 
			
		||||
    Tool(ToolType),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl RareDropItem {
 | 
			
		||||
    fn from_string(name: String) -> RareDropItem {
 | 
			
		||||
        let parse_funcs: [Box<dyn Fn(&String) -> Option<RareDropItem>>; 5] = [
 | 
			
		||||
            Box::new(|i| Some(RareDropItem::Weapon(str::parse::<WeaponType>(&i).ok()?))),
 | 
			
		||||
            Box::new(|i| Some(RareDropItem::Armor(str::parse::<ArmorType>(&i).ok()?))),
 | 
			
		||||
            Box::new(|i| Some(RareDropItem::Shield(str::parse::<ShieldType>(&i).ok()?))),
 | 
			
		||||
            Box::new(|i| Some(RareDropItem::Unit(str::parse::<UnitType>(&i).ok()?))),
 | 
			
		||||
            Box::new(|i| Some(RareDropItem::Tool(str::parse::<ToolType>(&i).ok()?)))];
 | 
			
		||||
 | 
			
		||||
        for parse in parse_funcs.iter() {
 | 
			
		||||
            match parse(&name) {
 | 
			
		||||
                Some(k) => return k,
 | 
			
		||||
                None => {},
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        panic!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct RareDropRate {
 | 
			
		||||
    rate: f32,
 | 
			
		||||
    item: RareDropItem
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize, Deserialize)]
 | 
			
		||||
pub struct RareDropConfigEntity {
 | 
			
		||||
    pub rate: f32,
 | 
			
		||||
    pub item: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub struct RareDropTable {
 | 
			
		||||
    rates: HashMap<MonsterType, Vec<RareDropRate>>,
 | 
			
		||||
    attribute_table: AttributeTable,
 | 
			
		||||
    armor_stats: GenericArmorTable,
 | 
			
		||||
    shield_stats: GenericShieldTable,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl RareDropTable {
 | 
			
		||||
    pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> RareDropTable {
 | 
			
		||||
        let cfg: HashMap<String, Vec<RareDropConfigEntity>> = load_data_file(episode, difficulty, section_id, "rare_rate.toml");
 | 
			
		||||
 | 
			
		||||
        let rates = cfg.into_iter()
 | 
			
		||||
            .map(|(monster, drops)| {
 | 
			
		||||
                let monster = monster.parse().unwrap();
 | 
			
		||||
                let drops = drops.into_iter().map(|drop| {
 | 
			
		||||
                    RareDropRate {
 | 
			
		||||
                        rate: drop.rate,
 | 
			
		||||
                        item: RareDropItem::from_string(drop.item),
 | 
			
		||||
                    }
 | 
			
		||||
                }).collect();
 | 
			
		||||
                (monster, drops)
 | 
			
		||||
            }).collect();
 | 
			
		||||
 | 
			
		||||
        RareDropTable {
 | 
			
		||||
            rates: rates,
 | 
			
		||||
            attribute_table: AttributeTable::new(episode, difficulty, section_id),
 | 
			
		||||
            armor_stats: GenericArmorTable::new(episode, difficulty, section_id),
 | 
			
		||||
            shield_stats: GenericShieldTable::new(episode, difficulty, section_id),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn apply_item_stats<R: Rng>(&self, map_area: &MapVariantType, item: RareDropItem, rng: &mut R) -> ItemDetail {
 | 
			
		||||
        match item {
 | 
			
		||||
            RareDropItem::Weapon(weapon) => {
 | 
			
		||||
                ItemDetail::Weapon(Weapon {
 | 
			
		||||
                    weapon: weapon,
 | 
			
		||||
                    special: None,
 | 
			
		||||
                    grind: 0,
 | 
			
		||||
                    attrs: self.attribute_table.generate_rare_attributes(map_area, rng),
 | 
			
		||||
                    equipped: false,
 | 
			
		||||
                    tekked: false,
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
            },
 | 
			
		||||
            RareDropItem::Armor(armor) => {
 | 
			
		||||
                ItemDetail::Armor(Armor {
 | 
			
		||||
                    armor: armor,
 | 
			
		||||
                    dfp: self.armor_stats.dfp_modifier(&armor, rng) as u8,
 | 
			
		||||
                    evp: self.armor_stats.evp_modifier(&armor, rng) as u8,
 | 
			
		||||
                    slots: self.armor_stats.slots(map_area, rng) as u8,
 | 
			
		||||
                    equipped: false,
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            RareDropItem::Shield(shield) => {
 | 
			
		||||
                ItemDetail::Shield(Shield {
 | 
			
		||||
                    shield: shield,
 | 
			
		||||
                    dfp: self.shield_stats.dfp_modifier(&shield, rng) as u8,
 | 
			
		||||
                    evp: self.shield_stats.evp_modifier(&shield, rng) as u8,
 | 
			
		||||
                    equipped: false,
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            RareDropItem::Unit(unit) => {
 | 
			
		||||
                ItemDetail::Unit(Unit {
 | 
			
		||||
                    unit: unit,
 | 
			
		||||
                    modifier: None,
 | 
			
		||||
                    equipped: false,
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            RareDropItem::Tool(tool) => {
 | 
			
		||||
                ItemDetail::Tool(Tool {
 | 
			
		||||
                    tool: tool,
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, monster: &MonsterType, rng: &mut R) -> Option<ItemDetail> {
 | 
			
		||||
        self.rates.get(monster)
 | 
			
		||||
            .and_then(|drop_rates| {
 | 
			
		||||
                drop_rates.iter()
 | 
			
		||||
                    .filter_map(|drop_rate| {
 | 
			
		||||
                        let rand: f32 = rng.gen();
 | 
			
		||||
                        if rand < drop_rate.rate {
 | 
			
		||||
                            Some(self.apply_item_stats(map_area, drop_rate.item, rng))
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            None
 | 
			
		||||
                        }
 | 
			
		||||
                    }).nth(0)
 | 
			
		||||
            })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user