Browse Source

cool unique server features

pbs
jake 4 years ago
parent
commit
4fb78048e5
  1. 2
      src/entity/item/unit.rs
  2. 4
      src/ship/drops/generic_shield.rs
  3. 129
      src/ship/drops/generic_unit.rs
  4. 1
      src/ship/drops/mod.rs
  5. 18
      src/ship/item_stats.rs

2
src/entity/item/unit.rs

@ -1,7 +1,7 @@
use serde::{Serialize, Deserialize};
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display)]
pub enum UnitType {
KnightPower,
GeneralPower,

4
src/ship/drops/generic_shield.rs

@ -105,10 +105,6 @@ mod test {
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
let gst = GenericShieldTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
//println!("{:?}", gst.get_drop(&MapVariantType::Forest1, &mut rng));
//println!("{:?}", gst.get_drop(&MapVariantType::Caves3, &mut rng));
//println!("{:?}", gst.get_drop(&MapVariantType::Mines2, &mut rng));
//println!("{:?}", gst.get_drop(&MapVariantType::DarkFalz, &mut rng));
assert!(gst.get_drop(&MapVariantType::Forest1, &mut rng) == Some(ItemDetail::Shield(ShieldDetail {
equipped: false,

129
src/ship/drops/generic_unit.rs

@ -0,0 +1,129 @@
use std::collections::BTreeMap;
use serde::{Serialize, Deserialize};
use rand::{Rng, SeedableRng};
use rand::distributions::{WeightedIndex, Distribution};
use rand::seq::IteratorRandom;
use crate::entity::item::{ItemDetail, Unit as UnitDetail};
use crate::entity::item::unit::{UnitType, Unit, UnitModifier};
use crate::ship::room::{Difficulty, Episode};
use crate::ship::map::MapVariantType;
use crate::entity::character::SectionID;
use crate::ship::drops::load_data_file;
use crate::ship::item_stats::{unit_stats, UnitStats};
#[derive(Debug, Serialize, Deserialize)]
struct UnitLevels {
area1: u32,
area2: u32,
area3: u32,
area4: u32,
area5: u32,
area6: u32,
area7: u32,
area8: u32,
area9: u32,
area10: u32,
}
impl UnitLevels {
fn level_by_area(&self, map_area: &MapVariantType) -> u32 {
match map_area.area_value().unwrap() {
0 => self.area1,
1 => self.area2,
2 => self.area3,
3 => self.area1,
4 => self.area1,
5 => self.area6,
6 => self.area7,
7 => self.area8,
8 => self.area9,
9 => self.area10,
_ => panic!()
}
}
}
pub struct GenericUnitTable {
unit_levels: UnitLevels,
unit_stats: BTreeMap<UnitType, UnitStats>,
}
impl GenericUnitTable {
pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> GenericUnitTable {
GenericUnitTable {
unit_levels: load_data_file(episode, difficulty, section_id, "unit_rate.toml"),
unit_stats: unit_stats(),
}
}
fn unit_type_and_modifier<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<(UnitType, Option<UnitModifier>)> {
let level = self.unit_levels.level_by_area(area_map) as i32;
if level == 0 {
return None;
}
let units = self.unit_stats
.iter()
.filter(|(_, stats)| {
stats.stars < 9
})
.filter_map(|(utype, stats)| {
match level - stats.stars as i32 {
-1 if stats.modifier != 0 => Some(vec![(*utype, Some(UnitModifier::Minus)), (*utype, Some(UnitModifier::MinusMinus))]),
0 => Some(vec![(*utype, None)]),
1 if stats.modifier != 0 => Some(vec![(*utype, Some(UnitModifier::Plus)), (*utype, Some(UnitModifier::PlusPlus))]),
_ => None,
}
})
.flatten();
Some(units.choose(rng).unwrap())
}
pub fn get_drop<R: Rng>(&self, area_map: &MapVariantType, rng: &mut R) -> Option<ItemDetail> {
let unit_type_modifier = self.unit_type_and_modifier(area_map, rng);
unit_type_modifier.map(|(unit_type, unit_modifier)| {
ItemDetail::Unit(UnitDetail {
equipped: false,
unit: Unit {
unit: unit_type,
modifier: unit_modifier,
}
})
})
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_unit_drops() {
let mut rng = rand_chacha::ChaCha20Rng::from_seed([23;32]);
let gut = GenericUnitTable::new(Episode::One, Difficulty::Normal, SectionID::Skyly);
assert!(gut.get_drop(&MapVariantType::Forest1, &mut rng) == None);
let gut = GenericUnitTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly);
let unit_tests = vec![(MapVariantType::Forest1, UnitType::ResistFreeze, Some(UnitModifier::PlusPlus)),
(MapVariantType::Caves3, UnitType::GeneralTP, None),
(MapVariantType::Mines2, UnitType::ResistEvil, Some(UnitModifier::PlusPlus)),
(MapVariantType::DarkFalz, UnitType::DragonHP, Some(UnitModifier::Minus))];
for (area, unit, umod) in unit_tests {
assert!(gut.get_drop(&area, &mut rng) == Some(ItemDetail::Unit(UnitDetail {
equipped: false,
unit: Unit {
unit: unit,
modifier: umod,
}
})));
}
}
}

1
src/ship/drops/mod.rs

@ -3,6 +3,7 @@ mod rare_drop_table;
mod generic_weapon;
mod generic_armor;
mod generic_shield;
mod generic_unit;
use std::collections::HashMap;

18
src/ship/item_stats.rs

@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, BTreeMap};
use serde::{Serialize, Deserialize};
use std::fs::File;
use std::io::Read;
@ -54,12 +54,12 @@ pub struct ShieldStats {
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
struct UnitStats {
stars: u32,
stat: u32,
amount: u32,
team_points: u32,
modifier: u32,
pub struct UnitStats {
pub stars: u32,
pub stat: u32,
pub amount: u32,
pub team_points: u32,
pub modifier: u32,
}
@ -79,8 +79,8 @@ pub fn shield_stats() -> HashMap<ShieldType, ShieldStats> {
}).collect()
}
fn unit_stats() -> HashMap<UnitType, UnitStats> {
let unit_stats: HashMap<String, UnitStats> = load_data_file("data/item_stats/unit_stats.toml");
pub fn unit_stats() -> BTreeMap<UnitType, UnitStats> {
let unit_stats: BTreeMap<String, UnitStats> = load_data_file("data/item_stats/unit_stats.toml");
unit_stats.iter()
.map(|(name, stats)| {
(name.parse().unwrap(), *stats)

Loading…
Cancel
Save