MapVariantType -> MapArea
This commit is contained in:
parent
c24161bfd4
commit
1279fedfee
@ -10,7 +10,7 @@ use crate::entity::item::tool::{Tool, ToolType};
|
|||||||
use crate::entity::character::SectionID;
|
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::MapArea;
|
||||||
use crate::ship::drops::{ItemDropType, 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};
|
||||||
@ -49,8 +49,8 @@ struct BoxDropRates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BoxDropRates {
|
impl BoxDropRates {
|
||||||
fn rates_by_area(&self, map_area: &MapVariantType) -> &BoxDropRate {
|
fn rates_by_area(&self, map_area: &MapArea) -> &BoxDropRate {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => &self.area1,
|
0 => &self.area1,
|
||||||
1 => &self.area2,
|
1 => &self.area2,
|
||||||
2 => &self.area3,
|
2 => &self.area3,
|
||||||
@ -122,8 +122,8 @@ impl BoxRareRates {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rates_by_area(&self, map_area: &MapVariantType) -> &Vec<BoxRareRate> {
|
fn rates_by_area(&self, map_area: &MapArea) -> &Vec<BoxRareRate> {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => &self.area1,
|
0 => &self.area1,
|
||||||
1 => &self.area2,
|
1 => &self.area2,
|
||||||
2 => &self.area3,
|
2 => &self.area3,
|
||||||
@ -171,7 +171,7 @@ impl BoxDropTable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rare_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
fn rare_drop<R: Rng>(&self, map_area: &MapArea, 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();
|
||||||
@ -184,7 +184,7 @@ impl BoxDropTable {
|
|||||||
}).nth(0)
|
}).nth(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_box_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
fn random_box_drop<R: Rng>(&self, map_area: &MapArea, 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,
|
||||||
@ -202,7 +202,7 @@ impl BoxDropTable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fixed_box_drop<R: Rng>(&self, fixed_drop: FixedBoxDropType, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
fn fixed_box_drop<R: Rng>(&self, fixed_drop: FixedBoxDropType, map_area: &MapArea, 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?
|
||||||
@ -216,7 +216,7 @@ impl BoxDropTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, object: &MapObject, rng: &mut R) -> Option<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapArea, 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 => {
|
||||||
@ -243,6 +243,6 @@ mod test {
|
|||||||
|
|
||||||
let bdt = BoxDropTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
let bdt = BoxDropTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
||||||
|
|
||||||
println!("{:?}", bdt.get_drop(&MapVariantType::Forest1, &MapObject {object: MapObjectType::Box}, &mut rng));
|
println!("{:?}", bdt.get_drop(&MapArea::Forest1, &MapObject {object: MapObjectType::Box}, &mut rng));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use rand::distributions::{WeightedIndex, Distribution};
|
|||||||
|
|
||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::{ItemDropType, 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};
|
||||||
@ -45,11 +45,11 @@ impl GenericArmorTable {
|
|||||||
gat
|
gat
|
||||||
}
|
}
|
||||||
|
|
||||||
fn armor_type<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> ArmorType {
|
fn armor_type<R: Rng>(&self, area_map: &MapArea, rng: &mut R) -> ArmorType {
|
||||||
let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
|
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();
|
self.rank_rates.rank3, self.rank_rates.rank4]).unwrap();
|
||||||
let rank = rank_weights.sample(rng) as i32;
|
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);
|
let armor_level = std::cmp::max(0i32, self.armor_set as i32 - 3i32 + rank + area_map.drop_area_value().unwrap_or(0) as i32);
|
||||||
match armor_level {
|
match armor_level {
|
||||||
0x00 => ArmorType::Frame,
|
0x00 => ArmorType::Frame,
|
||||||
0x01 => ArmorType::Armor,
|
0x01 => ArmorType::Armor,
|
||||||
@ -79,7 +79,7 @@ impl GenericArmorTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slots<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> usize {
|
pub fn slots<R: Rng>(&self, area_map: &MapArea, rng: &mut R) -> usize {
|
||||||
let slot_weights = WeightedIndex::new(&[self.slot_rates.slot0, self.slot_rates.slot1, self.slot_rates.slot2,
|
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();
|
self.slot_rates.slot3, self.slot_rates.slot4]).unwrap();
|
||||||
slot_weights.sample(rng)
|
slot_weights.sample(rng)
|
||||||
@ -95,7 +95,7 @@ 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<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, area_map: &MapArea, 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);
|
||||||
@ -120,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(ItemDropType::Armor(Armor {
|
assert!(gat.get_drop(&MapArea::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(ItemDropType::Armor(Armor {
|
assert!(gat.get_drop(&MapArea::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(ItemDropType::Armor(Armor {
|
assert!(gat.get_drop(&MapArea::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(ItemDropType::Armor(Armor {
|
assert!(gat.get_drop(&MapArea::DarkFalz, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||||
armor: ArmorType::ImperialArmor,
|
armor: ArmorType::ImperialArmor,
|
||||||
dfp: 2,
|
dfp: 2,
|
||||||
evp: 1,
|
evp: 1,
|
||||||
|
@ -5,7 +5,7 @@ use rand::distributions::{WeightedIndex, Distribution};
|
|||||||
|
|
||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::{ItemDropType, 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};
|
||||||
@ -35,11 +35,11 @@ impl GenericShieldTable {
|
|||||||
gst
|
gst
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shield_type<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> ShieldType {
|
fn shield_type<R: Rng>(&self, area_map: &MapArea, rng: &mut R) -> ShieldType {
|
||||||
let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
|
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();
|
self.rank_rates.rank3, self.rank_rates.rank4]).unwrap();
|
||||||
let rank = rank_weights.sample(rng) as i32;
|
let rank = rank_weights.sample(rng) as i32;
|
||||||
let shield_level = std::cmp::max(0i32, self.shield_set as i32 - 3i32 + rank + area_map.area_value().unwrap_or(0) as i32);
|
let shield_level = std::cmp::max(0i32, self.shield_set as i32 - 3i32 + rank + area_map.drop_area_value().unwrap_or(0) as i32);
|
||||||
match shield_level {
|
match shield_level {
|
||||||
0x00 => ShieldType::Barrier,
|
0x00 => ShieldType::Barrier,
|
||||||
0x01 => ShieldType::Shield,
|
0x01 => ShieldType::Shield,
|
||||||
@ -76,7 +76,7 @@ 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<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, area_map: &MapArea, 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);
|
||||||
@ -100,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(ItemDropType::Shield(Shield {
|
assert!(gst.get_drop(&MapArea::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(ItemDropType::Shield(Shield {
|
assert!(gst.get_drop(&MapArea::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(ItemDropType::Shield(Shield {
|
assert!(gst.get_drop(&MapArea::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(ItemDropType::Shield(Shield {
|
assert!(gst.get_drop(&MapArea::DarkFalz, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||||
shield: ShieldType::DivinityBarrier,
|
shield: ShieldType::DivinityBarrier,
|
||||||
dfp: 1,
|
dfp: 1,
|
||||||
evp: 0,
|
evp: 0,
|
||||||
|
@ -6,7 +6,7 @@ use rand::seq::IteratorRandom;
|
|||||||
|
|
||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::{ItemDropType, 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};
|
||||||
@ -28,8 +28,8 @@ struct UnitLevels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UnitLevels {
|
impl UnitLevels {
|
||||||
fn level_by_area(&self, map_area: &MapVariantType) -> u32 {
|
fn level_by_area(&self, map_area: &MapArea) -> u32 {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => self.area1,
|
0 => self.area1,
|
||||||
1 => self.area2,
|
1 => self.area2,
|
||||||
2 => self.area3,
|
2 => self.area3,
|
||||||
@ -60,7 +60,7 @@ impl GenericUnitTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unit_type_and_modifier<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<(UnitType, Option<UnitModifier>)> {
|
fn unit_type_and_modifier<R: Rng>(&self, area_map: &MapArea, rng: &mut R) -> Option<(UnitType, Option<UnitModifier>)> {
|
||||||
let level = self.unit_levels.level_by_area(area_map) as i32;
|
let level = self.unit_levels.level_by_area(area_map) as i32;
|
||||||
if level == 0 {
|
if level == 0 {
|
||||||
return None;
|
return None;
|
||||||
@ -83,7 +83,7 @@ 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<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, area_map: &MapArea, 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)| {
|
||||||
@ -104,14 +104,14 @@ mod test {
|
|||||||
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
||||||
|
|
||||||
let gut = GenericUnitTable::new(Episode::One, Difficulty::Normal, SectionID::Skyly);
|
let gut = GenericUnitTable::new(Episode::One, Difficulty::Normal, SectionID::Skyly);
|
||||||
assert!(gut.get_drop(&MapVariantType::Forest1, &mut rng) == None);
|
assert!(gut.get_drop(&MapArea::Forest1, &mut rng) == None);
|
||||||
|
|
||||||
let gut = GenericUnitTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly);
|
let gut = GenericUnitTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly);
|
||||||
|
|
||||||
let unit_tests = vec![(MapVariantType::Forest1, UnitType::ResistFreeze, Some(UnitModifier::PlusPlus)),
|
let unit_tests = vec![(MapArea::Forest1, UnitType::ResistFreeze, Some(UnitModifier::PlusPlus)),
|
||||||
(MapVariantType::Caves3, UnitType::GeneralTp, None),
|
(MapArea::Caves3, UnitType::GeneralTp, None),
|
||||||
(MapVariantType::Mines2, UnitType::ResistEvil, Some(UnitModifier::PlusPlus)),
|
(MapArea::Mines2, UnitType::ResistEvil, Some(UnitModifier::PlusPlus)),
|
||||||
(MapVariantType::DarkFalz, UnitType::DragonHp, Some(UnitModifier::Minus))];
|
(MapArea::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(ItemDropType::Unit(Unit {
|
assert!(gut.get_drop(&area, &mut rng) == Some(ItemDropType::Unit(Unit {
|
||||||
unit: unit,
|
unit: unit,
|
||||||
|
@ -8,7 +8,7 @@ use rand::seq::SliceRandom;
|
|||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::{ItemDropType, load_data_file};
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
|
|
||||||
@ -95,8 +95,8 @@ struct AttributeRates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AttributeRates {
|
impl AttributeRates {
|
||||||
fn get_by_area(&self, map_area: &MapVariantType) -> AttributeRate {
|
fn get_by_area(&self, map_area: &MapArea) -> AttributeRate {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => self.area1,
|
0 => self.area1,
|
||||||
1 => self.area2,
|
1 => self.area2,
|
||||||
2 => self.area3,
|
2 => self.area3,
|
||||||
@ -179,8 +179,8 @@ struct AreaPercentPatterns {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AreaPercentPatterns {
|
impl AreaPercentPatterns {
|
||||||
fn get_by_area(&self, map_area: &MapVariantType) -> AttributePercentPattern {
|
fn get_by_area(&self, map_area: &MapArea) -> AttributePercentPattern {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => self.area1,
|
0 => self.area1,
|
||||||
1 => self.area2,
|
1 => self.area2,
|
||||||
2 => self.area3,
|
2 => self.area3,
|
||||||
@ -301,13 +301,13 @@ impl AttributeTable {
|
|||||||
}).0
|
}).0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_attributes<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
|
fn generate_attributes<R: Rng>(&self, map_area: &MapArea, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
|
||||||
let percent_pattern = self.area_percent_patterns.get_by_area(map_area);
|
let percent_pattern = self.area_percent_patterns.get_by_area(map_area);
|
||||||
let attribute_rate = self.attribute_rates.get_by_area(map_area);
|
let attribute_rate = self.attribute_rates.get_by_area(map_area);
|
||||||
self.attributes(&percent_pattern, &attribute_rate, rng)
|
self.attributes(&percent_pattern, &attribute_rate, rng)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_rare_attributes<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
|
pub fn generate_rare_attributes<R: Rng>(&self, map_area: &MapArea, rng: &mut R) -> [Option<WeaponAttribute>; 3] {
|
||||||
let percent_pattern = AttributePercentPattern {
|
let percent_pattern = AttributePercentPattern {
|
||||||
attribute1: Some(PercentPatternType::Pattern6),
|
attribute1: Some(PercentPatternType::Pattern6),
|
||||||
attribute2: Some(PercentPatternType::Pattern6),
|
attribute2: Some(PercentPatternType::Pattern6),
|
||||||
@ -345,8 +345,8 @@ impl SpecialRates {
|
|||||||
load_data_file(episode, difficulty, section_id, "weapon_special_rate.toml")
|
load_data_file(episode, difficulty, section_id, "weapon_special_rate.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rate_by_area(&self, map_area: &MapVariantType) -> SpecialRate {
|
fn rate_by_area(&self, map_area: &MapArea) -> SpecialRate {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => self.area1,
|
0 => self.area1,
|
||||||
1 => self.area2,
|
1 => self.area2,
|
||||||
2 => self.area3,
|
2 => self.area3,
|
||||||
@ -376,7 +376,7 @@ impl SpecialRates {
|
|||||||
*specials.choose(rng).unwrap()
|
*specials.choose(rng).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_special<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<WeaponSpecial> {
|
fn get_special<R: Rng>(&self, map_area: &MapArea, rng: &mut R) -> Option<WeaponSpecial> {
|
||||||
let rate = self.rate_by_area(map_area);
|
let rate = self.rate_by_area(map_area);
|
||||||
if rng.gen_range(0, 100) < rate.rate {
|
if rng.gen_range(0, 100) < rate.rate {
|
||||||
Some(self.random_special_by_rank(rate.rank, rng))
|
Some(self.random_special_by_rank(rate.rank, rng))
|
||||||
@ -422,16 +422,16 @@ impl GenericWeaponTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn area_rank(&self, ratio: &WeaponRatio, map_area: &MapVariantType) -> (u32, u32) {
|
fn area_rank(&self, ratio: &WeaponRatio, map_area: &MapArea) -> (u32, u32) {
|
||||||
if ratio.rank >= 0 {
|
if ratio.rank >= 0 {
|
||||||
(map_area.area_value().unwrap_or(0), ratio.rank as u32)
|
(map_area.drop_area_value().unwrap_or(0), ratio.rank as u32)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
((map_area.area_value().unwrap_or(0) as i32 + ratio.rank) as u32, 0)
|
((map_area.drop_area_value().unwrap_or(0) as i32 + ratio.rank) as u32, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_possible_weapon_types(&self, map_area: &MapVariantType) -> BTreeMap<WeaponDropType, WeaponRatio> {
|
fn get_possible_weapon_types(&self, map_area: &MapArea) -> BTreeMap<WeaponDropType, WeaponRatio> {
|
||||||
let mut valid_weapons = BTreeMap::new();
|
let mut valid_weapons = BTreeMap::new();
|
||||||
|
|
||||||
let item_rate_pairs = vec![
|
let item_rate_pairs = vec![
|
||||||
@ -450,7 +450,7 @@ impl GenericWeaponTable {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (item_type, ratio) in item_rate_pairs.into_iter() {
|
for (item_type, ratio) in item_rate_pairs.into_iter() {
|
||||||
if ratio.rate > 0 && map_area.area_value().map(|k| k as i32 + ratio.rank).unwrap_or(-1) >= 0 {
|
if ratio.rate > 0 && map_area.drop_area_value().map(|k| k as i32 + ratio.rank).unwrap_or(-1) >= 0 {
|
||||||
valid_weapons.insert(item_type, ratio);
|
valid_weapons.insert(item_type, ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -458,7 +458,7 @@ impl GenericWeaponTable {
|
|||||||
valid_weapons
|
valid_weapons
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weapon_type<R: Rng>(&self, possible_weapon_types: &BTreeMap<WeaponDropType, WeaponRatio>, map_area: &MapVariantType, rng: &mut R) -> WeaponDropType {
|
fn weapon_type<R: Rng>(&self, possible_weapon_types: &BTreeMap<WeaponDropType, WeaponRatio>, map_area: &MapArea, rng: &mut R) -> WeaponDropType {
|
||||||
let mut weapon_rates = possible_weapon_types.iter()
|
let mut weapon_rates = possible_weapon_types.iter()
|
||||||
.map(|(weapon, stat)| {
|
.map(|(weapon, stat)| {
|
||||||
(weapon, stat.rate)
|
(weapon, stat.rate)
|
||||||
@ -468,7 +468,7 @@ impl GenericWeaponTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn weapon_rank(&self, ratio: &WeaponRatio, map_area: &MapVariantType) -> u32 {
|
fn weapon_rank(&self, ratio: &WeaponRatio, map_area: &MapArea) -> u32 {
|
||||||
let (area, rank) = self.area_rank(ratio, map_area);
|
let (area, rank) = self.area_rank(ratio, map_area);
|
||||||
let weapon_rank = (rank + area / ratio.inc);
|
let weapon_rank = (rank + area / ratio.inc);
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ impl GenericWeaponTable {
|
|||||||
weapons[std::cmp::min(weapons.len() - 1, weapon_rank as usize)]
|
weapons[std::cmp::min(weapons.len() - 1, weapon_rank as usize)]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_grind<R: Rng>(&self, ratio: &WeaponRatio, map_area: &MapVariantType, rng: &mut R) -> usize {
|
fn get_grind<R: Rng>(&self, ratio: &WeaponRatio, map_area: &MapArea, rng: &mut R) -> usize {
|
||||||
let (area, _) = self.area_rank(ratio, map_area);
|
let (area, _) = self.area_rank(ratio, map_area);
|
||||||
let pattern = std::cmp::min(area % ratio.inc, 3);
|
let pattern = std::cmp::min(area % ratio.inc, 3);
|
||||||
|
|
||||||
@ -489,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<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapArea, 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();
|
||||||
@ -519,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(ItemDropType::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapArea::Forest1, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Cane,
|
weapon: WeaponType::Cane,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 0,
|
grind: 0,
|
||||||
@ -528,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(ItemDropType::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapArea::Caves2, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Sniper,
|
weapon: WeaponType::Sniper,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 2,
|
grind: 2,
|
||||||
@ -537,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(ItemDropType::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapArea::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,
|
||||||
@ -546,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(ItemDropType::Weapon(Weapon {
|
assert!(gwt.get_drop(&MapArea::DarkFalz, &mut rng) == Some(ItemDropType::Weapon(Weapon {
|
||||||
weapon: WeaponType::Vulcan,
|
weapon: WeaponType::Vulcan,
|
||||||
special: None,
|
special: None,
|
||||||
grind: 0,
|
grind: 0,
|
||||||
|
@ -17,7 +17,7 @@ use rand::{Rng, SeedableRng};
|
|||||||
|
|
||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::generic_weapon::GenericWeaponTable;
|
use crate::ship::drops::generic_weapon::GenericWeaponTable;
|
||||||
use crate::ship::drops::generic_armor::GenericArmorTable;
|
use crate::ship::drops::generic_armor::GenericArmorTable;
|
||||||
@ -98,7 +98,7 @@ impl ItemDrop {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct DropTable<R: Rng + SeedableRng> {
|
pub struct DropTable<R: Rng + SeedableRng> {
|
||||||
monster_stats: HashMap<MonsterType, MonsterDropStats>,
|
monster_stats: HashMap<MonsterType, MonsterDropStats>,
|
||||||
rare_table: RareDropTable,
|
rare_table: RareDropTable,
|
||||||
weapon_table: GenericWeaponTable,
|
weapon_table: GenericWeaponTable,
|
||||||
@ -112,7 +112,7 @@ struct DropTable<R: Rng + SeedableRng> {
|
|||||||
|
|
||||||
|
|
||||||
impl<R: Rng + SeedableRng> DropTable<R> {
|
impl<R: Rng + SeedableRng> DropTable<R> {
|
||||||
fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable<R> {
|
pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable<R> {
|
||||||
let mut path = PathBuf::from("data/drops/");
|
let mut path = PathBuf::from("data/drops/");
|
||||||
path.push(episode.to_string());
|
path.push(episode.to_string());
|
||||||
path.push(difficulty.to_string().to_lowercase());
|
path.push(difficulty.to_string().to_lowercase());
|
||||||
@ -140,7 +140,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
|
|||||||
Some(ItemDropType::Meseta(self.rng.gen_range(monster.min_meseta, monster.max_meseta)))
|
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<ItemDropType> {
|
fn generate_typed_drop(&mut self, map_area: &MapArea, 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),
|
||||||
@ -150,7 +150,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_drop(&mut self, map_area: &MapVariantType, monster: &MonsterType) -> Option<ItemDropType> {
|
pub fn get_drop(&mut self, map_area: &MapArea, 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);
|
||||||
@ -178,7 +178,7 @@ impl<R: Rng + SeedableRng> DropTable<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_box_drop(&mut self, map_area: &MapVariantType, object: &MapObject) -> Option<ItemDropType> {
|
pub fn get_box_drop(&mut self, map_area: &MapArea, 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use crate::entity::item::mag::{Mag, MagType};
|
|||||||
use crate::entity::character::SectionID;
|
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::MapArea;
|
||||||
use crate::ship::drops::{ItemDropType, 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;
|
||||||
@ -95,7 +95,7 @@ impl RareDropTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_item_stats<R: Rng>(&self, map_area: &MapVariantType, item: RareDropItem, rng: &mut R) -> ItemDropType {
|
pub fn apply_item_stats<R: Rng>(&self, map_area: &MapArea, item: RareDropItem, rng: &mut R) -> ItemDropType {
|
||||||
match item {
|
match item {
|
||||||
RareDropItem::Weapon(weapon) => {
|
RareDropItem::Weapon(weapon) => {
|
||||||
ItemDropType::Weapon(Weapon {
|
ItemDropType::Weapon(Weapon {
|
||||||
@ -148,7 +148,7 @@ impl RareDropTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, monster: &MonsterType, rng: &mut R) -> Option<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapArea, 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()
|
||||||
|
@ -6,7 +6,7 @@ use rand::distributions::{WeightedIndex, Distribution};
|
|||||||
|
|
||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::{ItemDropType, load_data_file};
|
use crate::ship::drops::{ItemDropType, load_data_file};
|
||||||
|
|
||||||
@ -65,8 +65,8 @@ impl TechniqueRates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TechniqueRates {
|
impl TechniqueRates {
|
||||||
fn get_by_area<'a>(&'a self, map_area: &MapVariantType) -> &'a BTreeMap<Technique, TechniqueRateStat> {
|
fn get_by_area<'a>(&'a self, map_area: &MapArea) -> &'a BTreeMap<Technique, TechniqueRateStat> {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => &self.area1,
|
0 => &self.area1,
|
||||||
1 => &self.area2,
|
1 => &self.area2,
|
||||||
2 => &self.area3,
|
2 => &self.area3,
|
||||||
@ -95,7 +95,7 @@ impl TechniqueTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapArea, 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();
|
||||||
|
|
||||||
@ -118,10 +118,10 @@ mod test {
|
|||||||
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
|
||||||
let tt = TechniqueTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
let tt = TechniqueTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
||||||
|
|
||||||
let tech_tests = vec![(MapVariantType::Forest1, Technique::Resta, 13),
|
let tech_tests = vec![(MapArea::Forest1, Technique::Resta, 13),
|
||||||
(MapVariantType::Caves3, Technique::Foie, 24),
|
(MapArea::Caves3, Technique::Foie, 24),
|
||||||
(MapVariantType::Mines2, Technique::Gibarta, 20),
|
(MapArea::Mines2, Technique::Gibarta, 20),
|
||||||
(MapVariantType::DarkFalz, Technique::Razonde, 22)];
|
(MapArea::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(ItemDropType::TechniqueDisk(
|
assert!(tt.get_drop(&area, &mut rng) == Some(ItemDropType::TechniqueDisk(
|
||||||
|
@ -6,7 +6,7 @@ use rand::distributions::{WeightedIndex, Distribution};
|
|||||||
|
|
||||||
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::MapArea;
|
||||||
use crate::entity::character::SectionID;
|
use crate::entity::character::SectionID;
|
||||||
use crate::ship::drops::{ItemDropType, 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;
|
||||||
@ -93,8 +93,8 @@ impl ToolRates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ToolRates {
|
impl ToolRates {
|
||||||
fn get_by_area<'a>(&'a self, map_area: &MapVariantType) -> &'a BTreeMap<ToolRateType, u32> {
|
fn get_by_area<'a>(&'a self, map_area: &MapArea) -> &'a BTreeMap<ToolRateType, u32> {
|
||||||
match map_area.area_value().unwrap() {
|
match map_area.drop_area_value().unwrap() {
|
||||||
0 => &self.area1,
|
0 => &self.area1,
|
||||||
1 => &self.area2,
|
1 => &self.area2,
|
||||||
2 => &self.area3,
|
2 => &self.area3,
|
||||||
@ -124,7 +124,7 @@ impl ToolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_drop<R: Rng>(&self, map_area: &MapVariantType, rng: &mut R) -> Option<ItemDropType> {
|
pub fn get_drop<R: Rng>(&self, map_area: &MapArea, 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();
|
||||||
|
|
||||||
|
180
src/ship/map.rs
180
src/ship/map.rs
@ -340,9 +340,8 @@ enum MapVariantMode {
|
|||||||
Offline,
|
Offline,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: rename this since apparently I'm going to be using it a lot
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MapVariantType {
|
pub enum MapArea {
|
||||||
Pioneer2Ep1,
|
Pioneer2Ep1,
|
||||||
Forest1,
|
Forest1,
|
||||||
Forest2,
|
Forest2,
|
||||||
@ -360,23 +359,48 @@ pub enum MapVariantType {
|
|||||||
DarkFalz,
|
DarkFalz,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MapVariantType {
|
pub enum MapAreaError {
|
||||||
pub fn area_value(&self) -> Option<u32> {
|
UnknownMapArea(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MapArea {
|
||||||
|
pub fn from_value(episode: Episode, area: u32) -> Result<MapArea, MapAreaError> {
|
||||||
|
match (episode, area) {
|
||||||
|
(Episode::One, 0) => Ok(MapArea::Pioneer2Ep1),
|
||||||
|
(Episode::One, 1) => Ok(MapArea::Forest1),
|
||||||
|
(Episode::One, 2) => Ok(MapArea::Forest2),
|
||||||
|
(Episode::One, 3) => Ok(MapArea::Caves1),
|
||||||
|
(Episode::One, 4) => Ok(MapArea::Caves2),
|
||||||
|
(Episode::One, 5) => Ok(MapArea::Caves3),
|
||||||
|
(Episode::One, 6) => Ok(MapArea::Mines1),
|
||||||
|
(Episode::One, 7) => Ok(MapArea::Mines2),
|
||||||
|
(Episode::One, 8) => Ok(MapArea::Ruins1),
|
||||||
|
(Episode::One, 9) => Ok(MapArea::Ruins2),
|
||||||
|
(Episode::One, 10) => Ok(MapArea::Ruins3),
|
||||||
|
(Episode::One, 11) => Ok(MapArea::Dragon),
|
||||||
|
(Episode::One, 12) => Ok(MapArea::DeRolLe),
|
||||||
|
(Episode::One, 13) => Ok(MapArea::VolOpt),
|
||||||
|
(Episode::One, 14) => Ok(MapArea::DarkFalz),
|
||||||
|
_ => Err(MapAreaError::UnknownMapArea(area))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drop_area_value(&self) -> Option<u32> {
|
||||||
match self {
|
match self {
|
||||||
MapVariantType::Forest1 => Some(0),
|
MapArea::Forest1 => Some(0),
|
||||||
MapVariantType::Forest2 => Some(1),
|
MapArea::Forest2 => Some(1),
|
||||||
MapVariantType::Caves1 => Some(2),
|
MapArea::Caves1 => Some(2),
|
||||||
MapVariantType::Caves2 => Some(3),
|
MapArea::Caves2 => Some(3),
|
||||||
MapVariantType::Caves3 => Some(4),
|
MapArea::Caves3 => Some(4),
|
||||||
MapVariantType::Mines1 => Some(5),
|
MapArea::Mines1 => Some(5),
|
||||||
MapVariantType::Mines2 => Some(6),
|
MapArea::Mines2 => Some(6),
|
||||||
MapVariantType::Ruins1 => Some(7),
|
MapArea::Ruins1 => Some(7),
|
||||||
MapVariantType::Ruins2 => Some(8),
|
MapArea::Ruins2 => Some(8),
|
||||||
MapVariantType::Ruins3 => Some(9),
|
MapArea::Ruins3 => Some(9),
|
||||||
MapVariantType::Dragon => Some(2),
|
MapArea::Dragon => Some(2),
|
||||||
MapVariantType::DeRolLe => Some(5),
|
MapArea::DeRolLe => Some(5),
|
||||||
MapVariantType::VolOpt => Some(7),
|
MapArea::VolOpt => Some(7),
|
||||||
MapVariantType::DarkFalz => Some(9),
|
MapArea::DarkFalz => Some(9),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,31 +409,31 @@ impl MapVariantType {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MapVariant {
|
struct MapVariant {
|
||||||
map: MapVariantType,
|
map: MapArea,
|
||||||
mode: MapVariantMode,
|
mode: MapVariantMode,
|
||||||
major: u8,
|
major: u8,
|
||||||
minor: u8,
|
minor: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MapVariant {
|
impl MapVariant {
|
||||||
fn new(map: MapVariantType, mode: MapVariantMode) -> MapVariant {
|
fn new(map: MapArea, mode: MapVariantMode) -> MapVariant {
|
||||||
let major = match map {
|
let major = match map {
|
||||||
MapVariantType::Pioneer2Ep1 => 0,
|
MapArea::Pioneer2Ep1 => 0,
|
||||||
MapVariantType::Forest1 | MapVariantType::Forest2 => 0,
|
MapArea::Forest1 | MapArea::Forest2 => 0,
|
||||||
MapVariantType::Caves1 | MapVariantType::Caves2 | MapVariantType::Caves3 => rand::thread_rng().gen_range(0, 3),
|
MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 => rand::thread_rng().gen_range(0, 3),
|
||||||
MapVariantType::Mines1 | MapVariantType::Mines2 => rand::thread_rng().gen_range(0, 3),
|
MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 3),
|
||||||
MapVariantType::Ruins1 | MapVariantType::Ruins2 | MapVariantType::Ruins3 => rand::thread_rng().gen_range(0, 3),
|
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 3),
|
||||||
MapVariantType::Dragon | MapVariantType::DeRolLe | MapVariantType::VolOpt | MapVariantType::DarkFalz => 0,
|
MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let minor = match map {
|
let minor = match map {
|
||||||
MapVariantType::Pioneer2Ep1 => 0,
|
MapArea::Pioneer2Ep1 => 0,
|
||||||
MapVariantType::Forest1 => rand::thread_rng().gen_range(0, 5),
|
MapArea::Forest1 => rand::thread_rng().gen_range(0, 5),
|
||||||
MapVariantType::Forest2 => rand::thread_rng().gen_range(0, 5),
|
MapArea::Forest2 => rand::thread_rng().gen_range(0, 5),
|
||||||
MapVariantType::Caves1 | MapVariantType::Caves2 | MapVariantType::Caves3 => rand::thread_rng().gen_range(0, 2),
|
MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 => rand::thread_rng().gen_range(0, 2),
|
||||||
MapVariantType::Mines1 | MapVariantType::Mines2 => rand::thread_rng().gen_range(0, 2),
|
MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 2),
|
||||||
MapVariantType::Ruins1 | MapVariantType::Ruins2 | MapVariantType::Ruins3 => rand::thread_rng().gen_range(0, 2),
|
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 2),
|
||||||
MapVariantType::Dragon | MapVariantType::DeRolLe | MapVariantType::VolOpt | MapVariantType::DarkFalz => 0,
|
MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
MapVariant {
|
MapVariant {
|
||||||
@ -422,41 +446,41 @@ impl MapVariant {
|
|||||||
// TODO: rename to npc_file
|
// TODO: rename to npc_file
|
||||||
fn dat_file(&self) -> String {
|
fn dat_file(&self) -> String {
|
||||||
match self.map {
|
match self.map {
|
||||||
MapVariantType::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
|
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
|
||||||
MapVariantType::Forest1 => format!("data/maps/map_forest01_0{}e.dat", self.minor),
|
MapArea::Forest1 => format!("data/maps/map_forest01_0{}e.dat", self.minor),
|
||||||
MapVariantType::Forest2 => format!("data/maps/map_forest02_0{}e.dat", self.minor),
|
MapArea::Forest2 => format!("data/maps/map_forest02_0{}e.dat", self.minor),
|
||||||
MapVariantType::Caves1 => format!("data/maps/map_cave01_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Caves2 => format!("data/maps/map_cave02_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Caves3 => format!("data/maps/map_cave03_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Mines1 => format!("data/maps/map_machine01_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Mines2 => format!("data/maps/map_machine02_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}e.dat", self.major, self.minor),
|
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}e.dat", self.major, self.minor),
|
||||||
MapVariantType::Dragon => "data/maps/map_boss01e.dat".into(),
|
MapArea::Dragon => "data/maps/map_boss01e.dat".into(),
|
||||||
MapVariantType::DeRolLe => "data/maps/map_boss02e.dat".into(),
|
MapArea::DeRolLe => "data/maps/map_boss02e.dat".into(),
|
||||||
MapVariantType::VolOpt => "data/maps/map_boss03e.dat".into(),
|
MapArea::VolOpt => "data/maps/map_boss03e.dat".into(),
|
||||||
MapVariantType::DarkFalz => "data/maps/map_boss04e.dat".into(),
|
MapArea::DarkFalz => "data/maps/map_boss04e.dat".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn obj_file(&self) -> String {
|
fn obj_file(&self) -> String {
|
||||||
match self.map {
|
match self.map {
|
||||||
MapVariantType::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
|
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
|
||||||
MapVariantType::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
|
MapArea::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
|
||||||
MapVariantType::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
|
MapArea::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
|
||||||
MapVariantType::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Caves2 => format!("data/maps/map_cave02_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Caves3 => format!("data/maps/map_cave03_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Mines1 => format!("data/maps/map_machine01_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Mines2 => format!("data/maps/map_machine02_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}o.dat", self.major, self.minor),
|
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}o.dat", self.major, self.minor),
|
||||||
MapVariantType::Dragon => "data/maps/map_boss01o.dat".into(),
|
MapArea::Dragon => "data/maps/map_boss01o.dat".into(),
|
||||||
MapVariantType::DeRolLe => "data/maps/map_boss02o.dat".into(),
|
MapArea::DeRolLe => "data/maps/map_boss02o.dat".into(),
|
||||||
MapVariantType::VolOpt => "data/maps/map_boss03o.dat".into(),
|
MapArea::VolOpt => "data/maps/map_boss03o.dat".into(),
|
||||||
MapVariantType::DarkFalz => "data/maps/map_boss04o.dat".into(),
|
MapArea::DarkFalz => "data/maps/map_boss04o.dat".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,21 +607,21 @@ impl Maps {
|
|||||||
pub fn new(episode: Episode) -> Maps {
|
pub fn new(episode: Episode) -> Maps {
|
||||||
let map_variants = match episode {
|
let map_variants = match episode {
|
||||||
Episode::One => {
|
Episode::One => {
|
||||||
[MapVariant::new(MapVariantType::Pioneer2Ep1, MapVariantMode::Online),
|
[MapVariant::new(MapArea::Pioneer2Ep1, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Forest1, MapVariantMode::Online),
|
MapVariant::new(MapArea::Forest1, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Forest2, MapVariantMode::Online),
|
MapVariant::new(MapArea::Forest2, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Caves1, MapVariantMode::Online),
|
MapVariant::new(MapArea::Caves1, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Caves2, MapVariantMode::Online),
|
MapVariant::new(MapArea::Caves2, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Caves3, MapVariantMode::Online),
|
MapVariant::new(MapArea::Caves3, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Mines1, MapVariantMode::Online),
|
MapVariant::new(MapArea::Mines1, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Mines2, MapVariantMode::Online),
|
MapVariant::new(MapArea::Mines2, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Ruins1, MapVariantMode::Online),
|
MapVariant::new(MapArea::Ruins1, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Ruins2, MapVariantMode::Online),
|
MapVariant::new(MapArea::Ruins2, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Ruins3, MapVariantMode::Online),
|
MapVariant::new(MapArea::Ruins3, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::Dragon, MapVariantMode::Online),
|
MapVariant::new(MapArea::Dragon, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::DeRolLe, MapVariantMode::Online),
|
MapVariant::new(MapArea::DeRolLe, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::VolOpt, MapVariantMode::Online),
|
MapVariant::new(MapArea::VolOpt, MapVariantMode::Online),
|
||||||
MapVariant::new(MapVariantType::DarkFalz, MapVariantMode::Online),
|
MapVariant::new(MapArea::DarkFalz, MapVariantMode::Online),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user