mirror of
https://github.com/redstrate/Kawari.git
synced 2025-05-02 11:07:45 +00:00
Move model id grabbing to Inventory, fixup ClientSelectData
I wanted to make the lobby screen reflect your currently equipped items, but that doesn't yet for some reason. These are still good refactorings though!
This commit is contained in:
parent
614e470669
commit
ed8ccb86ee
5 changed files with 99 additions and 113 deletions
|
@ -832,12 +832,16 @@ async fn client_loop(
|
|||
}
|
||||
|
||||
let mut inventory = Inventory::default();
|
||||
{
|
||||
let mut game_data = game_data.lock().unwrap();
|
||||
|
||||
// fill inventory
|
||||
inventory.equip_racial_items(
|
||||
chara_make.customize.race,
|
||||
chara_make.customize.gender,
|
||||
&mut game_data,
|
||||
);
|
||||
}
|
||||
|
||||
let (content_id, actor_id) = database.create_player_data(
|
||||
*service_account_id,
|
||||
|
@ -932,11 +936,17 @@ async fn client_loop(
|
|||
world_name = game_data.get_world_name(config.world.world_id);
|
||||
}
|
||||
|
||||
let characters = database.get_character_list(
|
||||
let characters;
|
||||
{
|
||||
let mut game_data = game_data.lock().unwrap();
|
||||
|
||||
characters = database.get_character_list(
|
||||
*service_account_id,
|
||||
config.world.world_id,
|
||||
&world_name,
|
||||
&mut game_data,
|
||||
);
|
||||
}
|
||||
|
||||
// send response
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@ use serde_json::json;
|
|||
use crate::common::CustomizeData;
|
||||
|
||||
// TODO: this isn't really an enum in the game, nor is it a flag either. it's weird!
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(i32)]
|
||||
pub enum RemakeMode {
|
||||
/// No remake options are available.
|
||||
|
@ -15,10 +15,11 @@ pub enum RemakeMode {
|
|||
}
|
||||
|
||||
/// See https://github.com/aers/FFXIVClientStructs/blob/main/FFXIVClientStructs/FFXIV/Application/Network/WorkDefinitions/ClientSelectData.cs
|
||||
#[derive(Debug)]
|
||||
pub struct ClientSelectData {
|
||||
pub game_name_unk: String,
|
||||
pub character_name: String,
|
||||
pub current_class: i32,
|
||||
pub class_levels: [i32; 30],
|
||||
pub class_levels: [i32; 32],
|
||||
pub race: i32,
|
||||
pub subrace: i32,
|
||||
pub gender: i32,
|
||||
|
@ -32,9 +33,11 @@ pub struct ClientSelectData {
|
|||
/// The most notable is if your character can be remade, it says "Your character is currently bound by duty..."
|
||||
pub content_finder_condition: i32,
|
||||
pub customize: CustomizeData,
|
||||
pub model_main_weapon: i32,
|
||||
pub model_main_weapon: u64,
|
||||
pub model_sub_weapon: i32,
|
||||
pub unk14: [i32; 10], // probably model ids
|
||||
pub model_ids: [u32; 10],
|
||||
pub equip_stain: [u32; 10],
|
||||
pub glasses: [u32; 2],
|
||||
pub unk15: i32,
|
||||
pub unk16: i32,
|
||||
pub remake_mode: RemakeMode, // TODO: upstream a comment about this to FFXIVClientStructs
|
||||
|
@ -44,13 +47,12 @@ pub struct ClientSelectData {
|
|||
pub unk20: i32,
|
||||
pub world_name: String,
|
||||
pub unk22: i32,
|
||||
pub unk23: i32,
|
||||
}
|
||||
|
||||
impl ClientSelectData {
|
||||
pub fn to_json(&self) -> String {
|
||||
let content = json!([
|
||||
self.game_name_unk,
|
||||
self.character_name,
|
||||
self.current_class.to_string(),
|
||||
self.class_levels.map(|x| x.to_string()),
|
||||
self.race.to_string(),
|
||||
|
@ -66,7 +68,9 @@ impl ClientSelectData {
|
|||
self.customize.to_json(),
|
||||
self.model_main_weapon.to_string(),
|
||||
self.model_sub_weapon.to_string(),
|
||||
self.unk14.map(|x| x.to_string()),
|
||||
self.model_ids.map(|x| x.to_string()),
|
||||
self.equip_stain.map(|x| x.to_string()),
|
||||
self.glasses.map(|x| x.to_string()),
|
||||
self.unk15.to_string(),
|
||||
self.unk16.to_string(),
|
||||
(self.remake_mode as i32).to_string(),
|
||||
|
@ -75,7 +79,6 @@ impl ClientSelectData {
|
|||
self.unk20.to_string(),
|
||||
self.world_name,
|
||||
self.unk22.to_string(),
|
||||
self.unk23.to_string(),
|
||||
]);
|
||||
|
||||
let obj = json!({
|
||||
|
|
|
@ -613,50 +613,17 @@ impl ZoneConnection {
|
|||
let ipc;
|
||||
{
|
||||
let mut game_data = self.gamedata.lock().unwrap();
|
||||
let equipped = &self.player_data.inventory.equipped;
|
||||
let inventory = &self.player_data.inventory;
|
||||
|
||||
ipc = ServerZoneIpcSegment {
|
||||
op_code: ServerZoneIpcType::Equip,
|
||||
timestamp: timestamp_secs(),
|
||||
data: ServerZoneIpcData::Equip(Equip {
|
||||
main_weapon_id: game_data
|
||||
.get_primary_model_id(equipped.main_hand.id)
|
||||
.unwrap_or(0),
|
||||
main_weapon_id: inventory.get_main_weapon_id(&mut game_data),
|
||||
sub_weapon_id: 0,
|
||||
crest_enable: 0,
|
||||
pattern_invalid: 0,
|
||||
model_ids: [
|
||||
game_data
|
||||
.get_primary_model_id(equipped.head.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.body.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.hands.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.legs.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.feet.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.ears.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.neck.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.wrists.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.left_ring.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.right_ring.id)
|
||||
.unwrap_or(0) as u32,
|
||||
],
|
||||
model_ids: inventory.get_model_ids(&mut game_data),
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -785,7 +752,8 @@ impl ZoneConnection {
|
|||
|
||||
let chara_details = self.database.find_chara_make(self.player_data.content_id);
|
||||
|
||||
let equipped = &self.player_data.inventory.equipped;
|
||||
let inventory = &self.player_data.inventory;
|
||||
|
||||
CommonSpawn {
|
||||
class_job: self.player_data.classjob_id,
|
||||
name: chara_details.name,
|
||||
|
@ -797,41 +765,8 @@ impl ZoneConnection {
|
|||
object_kind: ObjectKind::Player(PlayerSubKind::Player),
|
||||
look: chara_details.chara_make.customize,
|
||||
display_flags: DisplayFlag::UNK,
|
||||
main_weapon_model: game_data
|
||||
.get_primary_model_id(equipped.main_hand.id)
|
||||
.unwrap_or(0),
|
||||
models: [
|
||||
game_data
|
||||
.get_primary_model_id(equipped.head.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.body.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.hands.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.legs.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.feet.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.ears.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.neck.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.wrists.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.left_ring.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(equipped.right_ring.id)
|
||||
.unwrap_or(0) as u32,
|
||||
],
|
||||
main_weapon_model: inventory.get_main_weapon_id(&mut game_data),
|
||||
models: inventory.get_model_ids(&mut game_data),
|
||||
pos: exit_position.unwrap_or_default(),
|
||||
rotation: exit_rotation.unwrap_or(0.0),
|
||||
..Default::default()
|
||||
|
|
|
@ -5,7 +5,7 @@ use serde::Deserialize;
|
|||
|
||||
use crate::{
|
||||
common::{
|
||||
CustomizeData, Position,
|
||||
CustomizeData, GameData, Position,
|
||||
workdefinitions::{CharaMake, ClientSelectData, RemakeMode},
|
||||
},
|
||||
lobby::ipc::{CharacterDetails, CharacterFlag},
|
||||
|
@ -225,6 +225,7 @@ impl WorldDatabase {
|
|||
service_account_id: u32,
|
||||
world_id: u16,
|
||||
world_name: &str,
|
||||
game_data: &mut GameData,
|
||||
) -> Vec<CharacterDetails> {
|
||||
let connection = self.connection.lock().unwrap();
|
||||
|
||||
|
@ -250,22 +251,24 @@ impl WorldDatabase {
|
|||
for (index, (content_id, actor_id)) in content_actor_ids.iter().enumerate() {
|
||||
let mut stmt = connection
|
||||
.prepare(
|
||||
"SELECT name, chara_make, zone_id FROM character_data WHERE content_id = ?1",
|
||||
"SELECT name, chara_make, zone_id, inventory FROM character_data WHERE content_id = ?1",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let result: Result<(String, String, u16), rusqlite::Error> = stmt
|
||||
let result: Result<(String, String, u16, String), rusqlite::Error> = stmt
|
||||
.query_row((content_id,), |row| {
|
||||
Ok((row.get(0)?, row.get(1)?, row.get(2)?))
|
||||
Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
|
||||
});
|
||||
|
||||
if let Ok((name, chara_make, zone_id)) = result {
|
||||
if let Ok((name, chara_make, zone_id, inventory_json)) = result {
|
||||
let chara_make = CharaMake::from_json(&chara_make);
|
||||
|
||||
let inventory: Inventory = serde_json::from_str(&inventory_json).unwrap();
|
||||
|
||||
let select_data = ClientSelectData {
|
||||
game_name_unk: "Final Fantasy".to_string(),
|
||||
character_name: name.clone(),
|
||||
current_class: 2,
|
||||
class_levels: [5; 30],
|
||||
class_levels: [5; 32],
|
||||
race: chara_make.customize.race as i32,
|
||||
subrace: chara_make.customize.subrace as i32,
|
||||
gender: chara_make.customize.gender as i32,
|
||||
|
@ -277,9 +280,11 @@ impl WorldDatabase {
|
|||
zone_id: zone_id as i32,
|
||||
content_finder_condition: 0,
|
||||
customize: chara_make.customize,
|
||||
model_main_weapon: 0,
|
||||
model_main_weapon: inventory.get_main_weapon_id(game_data),
|
||||
model_sub_weapon: 0,
|
||||
unk14: [0; 10],
|
||||
model_ids: inventory.get_model_ids(game_data),
|
||||
equip_stain: [0; 10],
|
||||
glasses: [0; 2],
|
||||
unk15: 0,
|
||||
unk16: 0,
|
||||
remake_mode: RemakeMode::None,
|
||||
|
@ -288,7 +293,6 @@ impl WorldDatabase {
|
|||
unk20: 0,
|
||||
world_name: String::new(),
|
||||
unk22: 0,
|
||||
unk23: 0,
|
||||
};
|
||||
|
||||
characters.push(CharacterDetails {
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use physis::{
|
||||
common::{Language, Platform},
|
||||
gamedata::GameData,
|
||||
};
|
||||
use physis::common::Language;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::config::get_config;
|
||||
use crate::common::GameData;
|
||||
|
||||
use super::ipc::{ContainerType, InventoryModify};
|
||||
|
||||
|
@ -179,14 +176,10 @@ impl Default for Inventory {
|
|||
|
||||
impl Inventory {
|
||||
/// Equip the starting items for a given race
|
||||
pub fn equip_racial_items(&mut self, race_id: u8, gender: u8) {
|
||||
let config = get_config();
|
||||
|
||||
let mut game_data =
|
||||
GameData::from_existing(Platform::Win32, &config.game_location).unwrap();
|
||||
|
||||
let exh = game_data.read_excel_sheet_header("Race").unwrap();
|
||||
pub fn equip_racial_items(&mut self, race_id: u8, gender: u8, game_data: &mut GameData) {
|
||||
let exh = game_data.game_data.read_excel_sheet_header("Race").unwrap();
|
||||
let exd = game_data
|
||||
.game_data
|
||||
.read_excel_sheet("Race", &exh, Language::English, 0)
|
||||
.unwrap();
|
||||
|
||||
|
@ -278,4 +271,45 @@ impl Inventory {
|
|||
ContainerType::ArmouryBody => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_main_weapon_id(&self, game_data: &mut GameData) -> u64 {
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.main_hand.id)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn get_model_ids(&self, game_data: &mut GameData) -> [u32; 10] {
|
||||
[
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.head.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.body.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.hands.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.legs.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.feet.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.ears.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.neck.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.wrists.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.left_ring.id)
|
||||
.unwrap_or(0) as u32,
|
||||
game_data
|
||||
.get_primary_model_id(self.equipped.right_ring.id)
|
||||
.unwrap_or(0) as u32,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue