itemdetail -> itemdroptype for drops
This commit is contained in:
parent
a7434346db
commit
620bcade7b
@ -2,7 +2,6 @@ use std::collections::HashMap;
|
|||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::weapon::{Weapon, WeaponType};
|
use crate::entity::item::weapon::{Weapon, WeaponType};
|
||||||
use crate::entity::item::armor::{Armor, ArmorType};
|
use crate::entity::item::armor::{Armor, ArmorType};
|
||||||
use crate::entity::item::shield::{Shield, ShieldType};
|
use crate::entity::item::shield::{Shield, ShieldType};
|
||||||
@ -12,7 +11,7 @@ use crate::entity::character::SectionID;
|
|||||||
use crate::ship::monster::MonsterType;
|
use crate::ship::monster::MonsterType;
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
use crate::ship::map::{MapObject, MapObjectType, FixedBoxDropType};
|
use crate::ship::map::{MapObject, MapObjectType, FixedBoxDropType};
|
||||||
use crate::ship::drops::rare_drop_table::{RareDropTable, RareDropItem};
|
use crate::ship::drops::rare_drop_table::{RareDropTable, RareDropItem};
|
||||||
use crate::ship::drops::generic_weapon::GenericWeaponTable;
|
use crate::ship::drops::generic_weapon::GenericWeaponTable;
|
||||||
@ -172,7 +171,7 @@ impl BoxDropTable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rare_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
fn rare_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
self.rare_rates.rates_by_area(map_area).iter()
|
self.rare_rates.rates_by_area(map_area).iter()
|
||||||
.filter_map(|rate| {
|
.filter_map(|rate| {
|
||||||
let rand: f32 = rng.gen();
|
let rand: f32 = rng.gen();
|
||||||
@ -185,7 +184,7 @@ impl BoxDropTable {
|
|||||||
}).nth(0)
|
}).nth(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_box_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
fn random_box_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
self.rare_drop(map_area, rng).or_else(|| {
|
self.rare_drop(map_area, rng).or_else(|| {
|
||||||
let rate = self.box_rates.rates_by_area(map_area);
|
let rate = self.box_rates.rates_by_area(map_area);
|
||||||
let type_weights = WeightedIndex::new(&[rate.weapon_rate, rate.armor_rate, rate.shield_rate, rate.unit_rate,
|
let type_weights = WeightedIndex::new(&[rate.weapon_rate, rate.armor_rate, rate.shield_rate, rate.unit_rate,
|
||||||
@ -197,24 +196,27 @@ impl BoxDropTable {
|
|||||||
2 => self.shield_table.get_drop(map_area, rng),
|
2 => self.shield_table.get_drop(map_area, rng),
|
||||||
3 => self.unit_table.get_drop(map_area, rng),
|
3 => self.unit_table.get_drop(map_area, rng),
|
||||||
4 => self.tool_table.get_drop(map_area, rng),
|
4 => self.tool_table.get_drop(map_area, rng),
|
||||||
//5 => meseta drop
|
5 => Some(ItemDropType::Meseta(rng.gen_range(rate.min_meseta, rate.max_meseta))),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fixed_box_drop<R: Rng>(&self, fixed_drop: FixedBoxDropType, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
fn fixed_box_drop<R: Rng>(&self, fixed_drop: FixedBoxDropType, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
match fixed_drop {
|
match fixed_drop {
|
||||||
FixedBoxDropType::Weapon => self.weapon_table.get_drop(map_area, rng),
|
FixedBoxDropType::Weapon => self.weapon_table.get_drop(map_area, rng),
|
||||||
FixedBoxDropType::Armor => self.armor_table.get_drop(map_area, rng), // TODO: should this drop shield?
|
FixedBoxDropType::Armor => self.armor_table.get_drop(map_area, rng), // TODO: should this drop shield?
|
||||||
FixedBoxDropType::Tool => self.tool_table.get_drop(map_area, rng),
|
FixedBoxDropType::Tool => self.tool_table.get_drop(map_area, rng),
|
||||||
FixedBoxDropType::Meseta => panic!(),
|
FixedBoxDropType::Meseta => {
|
||||||
|
let rate = self.box_rates.rates_by_area(map_area);
|
||||||
|
Some(ItemDropType::Meseta(rng.gen_range(rate.min_meseta, rate.max_meseta)))
|
||||||
|
},
|
||||||
FixedBoxDropType::Random => self.random_box_drop(map_area, rng),
|
FixedBoxDropType::Random => self.random_box_drop(map_area, rng),
|
||||||
FixedBoxDropType::Specific(value) => panic!(),
|
FixedBoxDropType::Specific(value) => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, object: &MapObject, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, object: &MapObject, rng: &mut R) -> Option<ItemDropType> {
|
||||||
match object.object {
|
match object.object {
|
||||||
MapObjectType::Box | MapObjectType::EnemyBox | MapObjectType::RuinsBox| MapObjectType::RuinsEnemyBox
|
MapObjectType::Box | MapObjectType::EnemyBox | MapObjectType::RuinsBox| MapObjectType::RuinsEnemyBox
|
||||||
| MapObjectType::CcaBox => {
|
| MapObjectType::CcaBox => {
|
||||||
|
@ -3,12 +3,11 @@ use serde::{Serialize, Deserialize};
|
|||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
|
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::armor::{ArmorType, Armor};
|
use crate::entity::item::armor::{ArmorType, Armor};
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
use crate::ship::item_stats::{armor_stats, ArmorStats};
|
use crate::ship::item_stats::{armor_stats, ArmorStats};
|
||||||
|
|
||||||
|
|
||||||
@ -96,14 +95,14 @@ impl GenericArmorTable {
|
|||||||
rng.gen_range(0, stats.evp_modifier)
|
rng.gen_range(0, stats.evp_modifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
let armor_type = self.armor_type(area_map, rng);
|
let armor_type = self.armor_type(area_map, rng);
|
||||||
let slots = self.slots(area_map, rng);
|
let slots = self.slots(area_map, rng);
|
||||||
let dfp_modifier = self.dfp_modifier(&armor_type, rng);
|
let dfp_modifier = self.dfp_modifier(&armor_type, rng);
|
||||||
let evp_modifier = self.dfp_modifier(&armor_type, rng);
|
let evp_modifier = self.dfp_modifier(&armor_type, rng);
|
||||||
|
|
||||||
|
|
||||||
Some(ItemDetail::Armor(Armor {
|
Some(ItemDropType::Armor(Armor {
|
||||||
armor: armor_type,
|
armor: armor_type,
|
||||||
dfp: dfp_modifier as u8,
|
dfp: dfp_modifier as u8,
|
||||||
evp: evp_modifier as u8,
|
evp: evp_modifier as u8,
|
||||||
@ -121,25 +120,25 @@ mod test {
|
|||||||
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
||||||
|
|
||||||
let gat = GenericArmorTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
let gat = GenericArmorTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
||||||
assert!(gat.get_drop(&MapVariantType::Mines1, &mut rng) == Some(ItemDetail::Armor(Armor {
|
assert!(gat.get_drop(&MapVariantType::Mines1, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||||
armor: ArmorType::GeneralArmor,
|
armor: ArmorType::GeneralArmor,
|
||||||
dfp: 0,
|
dfp: 0,
|
||||||
evp: 0,
|
evp: 0,
|
||||||
slots: 1,
|
slots: 1,
|
||||||
})));
|
})));
|
||||||
assert!(gat.get_drop(&MapVariantType::Caves3, &mut rng) == Some(ItemDetail::Armor(Armor {
|
assert!(gat.get_drop(&MapVariantType::Caves3, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||||
armor: ArmorType::AbsorbArmor,
|
armor: ArmorType::AbsorbArmor,
|
||||||
dfp: 1,
|
dfp: 1,
|
||||||
evp: 1,
|
evp: 1,
|
||||||
slots: 1,
|
slots: 1,
|
||||||
})));
|
})));
|
||||||
assert!(gat.get_drop(&MapVariantType::Forest2, &mut rng) == Some(ItemDetail::Armor(Armor {
|
assert!(gat.get_drop(&MapVariantType::Forest2, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||||
armor: ArmorType::HyperFrame,
|
armor: ArmorType::HyperFrame,
|
||||||
dfp: 0,
|
dfp: 0,
|
||||||
evp: 0,
|
evp: 0,
|
||||||
slots: 0,
|
slots: 0,
|
||||||
})));
|
})));
|
||||||
assert!(gat.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDetail::Armor(Armor {
|
assert!(gat.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||||
armor: ArmorType::ImperialArmor,
|
armor: ArmorType::ImperialArmor,
|
||||||
dfp: 2,
|
dfp: 2,
|
||||||
evp: 1,
|
evp: 1,
|
||||||
|
@ -3,12 +3,11 @@ use serde::{Serialize, Deserialize};
|
|||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
|
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::shield::{ShieldType, Shield};
|
use crate::entity::item::shield::{ShieldType, Shield};
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
use crate::ship::item_stats::{shield_stats, ShieldStats};
|
use crate::ship::item_stats::{shield_stats, ShieldStats};
|
||||||
|
|
||||||
|
|
||||||
@ -77,13 +76,13 @@ impl GenericShieldTable {
|
|||||||
rng.gen_range(0, stats.evp_modifier)
|
rng.gen_range(0, stats.evp_modifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
let shield_type = self.shield_type(area_map, rng);
|
let shield_type = self.shield_type(area_map, rng);
|
||||||
let dfp_modifier = self.dfp_modifier(&shield_type, rng);
|
let dfp_modifier = self.dfp_modifier(&shield_type, rng);
|
||||||
let evp_modifier = self.dfp_modifier(&shield_type, rng);
|
let evp_modifier = self.dfp_modifier(&shield_type, rng);
|
||||||
|
|
||||||
|
|
||||||
Some(ItemDetail::Shield(Shield {
|
Some(ItemDropType::Shield(Shield {
|
||||||
shield: shield_type,
|
shield: shield_type,
|
||||||
dfp: dfp_modifier as u8,
|
dfp: dfp_modifier as u8,
|
||||||
evp: evp_modifier as u8,
|
evp: evp_modifier as u8,
|
||||||
@ -101,22 +100,22 @@ mod test {
|
|||||||
|
|
||||||
let gst = GenericShieldTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
let gst = GenericShieldTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
||||||
|
|
||||||
assert!(gst.get_drop(&MapVariantType::Forest1, &mut rng) == Some(ItemDetail::Shield(Shield {
|
assert!(gst.get_drop(&MapVariantType::Forest1, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||||
shield: ShieldType::FreezeBarrier,
|
shield: ShieldType::FreezeBarrier,
|
||||||
dfp: 4,
|
dfp: 4,
|
||||||
evp: 1,
|
evp: 1,
|
||||||
})));
|
})));
|
||||||
assert!(gst.get_drop(&MapVariantType::Caves3, &mut rng) == Some(ItemDetail::Shield(Shield {
|
assert!(gst.get_drop(&MapVariantType::Caves3, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||||
shield: ShieldType::PsychicBarrier,
|
shield: ShieldType::PsychicBarrier,
|
||||||
dfp: 3,
|
dfp: 3,
|
||||||
evp: 2,
|
evp: 2,
|
||||||
})));
|
})));
|
||||||
assert!(gst.get_drop(&MapVariantType::Mines2, &mut rng) == Some(ItemDetail::Shield(Shield {
|
assert!(gst.get_drop(&MapVariantType::Mines2, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||||
shield: ShieldType::ImperialBarrier,
|
shield: ShieldType::ImperialBarrier,
|
||||||
dfp: 0,
|
dfp: 0,
|
||||||
evp: 4,
|
evp: 4,
|
||||||
})));
|
})));
|
||||||
assert!(gst.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDetail::Shield(Shield {
|
assert!(gst.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||||
shield: ShieldType::DivinityBarrier,
|
shield: ShieldType::DivinityBarrier,
|
||||||
dfp: 1,
|
dfp: 1,
|
||||||
evp: 0,
|
evp: 0,
|
||||||
|
@ -4,12 +4,11 @@ use rand::{Rng, SeedableRng};
|
|||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
use rand::seq::IteratorRandom;
|
use rand::seq::IteratorRandom;
|
||||||
|
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::unit::{UnitType, Unit, UnitModifier};
|
use crate::entity::item::unit::{UnitType, Unit, UnitModifier};
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
use crate::ship::item_stats::{unit_stats, UnitStats};
|
use crate::ship::item_stats::{unit_stats, UnitStats};
|
||||||
|
|
||||||
|
|
||||||
@ -84,11 +83,11 @@ impl GenericUnitTable {
|
|||||||
Some(units.choose(rng).unwrap())
|
Some(units.choose(rng).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
let unit_type_modifier = self.unit_type_and_modifier(area_map, rng);
|
let unit_type_modifier = self.unit_type_and_modifier(area_map, rng);
|
||||||
|
|
||||||
unit_type_modifier.map(|(unit_type, unit_modifier)| {
|
unit_type_modifier.map(|(unit_type, unit_modifier)| {
|
||||||
ItemDetail::Unit(Unit {
|
ItemDropType::Unit(Unit {
|
||||||
unit: unit_type,
|
unit: unit_type,
|
||||||
modifier: unit_modifier,
|
modifier: unit_modifier,
|
||||||
})
|
})
|
||||||
@ -114,7 +113,7 @@ mod test {
|
|||||||
(MapVariantType::Mines2, UnitType::ResistEvil, Some(UnitModifier::PlusPlus)),
|
(MapVariantType::Mines2, UnitType::ResistEvil, Some(UnitModifier::PlusPlus)),
|
||||||
(MapVariantType::DarkFalz, UnitType::DragonHp, Some(UnitModifier::Minus))];
|
(MapVariantType::DarkFalz, UnitType::DragonHp, Some(UnitModifier::Minus))];
|
||||||
for (area, unit, umod) in unit_tests {
|
for (area, unit, umod) in unit_tests {
|
||||||
assert!(gut.get_drop(&area, &mut rng) == Some(ItemDetail::Unit(Unit {
|
assert!(gut.get_drop(&area, &mut rng) == Some(ItemDropType::Unit(Unit {
|
||||||
unit: unit,
|
unit: unit,
|
||||||
modifier: umod,
|
modifier: umod,
|
||||||
})));
|
})));
|
||||||
|
@ -5,13 +5,12 @@ use rand::{Rng, SeedableRng};
|
|||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
use crate::entity::item::{ItemDetail};
|
|
||||||
use crate::entity::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial};
|
use crate::entity::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial};
|
||||||
use crate::ship::monster::MonsterType;
|
use crate::ship::monster::MonsterType;
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -490,7 +489,7 @@ impl GenericWeaponTable {
|
|||||||
grind_choice.sample(rng)
|
grind_choice.sample(rng)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
let possible_weapon_types = self.get_possible_weapon_types(map_area);
|
let possible_weapon_types = self.get_possible_weapon_types(map_area);
|
||||||
let weapon_type = self.weapon_type(&possible_weapon_types, map_area, rng);
|
let weapon_type = self.weapon_type(&possible_weapon_types, map_area, rng);
|
||||||
let ratio = possible_weapon_types.get(&weapon_type).unwrap();
|
let ratio = possible_weapon_types.get(&weapon_type).unwrap();
|
||||||
@ -500,7 +499,7 @@ impl GenericWeaponTable {
|
|||||||
let weapon_special = self.special_table.get_special(map_area, rng);
|
let weapon_special = self.special_table.get_special(map_area, rng);
|
||||||
let actual_weapon = self.actual_weapon(&weapon_type, weapon_rank);
|
let actual_weapon = self.actual_weapon(&weapon_type, weapon_rank);
|
||||||
|
|
||||||
Some(ItemDetail::Weapon(Weapon {
|
Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: actual_weapon,
|
weapon: actual_weapon,
|
||||||
special: weapon_special,
|
special: weapon_special,
|
||||||
grind: weapon_grind as u8,
|
grind: weapon_grind as u8,
|
||||||
@ -520,7 +519,7 @@ mod test {
|
|||||||
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
||||||
|
|
||||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Normal, SectionID::Skyly);
|
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Normal, SectionID::Skyly);
|
||||||
assert!(gwt.get_drop(&MapVariantType::Forest1, &mut rng) == Some(ItemDetail::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapVariantType::Forest1, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Cane,
|
weapon: WeaponType::Cane,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 0,
|
grind: 0,
|
||||||
@ -529,7 +528,7 @@ mod test {
|
|||||||
})));
|
})));
|
||||||
|
|
||||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly);
|
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly);
|
||||||
assert!(gwt.get_drop(&MapVariantType::Caves2, &mut rng) == Some(ItemDetail::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapVariantType::Caves2, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Sniper,
|
weapon: WeaponType::Sniper,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 2,
|
grind: 2,
|
||||||
@ -538,7 +537,7 @@ mod test {
|
|||||||
})));
|
})));
|
||||||
|
|
||||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::VeryHard, SectionID::Skyly);
|
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::VeryHard, SectionID::Skyly);
|
||||||
assert!(gwt.get_drop(&MapVariantType::Mines1, &mut rng) == Some(ItemDetail::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapVariantType::Mines1, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Club,
|
weapon: WeaponType::Club,
|
||||||
special: Some(WeaponSpecial::Berserk),
|
special: Some(WeaponSpecial::Berserk),
|
||||||
grind: 0,
|
grind: 0,
|
||||||
@ -547,7 +546,7 @@ mod test {
|
|||||||
})));
|
})));
|
||||||
|
|
||||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
||||||
assert!(gwt.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDetail::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapVariantType::DarkFalz, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Vulcan,
|
weapon: WeaponType::Vulcan,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 0,
|
grind: 0,
|
||||||
|
@ -15,7 +15,6 @@ use std::io::Read;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
|
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::ship::monster::MonsterType;
|
use crate::ship::monster::MonsterType;
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
@ -28,6 +27,7 @@ use crate::ship::drops::tool_table::ToolTable;
|
|||||||
use crate::ship::drops::rare_drop_table::RareDropTable;
|
use crate::ship::drops::rare_drop_table::RareDropTable;
|
||||||
use crate::ship::drops::box_drop_table::BoxDropTable;
|
use crate::ship::drops::box_drop_table::BoxDropTable;
|
||||||
use crate::ship::map::MapObject;
|
use crate::ship::map::MapObject;
|
||||||
|
use crate::entity::item::{weapon, armor, shield, unit, mag, tool, tech};
|
||||||
|
|
||||||
|
|
||||||
fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf {
|
fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf {
|
||||||
@ -71,19 +71,26 @@ pub struct MonsterDropStats {
|
|||||||
pub max_meseta: u32,
|
pub max_meseta: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ItemDropType
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum ItemDropItem {
|
pub enum ItemDropType {
|
||||||
Weapon,
|
Weapon(weapon::Weapon),
|
||||||
|
Armor(armor::Armor),
|
||||||
|
Shield(shield::Shield),
|
||||||
|
Unit(unit::Unit),
|
||||||
|
Tool(tool::Tool),
|
||||||
|
TechniqueDisk(tech::TechniqueDisk),
|
||||||
|
Mag(mag::Mag),
|
||||||
|
Meseta(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ItemDrop {
|
struct ItemDrop {
|
||||||
x: f32,
|
x: f32,
|
||||||
y: f32,
|
y: f32,
|
||||||
z: f32,
|
z: f32,
|
||||||
item: ItemDropItem,
|
item: ItemDropType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemDropItem {
|
impl ItemDrop {
|
||||||
pub fn as_client_bytes(&self) -> u8 {
|
pub fn as_client_bytes(&self) -> u8 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
@ -129,11 +136,11 @@ impl<R: Rng + SeedableRng> DropTable<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_meseta(&self, monster: &MonsterDropStats) -> Option<ItemDetail> {
|
fn generate_meseta(&mut self, monster: &MonsterDropStats) -> Option<ItemDropType> {
|
||||||
None
|
Some(ItemDropType::Meseta(self.rng.gen_range(monster.min_meseta, monster.max_meseta)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_typed_drop(&mut self, map_area: &MapVariantType, monster: &MonsterDropStats) -> Option<ItemDetail> {
|
fn generate_typed_drop(&mut self, map_area: &MapVariantType, monster: &MonsterDropStats) -> Option<ItemDropType> {
|
||||||
match monster.drop_type {
|
match monster.drop_type {
|
||||||
MonsterDropType::Weapon => self.weapon_table.get_drop(map_area, &mut self.rng),
|
MonsterDropType::Weapon => self.weapon_table.get_drop(map_area, &mut self.rng),
|
||||||
MonsterDropType::Armor => self.armor_table.get_drop(map_area, &mut self.rng),
|
MonsterDropType::Armor => self.armor_table.get_drop(map_area, &mut self.rng),
|
||||||
@ -143,7 +150,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_drop(&mut self, map_area: &MapVariantType, monster: &MonsterType) -> Option<ItemDetail> {
|
fn get_drop(&mut self, map_area: &MapVariantType, monster: &MonsterType) -> Option<ItemDropType> {
|
||||||
let monster_stat = *self.monster_stats.get(monster)?;
|
let monster_stat = *self.monster_stats.get(monster)?;
|
||||||
|
|
||||||
let drop_anything = self.rng.gen_range(0, 100);
|
let drop_anything = self.rng.gen_range(0, 100);
|
||||||
@ -171,7 +178,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_box_drop(&mut self, map_area: &MapVariantType, object: &MapObject) -> Option<ItemDetail> {
|
pub fn get_box_drop(&mut self, map_area: &MapVariantType, object: &MapObject) -> Option<ItemDropType> {
|
||||||
self.box_table.get_drop(map_area, object, &mut self.rng)
|
self.box_table.get_drop(map_area, object, &mut self.rng)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::weapon::{Weapon, WeaponType};
|
use crate::entity::item::weapon::{Weapon, WeaponType};
|
||||||
use crate::entity::item::armor::{Armor, ArmorType};
|
use crate::entity::item::armor::{Armor, ArmorType};
|
||||||
use crate::entity::item::shield::{Shield, ShieldType};
|
use crate::entity::item::shield::{Shield, ShieldType};
|
||||||
@ -12,7 +11,7 @@ use crate::entity::character::SectionID;
|
|||||||
use crate::ship::monster::MonsterType;
|
use crate::ship::monster::MonsterType;
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
use crate::ship::drops::generic_weapon::AttributeTable;
|
use crate::ship::drops::generic_weapon::AttributeTable;
|
||||||
use crate::ship::drops::generic_armor::GenericArmorTable;
|
use crate::ship::drops::generic_armor::GenericArmorTable;
|
||||||
use crate::ship::drops::generic_shield::GenericShieldTable;
|
use crate::ship::drops::generic_shield::GenericShieldTable;
|
||||||
@ -96,10 +95,10 @@ impl RareDropTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_item_stats<R: Rng>(&self, map_area: &MapVariantType, item: RareDropItem, rng: &mut R) -> ItemDetail {
|
pub fn apply_item_stats<R: Rng>(&self, map_area: &MapVariantType, item: RareDropItem, rng: &mut R) -> ItemDropType {
|
||||||
match item {
|
match item {
|
||||||
RareDropItem::Weapon(weapon) => {
|
RareDropItem::Weapon(weapon) => {
|
||||||
ItemDetail::Weapon(Weapon {
|
ItemDropType::Weapon(Weapon {
|
||||||
weapon: weapon,
|
weapon: weapon,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 0,
|
grind: 0,
|
||||||
@ -109,7 +108,7 @@ impl RareDropTable {
|
|||||||
|
|
||||||
},
|
},
|
||||||
RareDropItem::Armor(armor) => {
|
RareDropItem::Armor(armor) => {
|
||||||
ItemDetail::Armor(Armor {
|
ItemDropType::Armor(Armor {
|
||||||
armor: armor,
|
armor: armor,
|
||||||
dfp: self.armor_stats.dfp_modifier(&armor, rng) as u8,
|
dfp: self.armor_stats.dfp_modifier(&armor, rng) as u8,
|
||||||
evp: self.armor_stats.evp_modifier(&armor, rng) as u8,
|
evp: self.armor_stats.evp_modifier(&armor, rng) as u8,
|
||||||
@ -117,25 +116,25 @@ impl RareDropTable {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
RareDropItem::Shield(shield) => {
|
RareDropItem::Shield(shield) => {
|
||||||
ItemDetail::Shield(Shield {
|
ItemDropType::Shield(Shield {
|
||||||
shield: shield,
|
shield: shield,
|
||||||
dfp: self.shield_stats.dfp_modifier(&shield, rng) as u8,
|
dfp: self.shield_stats.dfp_modifier(&shield, rng) as u8,
|
||||||
evp: self.shield_stats.evp_modifier(&shield, rng) as u8,
|
evp: self.shield_stats.evp_modifier(&shield, rng) as u8,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
RareDropItem::Unit(unit) => {
|
RareDropItem::Unit(unit) => {
|
||||||
ItemDetail::Unit(Unit {
|
ItemDropType::Unit(Unit {
|
||||||
unit: unit,
|
unit: unit,
|
||||||
modifier: None,
|
modifier: None,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
RareDropItem::Tool(tool) => {
|
RareDropItem::Tool(tool) => {
|
||||||
ItemDetail::Tool(Tool {
|
ItemDropType::Tool(Tool {
|
||||||
tool: tool,
|
tool: tool,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
RareDropItem::Mag(mag) => {
|
RareDropItem::Mag(mag) => {
|
||||||
ItemDetail::Mag(Mag {
|
ItemDropType::Mag(Mag {
|
||||||
mag: mag,
|
mag: mag,
|
||||||
def: 500,
|
def: 500,
|
||||||
pow: 0,
|
pow: 0,
|
||||||
@ -149,7 +148,7 @@ impl RareDropTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, monster: &MonsterType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, monster: &MonsterType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
self.rates.get(monster)
|
self.rates.get(monster)
|
||||||
.and_then(|drop_rates| {
|
.and_then(|drop_rates| {
|
||||||
drop_rates.iter()
|
drop_rates.iter()
|
||||||
|
@ -4,12 +4,11 @@ use serde::{Serialize, Deserialize};
|
|||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
|
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::tech::{Technique, TechniqueDisk};
|
use crate::entity::item::tech::{Technique, TechniqueDisk};
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -96,14 +95,14 @@ impl TechniqueTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
let mut tech_rates = self.rates.get_by_area(map_area).iter();
|
let mut tech_rates = self.rates.get_by_area(map_area).iter();
|
||||||
let tech_weights = WeightedIndex::new(tech_rates.clone().map(|(_, stat)| stat.rate)).unwrap();
|
let tech_weights = WeightedIndex::new(tech_rates.clone().map(|(_, stat)| stat.rate)).unwrap();
|
||||||
|
|
||||||
let (tech, stat) = tech_rates.nth(tech_weights.sample(rng)).unwrap();
|
let (tech, stat) = tech_rates.nth(tech_weights.sample(rng)).unwrap();
|
||||||
let level = rng.gen_range(stat.min, stat.max+1);
|
let level = rng.gen_range(stat.min, stat.max+1);
|
||||||
|
|
||||||
Some(ItemDetail::TechniqueDisk(TechniqueDisk {
|
Some(ItemDropType::TechniqueDisk(TechniqueDisk {
|
||||||
tech: *tech,
|
tech: *tech,
|
||||||
level: level as u32
|
level: level as u32
|
||||||
}))
|
}))
|
||||||
@ -125,7 +124,7 @@ mod test {
|
|||||||
(MapVariantType::DarkFalz, Technique::Razonde, 22)];
|
(MapVariantType::DarkFalz, Technique::Razonde, 22)];
|
||||||
|
|
||||||
for (area, tech, level) in tech_tests {
|
for (area, tech, level) in tech_tests {
|
||||||
assert!(tt.get_drop(&area, &mut rng) == Some(ItemDetail::TechniqueDisk(
|
assert!(tt.get_drop(&area, &mut rng) == Some(ItemDropType::TechniqueDisk(
|
||||||
TechniqueDisk {
|
TechniqueDisk {
|
||||||
tech: tech,
|
tech: tech,
|
||||||
level: level
|
level: level
|
||||||
|
@ -4,12 +4,11 @@ use serde::{Serialize, Deserialize};
|
|||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
|
|
||||||
use crate::entity::item::ItemDetail;
|
|
||||||
use crate::entity::item::tool::{Tool, ToolType};
|
use crate::entity::item::tool::{Tool, ToolType};
|
||||||
use crate::ship::room::{Difficulty, Episode};
|
use crate::ship::room::{Difficulty, Episode};
|
||||||
use crate::ship::map::MapVariantType;
|
use crate::ship::map::MapVariantType;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::load_data_file;
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
use crate::ship::drops::tech_table::TechniqueTable;
|
use crate::ship::drops::tech_table::TechniqueTable;
|
||||||
|
|
||||||
|
|
||||||
@ -125,7 +124,7 @@ impl ToolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
||||||
let tool_rates = self.rates.get_by_area(map_area).iter();
|
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_weights = WeightedIndex::new(tool_rates.clone().map(|(_, weights)| weights)).unwrap();
|
||||||
|
|
||||||
@ -159,7 +158,7 @@ impl ToolTable {
|
|||||||
ToolRateType::Technique => return self.tech_table.get_drop(map_area, rng),
|
ToolRateType::Technique => return self.tech_table.get_drop(map_area, rng),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(ItemDetail::Tool(Tool {
|
Some(ItemDropType::Tool(Tool {
|
||||||
tool: tool_type
|
tool: tool_type
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user