jake
5 years ago
4 changed files with 124 additions and 0 deletions
1
data/char_stats.json
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,121 @@ |
|||||
|
use std::collections::HashMap;
|
||||
|
use std::fs::File;
|
||||
|
use serde_json::Value;
|
||||
|
use libpso::character::character::Class;
|
||||
|
|
||||
|
#[derive(Default, Copy, Clone, Debug, PartialEq)]
|
||||
|
pub struct CharacterStats {
|
||||
|
pub hp: u16,
|
||||
|
pub atp: u16,
|
||||
|
pub mst: u16,
|
||||
|
pub evp: u16,
|
||||
|
pub dfp: u16,
|
||||
|
pub ata: u16,
|
||||
|
pub lck: u16,
|
||||
|
}
|
||||
|
|
||||
|
#[derive(Default, Copy, Clone, Debug)]
|
||||
|
struct CharacterLevelEntry {
|
||||
|
hp: u32,
|
||||
|
atp: u32,
|
||||
|
mst: u32,
|
||||
|
evp: u32,
|
||||
|
dfp: u32,
|
||||
|
ata: u32,
|
||||
|
lck: u32,
|
||||
|
exp: u32,
|
||||
|
}
|
||||
|
|
||||
|
pub struct CharacterLevelTable {
|
||||
|
table: HashMap<Class, [CharacterLevelEntry; 200]>,
|
||||
|
}
|
||||
|
|
||||
|
|
||||
|
impl CharacterLevelTable {
|
||||
|
pub fn new() -> CharacterLevelTable {
|
||||
|
let file = File::open("data/char_stats.json").unwrap();
|
||||
|
let json: Value = serde_json::from_reader(file).unwrap();
|
||||
|
let mut table = HashMap::new();
|
||||
|
|
||||
|
for it in json.as_object().unwrap().iter(){
|
||||
|
let cl = match it.0.as_str() {
|
||||
|
"HUmar" => Class::HUmar,
|
||||
|
"HUnewearl" => Class::HUnewearl,
|
||||
|
"HUcast" => Class::HUcast,
|
||||
|
"HUcaseal" => Class::HUcaseal,
|
||||
|
"RAmar" => Class::RAmar,
|
||||
|
"RAmarl" => Class::RAmarl,
|
||||
|
"RAcast" => Class::RAcast,
|
||||
|
"RAcaseal" => Class::RAcaseal,
|
||||
|
"FOmar" => Class::FOmar,
|
||||
|
"FOmarl" => Class::FOmarl,
|
||||
|
"FOnewm" => Class::FOnewm,
|
||||
|
"FOnewearl" => Class::FOnewearl,
|
||||
|
_ => panic!("unexpected class in char stats"),
|
||||
|
};
|
||||
|
|
||||
|
let mut statlist = [CharacterLevelEntry::default(); 200];
|
||||
|
for (i, stat) in it.1.as_array().unwrap().into_iter().enumerate() {
|
||||
|
statlist[i] = CharacterLevelEntry {
|
||||
|
hp: stat["hp"].as_i64().unwrap() as u32,
|
||||
|
atp: stat["atp"].as_i64().unwrap() as u32,
|
||||
|
mst: stat["mst"].as_i64().unwrap() as u32,
|
||||
|
evp: stat["evp"].as_i64().unwrap() as u32,
|
||||
|
dfp: stat["dfp"].as_i64().unwrap() as u32,
|
||||
|
ata: stat["ata"].as_i64().unwrap() as u32,
|
||||
|
lck: stat["lck"].as_i64().unwrap() as u32,
|
||||
|
exp: stat["xp"].as_i64().unwrap() as u32,
|
||||
|
}
|
||||
|
}
|
||||
|
|
||||
|
table.insert(cl, statlist);
|
||||
|
}
|
||||
|
|
||||
|
CharacterLevelTable {
|
||||
|
table: table,
|
||||
|
}
|
||||
|
}
|
||||
|
|
||||
|
pub fn get_stats_from_exp(&self, ch_class: Class, exp: u32) -> (u32, CharacterStats) {
|
||||
|
if let Some(statlist) = self.table.get(&ch_class) {
|
||||
|
statlist
|
||||
|
.iter()
|
||||
|
.filter(|stat| {
|
||||
|
stat.exp <= exp
|
||||
|
})
|
||||
|
.inspect(|k| {
|
||||
|
println!("{:?}", k)
|
||||
|
})
|
||||
|
.fold((0, CharacterStats::default()), |acc, &k| {
|
||||
|
(acc.0 + 1, CharacterStats {
|
||||
|
hp: acc.1.hp + k.hp as u16,
|
||||
|
atp: acc.1.atp + k.atp as u16,
|
||||
|
mst: acc.1.mst + k.mst as u16,
|
||||
|
evp: acc.1.evp + k.evp as u16,
|
||||
|
dfp: acc.1.dfp + k.dfp as u16,
|
||||
|
ata: acc.1.ata + k.ata as u16,
|
||||
|
lck: acc.1.lck + k.lck as u16,
|
||||
|
})
|
||||
|
})
|
||||
|
}
|
||||
|
else {
|
||||
|
(0, CharacterStats::default())
|
||||
|
}
|
||||
|
}
|
||||
|
}
|
||||
|
|
||||
|
#[cfg(test)]
|
||||
|
mod test {
|
||||
|
use super::*;
|
||||
|
#[test]
|
||||
|
fn test_stat_levels() {
|
||||
|
let table = CharacterLevelTable::new();
|
||||
|
println!("A {:?}", table.get_stats_from_exp(Class::FOmarl, 0));
|
||||
|
println!("B {:?}", table.get_stats_from_exp(Class::FOmarl, 1));
|
||||
|
println!("C {:?}", table.get_stats_from_exp(Class::FOmarl, 50));
|
||||
|
println!("D {:?}", table.get_stats_from_exp(Class::FOmarl, 51));
|
||||
|
println!("E {:?}", table.get_stats_from_exp(Class::FOmarl, 1000));
|
||||
|
assert!(table.get_stats_from_exp(Class::FOmarl, 0) == (1, CharacterStats { hp: 20, atp: 13, mst: 53, evp: 35, dfp: 10, ata: 15, lck: 10 }));
|
||||
|
assert!(table.get_stats_from_exp(Class::FOmarl, 1 << 17) == (36, CharacterStats { hp: 125, atp: 114, mst: 219, evp: 182, dfp: 42, ata: 213, lck: 10 }));
|
||||
|
}
|
||||
|
}
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue