mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-09 07:27:46 +00:00
Update Icarus, switch to the new Physis Resource system
While there isn't a functional difference in Kawari yet, this is paving the way to allow loading unpacked game files.
This commit is contained in:
parent
9b03e2d7c2
commit
7b6605b018
5 changed files with 33 additions and 35 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -213,9 +213,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.28"
|
||||
version = "1.2.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c"
|
||||
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
|
@ -542,9 +542,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.14"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
|
||||
checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
|
@ -567,7 +567,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "icarus"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/redstrate/Icarus?branch=ver%2F2025.06.10.0000.0000#c6eb3b05ebe54b86c25d09dbc0bfc7b30f5cdadf"
|
||||
source = "git+https://github.com/redstrate/Icarus?branch=ver%2F2025.06.28.0000.0000#bcd980957786ac63f89c63e190b06358685ce762"
|
||||
dependencies = [
|
||||
"physis",
|
||||
]
|
||||
|
@ -1060,7 +1060,7 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
|||
[[package]]
|
||||
name = "physis"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/redstrate/physis#c602e6b28f06c178707bef5a9ea78fdc70c8f4a3"
|
||||
source = "git+https://github.com/redstrate/physis#c2eb47cca0300b9ecaae69473f03539a9e1e4662"
|
||||
dependencies = [
|
||||
"binrw",
|
||||
"bitflags",
|
||||
|
@ -1456,9 +1456,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.46.0"
|
||||
version = "1.46.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4"
|
||||
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
|
|
@ -72,7 +72,7 @@ physis = { git = "https://github.com/redstrate/physis", default-features = false
|
|||
bitflags = { version = "2.9", default-features = false }
|
||||
|
||||
# excel sheet data
|
||||
icarus = { git = "https://github.com/redstrate/Icarus", branch = "ver/2025.06.10.0000.0000", features = ["Warp", "Tribe", "ClassJob", "World", "TerritoryType", "Race", "Aetheryte", "EquipSlotCategory", "Action", "WeatherRate", "PlaceName", "GilShopItem"], default-features = false }
|
||||
icarus = { git = "https://github.com/redstrate/Icarus", branch = "ver/2025.06.28.0000.0000", features = ["Warp", "Tribe", "ClassJob", "World", "TerritoryType", "Race", "Aetheryte", "EquipSlotCategory", "Action", "WeatherRate", "PlaceName", "GilShopItem"], default-features = false }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
# Used for the web servers
|
||||
|
|
|
@ -11,6 +11,7 @@ use icarus::{Tribe::TribeSheet, Warp::WarpSheet};
|
|||
use physis::common::{Language, Platform};
|
||||
use physis::exd::{EXD, ExcelRowKind};
|
||||
use physis::exh::EXH;
|
||||
use physis::resource::{SqPackResource, read_excel_sheet, read_excel_sheet_header};
|
||||
|
||||
use crate::{common::Attributes, config::get_config};
|
||||
|
||||
|
@ -18,7 +19,7 @@ use super::timestamp_secs;
|
|||
|
||||
/// Convenient methods built on top of Physis to access data relevant to the server
|
||||
pub struct GameData {
|
||||
pub game_data: physis::gamedata::GameData,
|
||||
pub resource: SqPackResource,
|
||||
pub item_exh: EXH,
|
||||
pub item_pages: Vec<EXD>,
|
||||
pub classjob_exp_indexes: Vec<i8>,
|
||||
|
@ -56,17 +57,14 @@ impl GameData {
|
|||
pub fn new() -> Self {
|
||||
let config = get_config();
|
||||
|
||||
let mut game_data =
|
||||
physis::gamedata::GameData::from_existing(Platform::Win32, &config.game_location);
|
||||
let mut game_data = SqPackResource::from_existing(Platform::Win32, &config.game_location);
|
||||
|
||||
let mut item_pages = Vec::new();
|
||||
|
||||
let item_exh = game_data.read_excel_sheet_header("Item").unwrap();
|
||||
let item_exh = read_excel_sheet_header(&mut game_data, "Item").unwrap();
|
||||
for (i, _) in item_exh.pages.iter().enumerate() {
|
||||
item_pages.push(
|
||||
game_data
|
||||
.read_excel_sheet("Item", &item_exh, Language::English, i)
|
||||
.unwrap(),
|
||||
read_excel_sheet(&mut game_data, "Item", &item_exh, Language::English, i).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -81,7 +79,7 @@ impl GameData {
|
|||
}
|
||||
|
||||
Self {
|
||||
game_data,
|
||||
resource: game_data,
|
||||
item_exh,
|
||||
item_pages,
|
||||
classjob_exp_indexes,
|
||||
|
@ -90,7 +88,7 @@ impl GameData {
|
|||
|
||||
/// Gets the world name from an id into the World Excel sheet.
|
||||
pub fn get_world_name(&mut self, world_id: u16) -> Option<String> {
|
||||
let sheet = WorldSheet::read_from(&mut self.game_data, Language::None)?;
|
||||
let sheet = WorldSheet::read_from(&mut self.resource, Language::None)?;
|
||||
let row = sheet.get_row(world_id as u32)?;
|
||||
|
||||
row.Name().into_string().cloned()
|
||||
|
@ -98,7 +96,7 @@ impl GameData {
|
|||
|
||||
/// Gets the starting city-state from a given class/job id.
|
||||
pub fn get_citystate(&mut self, classjob_id: u16) -> Option<u8> {
|
||||
let sheet = ClassJobSheet::read_from(&mut self.game_data, Language::English)?;
|
||||
let sheet = ClassJobSheet::read_from(&mut self.resource, Language::English)?;
|
||||
let row = sheet.get_row(classjob_id as u32)?;
|
||||
|
||||
row.StartingTown().into_u8().copied()
|
||||
|
@ -108,7 +106,7 @@ impl GameData {
|
|||
// 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 sheet = TribeSheet::read_from(&mut self.game_data, Language::English)?;
|
||||
let sheet = TribeSheet::read_from(&mut self.resource, Language::English)?;
|
||||
let row = sheet.get_row(tribe_id as u32)?;
|
||||
|
||||
Some(Attributes {
|
||||
|
@ -207,7 +205,7 @@ impl GameData {
|
|||
|
||||
/// Returns the pop range object id that's associated with the warp id
|
||||
pub fn get_warp(&mut self, warp_id: u32) -> Option<(u32, u16)> {
|
||||
let sheet = WarpSheet::read_from(&mut self.game_data, Language::English)?;
|
||||
let sheet = WarpSheet::read_from(&mut self.resource, Language::English)?;
|
||||
let row = sheet.get_row(warp_id)?;
|
||||
|
||||
let pop_range_id = row.PopRange().into_u32()?;
|
||||
|
@ -217,7 +215,7 @@ impl GameData {
|
|||
}
|
||||
|
||||
pub fn get_aetheryte(&mut self, aetheryte_id: u32) -> Option<(u32, u16)> {
|
||||
let sheet = AetheryteSheet::read_from(&mut self.game_data, Language::English)?;
|
||||
let sheet = AetheryteSheet::read_from(&mut self.resource, Language::English)?;
|
||||
let row = sheet.get_row(aetheryte_id)?;
|
||||
|
||||
// TODO: just look in the level sheet?
|
||||
|
@ -229,7 +227,7 @@ impl GameData {
|
|||
|
||||
// Retrieves a zone's internal name, place name or parent region name.
|
||||
pub fn get_territory_name(&mut self, zone_id: u32, which: TerritoryNameKind) -> Option<String> {
|
||||
let sheet = TerritoryTypeSheet::read_from(&mut self.game_data, Language::None)?;
|
||||
let sheet = TerritoryTypeSheet::read_from(&mut self.resource, Language::None)?;
|
||||
let row = sheet.get_row(zone_id)?;
|
||||
|
||||
let offset = match which {
|
||||
|
@ -240,7 +238,7 @@ impl GameData {
|
|||
TerritoryNameKind::Place => row.PlaceName().into_u16()?,
|
||||
};
|
||||
|
||||
let sheet = PlaceNameSheet::read_from(&mut self.game_data, Language::English)?;
|
||||
let sheet = PlaceNameSheet::read_from(&mut self.resource, Language::English)?;
|
||||
let row = sheet.get_row(*offset as u32)?;
|
||||
|
||||
let value = row.Name().into_string()?;
|
||||
|
@ -250,7 +248,7 @@ impl GameData {
|
|||
|
||||
/// Turn an equip slot category id into a slot for the equipped inventory
|
||||
pub fn get_equipslot_category(&mut self, equipslot_id: u8) -> Option<u16> {
|
||||
let sheet = EquipSlotCategorySheet::read_from(&mut self.game_data, Language::None)?;
|
||||
let sheet = EquipSlotCategorySheet::read_from(&mut self.resource, Language::None)?;
|
||||
let row = sheet.get_row(equipslot_id as u32)?;
|
||||
|
||||
let main_hand = row.MainHand().into_i8()?;
|
||||
|
@ -322,7 +320,7 @@ impl GameData {
|
|||
}
|
||||
|
||||
pub fn get_casttime(&mut self, action_id: u32) -> Option<u16> {
|
||||
let sheet = ActionSheet::read_from(&mut self.game_data, Language::English)?;
|
||||
let sheet = ActionSheet::read_from(&mut self.resource, Language::English)?;
|
||||
let row = sheet.get_row(action_id)?;
|
||||
|
||||
row.Cast100ms().into_u16().copied()
|
||||
|
@ -331,7 +329,7 @@ impl GameData {
|
|||
/// Calculates the current weather at the current time
|
||||
// TODO: instead allow targetting a specific time to calculate forcecasts
|
||||
pub fn get_weather_rate(&mut self, weather_rate_id: u32) -> Option<i32> {
|
||||
let sheet = WeatherRateSheet::read_from(&mut self.game_data, Language::None)?;
|
||||
let sheet = WeatherRateSheet::read_from(&mut self.resource, Language::None)?;
|
||||
let row = sheet.get_row(weather_rate_id)?;
|
||||
|
||||
let target = Self::calculate_target();
|
||||
|
@ -379,7 +377,7 @@ impl GameData {
|
|||
|
||||
/// Gets the current weather for the given zone id
|
||||
pub fn get_weather(&mut self, zone_id: u32) -> Option<i32> {
|
||||
let sheet = TerritoryTypeSheet::read_from(&mut self.game_data, Language::None)?;
|
||||
let sheet = TerritoryTypeSheet::read_from(&mut self.resource, Language::None)?;
|
||||
let row = sheet.get_row(zone_id)?;
|
||||
|
||||
let weather_rate_id = row.WeatherRate().into_u8()?;
|
||||
|
@ -394,7 +392,7 @@ impl GameData {
|
|||
|
||||
/// Gets the item and its cost from the specified shop.
|
||||
pub fn get_gilshop_item(&mut self, gilshop_id: u32, index: u16) -> Option<ItemInfo> {
|
||||
let sheet = GilShopItemSheet::read_from(&mut self.game_data, Language::None)?;
|
||||
let sheet = GilShopItemSheet::read_from(&mut self.resource, Language::None)?;
|
||||
let row = sheet.get_subrow(gilshop_id, index)?;
|
||||
let item_id = row.Item().into_i32()?;
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ impl<'a> Iterator for InventoryIterator<'a> {
|
|||
impl Inventory {
|
||||
/// Equip the starting items for a given classjob
|
||||
pub fn equip_classjob_items(&mut self, classjob_id: u16, game_data: &mut GameData) {
|
||||
let sheet = ClassJobSheet::read_from(&mut game_data.game_data, Language::English).unwrap();
|
||||
let sheet = ClassJobSheet::read_from(&mut game_data.resource, Language::English).unwrap();
|
||||
let row = sheet.get_row(classjob_id as u32).unwrap();
|
||||
|
||||
self.equipped.main_hand =
|
||||
|
@ -149,7 +149,7 @@ impl Inventory {
|
|||
|
||||
/// Equip the starting items for a given race
|
||||
pub fn equip_racial_items(&mut self, race_id: u8, gender: u8, game_data: &mut GameData) {
|
||||
let sheet = RaceSheet::read_from(&mut game_data.game_data, Language::English).unwrap();
|
||||
let sheet = RaceSheet::read_from(&mut game_data.resource, Language::English).unwrap();
|
||||
let row = sheet.get_row(race_id as u32).unwrap();
|
||||
|
||||
if gender == 0 {
|
||||
|
|
|
@ -5,6 +5,7 @@ use physis::{
|
|||
ExitRangeInstanceObject, InstanceObject, LayerEntryData, LayerGroup, PopRangeInstanceObject,
|
||||
},
|
||||
lvb::Lvb,
|
||||
resource::Resource,
|
||||
};
|
||||
|
||||
use crate::common::{GameData, TerritoryNameKind};
|
||||
|
@ -27,8 +28,7 @@ impl Zone {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let sheet =
|
||||
TerritoryTypeSheet::read_from(&mut game_data.game_data, Language::None).unwrap();
|
||||
let sheet = TerritoryTypeSheet::read_from(&mut game_data.resource, Language::None).unwrap();
|
||||
let Some(row) = sheet.get_row(id as u32) else {
|
||||
tracing::warn!("Invalid zone id {id}, allowing anyway...");
|
||||
return zone;
|
||||
|
@ -40,11 +40,11 @@ impl Zone {
|
|||
let bg_path = row.Bg().into_string().unwrap();
|
||||
|
||||
let path = format!("bg/{}.lvb", &bg_path);
|
||||
let lgb_file = game_data.game_data.extract(&path).unwrap();
|
||||
let lgb_file = game_data.resource.read(&path).unwrap();
|
||||
let lgb = Lvb::from_existing(&lgb_file).unwrap();
|
||||
|
||||
let mut load_lgb = |path: &str| -> Option<LayerGroup> {
|
||||
let lgb_file = game_data.game_data.extract(path)?;
|
||||
let lgb_file = game_data.resource.read(path)?;
|
||||
tracing::info!("Loading {path}");
|
||||
let lgb = LayerGroup::from_existing(&lgb_file);
|
||||
if lgb.is_none() {
|
||||
|
|
Loading…
Add table
Reference in a new issue