1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-07-01 04:07:45 +00:00
kawari/src/common/gamedata.rs

118 lines
3.6 KiB
Rust
Raw Normal View History

use physis::common::{Language, Platform};
use crate::{common::Attributes, config::get_config};
/// Convenient methods built on top of Physis to access data relevant to the server
pub struct GameData {
pub game_data: physis::gamedata::GameData,
}
impl Default for GameData {
fn default() -> Self {
Self::new()
}
}
impl GameData {
pub fn new() -> Self {
let config = get_config();
Self {
game_data: physis::gamedata::GameData::from_existing(
Platform::Win32,
&config.game_location,
)
.unwrap(),
}
}
/// Gets the world name from an id into the World Excel sheet.
pub fn get_world_name(&mut self, world_id: u16) -> String {
let exh = self.game_data.read_excel_sheet_header("World").unwrap();
let exd = self
.game_data
.read_excel_sheet("World", &exh, Language::None, 0)
.unwrap();
let world_row = &exd.read_row(&exh, world_id as u32).unwrap()[0];
let physis::exd::ColumnData::String(name) = &world_row.data[1] else {
panic!("Unexpected type!");
};
name.clone()
}
/// Gets the starting city-state from a given class/job id.
pub fn get_citystate(&mut self, classjob_id: u16) -> u8 {
let exh = self.game_data.read_excel_sheet_header("ClassJob").unwrap();
let exd = self
.game_data
.read_excel_sheet("ClassJob", &exh, Language::English, 0)
.unwrap();
let world_row = &exd.read_row(&exh, classjob_id as u32).unwrap()[0];
let physis::exd::ColumnData::UInt8(town_id) = &world_row.data[33] else {
panic!("Unexpected type!");
};
*town_id
}
pub fn get_racial_base_attributes(&mut self, tribe_id: u8) -> Attributes {
// The Tribe Excel sheet only has deltas (e.g. 2 or -2) which are applied to a base 20 number... from somewhere
let base_stat = 20;
let exh = self.game_data.read_excel_sheet_header("Tribe").unwrap();
let exd = self
.game_data
.read_excel_sheet("Tribe", &exh, Language::English, 0)
.unwrap();
let tribe_row = &exd.read_row(&exh, tribe_id as u32).unwrap()[0];
let get_column = |column_index: usize| {
let physis::exd::ColumnData::Int8(delta) = &tribe_row.data[column_index] else {
panic!("Unexpected type!");
};
*delta
};
Attributes {
strength: (base_stat + get_column(4)) as u32,
dexterity: (base_stat + get_column(6)) as u32,
vitality: (base_stat + get_column(5)) as u32,
intelligence: (base_stat + get_column(7)) as u32,
mind: (base_stat + get_column(8)) as u32,
}
}
/// Gets the primary model ID for a given item ID
pub fn get_primary_model_id(&mut self, item_id: u32) -> u16 {
let exh = self.game_data.read_excel_sheet_header("Item").unwrap();
for (i, _) in exh.pages.iter().enumerate() {
let exd = self
.game_data
.read_excel_sheet("Item", &exh, Language::English, i)
.unwrap();
if let Some(row) = exd.read_row(&exh, item_id) {
let item_row = &row[0];
let physis::exd::ColumnData::UInt64(id) = &item_row.data[47] else {
panic!("Unexpected type!");
};
return *id as u16;
}
}
// TODO: just turn this into an Option<>
tracing::warn!("Failed to get model id for {item_id}, this is most likely a bug!");
0
}
}