mirror of
https://github.com/redstrate/Kawari.git
synced 2025-06-30 11:47:45 +00:00
Fix bad assumption with EXP/Level array indices
They don't always correspond to their classjob id, because jobs share the same EXP/Levels as their base classes.
This commit is contained in:
parent
8f61fc36bd
commit
66da9abc90
2 changed files with 84 additions and 51 deletions
|
@ -20,6 +20,7 @@ pub struct GameData {
|
||||||
pub game_data: physis::gamedata::GameData,
|
pub game_data: physis::gamedata::GameData,
|
||||||
pub item_exh: EXH,
|
pub item_exh: EXH,
|
||||||
pub item_pages: Vec<EXD>,
|
pub item_pages: Vec<EXD>,
|
||||||
|
pub classjob_exp_indexes: Vec<i8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GameData {
|
impl Default for GameData {
|
||||||
|
@ -46,10 +47,21 @@ impl GameData {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut classjob_exp_indexes = Vec::new();
|
||||||
|
|
||||||
|
let sheet = ClassJobSheet::read_from(&mut game_data, Language::English).unwrap();
|
||||||
|
// TODO: ids are hardcoded until we have API in Icarus to do this
|
||||||
|
for i in 0..43 {
|
||||||
|
let row = sheet.get_row(i).unwrap();
|
||||||
|
|
||||||
|
classjob_exp_indexes.push(*row.ExpArrayIndex().into_i8().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
game_data,
|
game_data,
|
||||||
item_exh,
|
item_exh,
|
||||||
item_pages,
|
item_pages,
|
||||||
|
classjob_exp_indexes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,11 +326,8 @@ impl GameData {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the array index used in EXP & levels.
|
/// Gets the array index used in EXP & levels.
|
||||||
pub fn get_exp_array_index(&mut self, classjob_id: u16) -> Option<i8> {
|
pub fn get_exp_array_index(&self, classjob_id: u16) -> Option<i8> {
|
||||||
let sheet = ClassJobSheet::read_from(&mut self.game_data, Language::English)?;
|
self.classjob_exp_indexes.get(classjob_id as usize).copied()
|
||||||
let row = sheet.get_row(classjob_id as u32)?;
|
|
||||||
|
|
||||||
row.ExpArrayIndex().into_i8().copied()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,24 +84,6 @@ pub struct PlayerData {
|
||||||
pub aetherytes: Vec<u8>,
|
pub aetherytes: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlayerData {
|
|
||||||
pub fn current_level(&self) -> i32 {
|
|
||||||
self.classjob_levels[self.classjob_id as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_current_level(&mut self, level: i32) {
|
|
||||||
self.classjob_levels[self.classjob_id as usize] = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn current_exp(&self) -> u32 {
|
|
||||||
self.classjob_exp[self.classjob_id as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_current_exp(&mut self, exp: u32) {
|
|
||||||
self.classjob_exp[self.classjob_id as usize] = exp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a single connection between an instance of the client and the world server
|
/// Represents a single connection between an instance of the client and the world server
|
||||||
pub struct ZoneConnection {
|
pub struct ZoneConnection {
|
||||||
pub config: WorldConfig,
|
pub config: WorldConfig,
|
||||||
|
@ -315,19 +297,24 @@ impl ZoneConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_class_info(&mut self) {
|
pub async fn update_class_info(&mut self) {
|
||||||
let ipc = ServerZoneIpcSegment {
|
let ipc;
|
||||||
|
{
|
||||||
|
let game_data = self.gamedata.lock().unwrap();
|
||||||
|
|
||||||
|
ipc = ServerZoneIpcSegment {
|
||||||
op_code: ServerZoneIpcType::UpdateClassInfo,
|
op_code: ServerZoneIpcType::UpdateClassInfo,
|
||||||
timestamp: timestamp_secs(),
|
timestamp: timestamp_secs(),
|
||||||
data: ServerZoneIpcData::UpdateClassInfo(UpdateClassInfo {
|
data: ServerZoneIpcData::UpdateClassInfo(UpdateClassInfo {
|
||||||
class_id: self.player_data.classjob_id,
|
class_id: self.player_data.classjob_id,
|
||||||
synced_level: self.player_data.current_level() as u16,
|
synced_level: self.current_level(&game_data) as u16,
|
||||||
class_level: self.player_data.current_level() as u16,
|
class_level: self.current_level(&game_data) as u16,
|
||||||
current_level: self.player_data.current_level() as u16,
|
current_level: self.current_level(&game_data) as u16,
|
||||||
current_exp: self.player_data.current_exp(),
|
current_exp: self.current_exp(&game_data),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
self.send_segment(PacketSegment {
|
self.send_segment(PacketSegment {
|
||||||
source_actor: self.player_data.actor_id,
|
source_actor: self.player_data.actor_id,
|
||||||
|
@ -748,7 +735,7 @@ impl ZoneConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task::SetLevel { level } => {
|
Task::SetLevel { level } => {
|
||||||
self.player_data.set_current_level(*level);
|
self.set_current_level(*level);
|
||||||
self.update_class_info().await;
|
self.update_class_info().await;
|
||||||
}
|
}
|
||||||
Task::ChangeWeather { id } => {
|
Task::ChangeWeather { id } => {
|
||||||
|
@ -875,13 +862,17 @@ impl ZoneConnection {
|
||||||
list[..self.status_effects.status_effects.len()]
|
list[..self.status_effects.status_effects.len()]
|
||||||
.copy_from_slice(&self.status_effects.status_effects);
|
.copy_from_slice(&self.status_effects.status_effects);
|
||||||
|
|
||||||
let ipc = ServerZoneIpcSegment {
|
let ipc;
|
||||||
|
{
|
||||||
|
let game_data = self.gamedata.lock().unwrap();
|
||||||
|
|
||||||
|
ipc = ServerZoneIpcSegment {
|
||||||
op_code: ServerZoneIpcType::StatusEffectList,
|
op_code: ServerZoneIpcType::StatusEffectList,
|
||||||
timestamp: timestamp_secs(),
|
timestamp: timestamp_secs(),
|
||||||
data: ServerZoneIpcData::StatusEffectList(StatusEffectList {
|
data: ServerZoneIpcData::StatusEffectList(StatusEffectList {
|
||||||
statues: list,
|
statues: list,
|
||||||
classjob_id: self.player_data.classjob_id,
|
classjob_id: self.player_data.classjob_id,
|
||||||
level: self.player_data.current_level() as u8,
|
level: self.current_level(&game_data) as u8,
|
||||||
curr_hp: self.player_data.curr_hp,
|
curr_hp: self.player_data.curr_hp,
|
||||||
max_hp: self.player_data.max_hp,
|
max_hp: self.player_data.max_hp,
|
||||||
curr_mp: self.player_data.curr_mp,
|
curr_mp: self.player_data.curr_mp,
|
||||||
|
@ -890,6 +881,7 @@ impl ZoneConnection {
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
self.send_segment(PacketSegment {
|
self.send_segment(PacketSegment {
|
||||||
source_actor: self.player_data.actor_id,
|
source_actor: self.player_data.actor_id,
|
||||||
|
@ -1019,7 +1011,7 @@ impl ZoneConnection {
|
||||||
hp_max: self.player_data.max_hp,
|
hp_max: self.player_data.max_hp,
|
||||||
mp_curr: self.player_data.curr_mp,
|
mp_curr: self.player_data.curr_mp,
|
||||||
mp_max: self.player_data.max_mp,
|
mp_max: self.player_data.max_mp,
|
||||||
level: self.player_data.current_level() as u8,
|
level: self.current_level(&game_data) as u8,
|
||||||
object_kind: ObjectKind::Player(PlayerSubKind::Player),
|
object_kind: ObjectKind::Player(PlayerSubKind::Player),
|
||||||
look: chara_details.chara_make.customize,
|
look: chara_details.chara_make.customize,
|
||||||
display_flags: DisplayFlag::UNK,
|
display_flags: DisplayFlag::UNK,
|
||||||
|
@ -1168,4 +1160,36 @@ impl ZoneConnection {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_level(&self, game_data: &GameData) -> i32 {
|
||||||
|
let index = game_data
|
||||||
|
.get_exp_array_index(self.player_data.classjob_id as u16)
|
||||||
|
.unwrap();
|
||||||
|
self.player_data.classjob_levels[index as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_current_level(&mut self, level: i32) {
|
||||||
|
let game_data = self.gamedata.lock().unwrap();
|
||||||
|
|
||||||
|
let index = game_data
|
||||||
|
.get_exp_array_index(self.player_data.classjob_id as u16)
|
||||||
|
.unwrap();
|
||||||
|
self.player_data.classjob_levels[index as usize] = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_exp(&self, game_data: &GameData) -> u32 {
|
||||||
|
let index = game_data
|
||||||
|
.get_exp_array_index(self.player_data.classjob_id as u16)
|
||||||
|
.unwrap();
|
||||||
|
self.player_data.classjob_exp[index as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_current_exp(&mut self, exp: u32) {
|
||||||
|
let game_data = self.gamedata.lock().unwrap();
|
||||||
|
|
||||||
|
let index = game_data
|
||||||
|
.get_exp_array_index(self.player_data.classjob_id as u16)
|
||||||
|
.unwrap();
|
||||||
|
self.player_data.classjob_exp[index as usize] = exp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue