add tools
This commit is contained in:
+10831
File diff suppressed because it is too large
Load Diff
@@ -1,47 +1,151 @@
|
|||||||
use super::*;
|
use crate::net::tools::{self, BattleType, Monster};
|
||||||
|
|
||||||
static BATTLE_LINEUP: [u32; 4] = [1309, 1308, 1307, 1315];
|
use super::*;
|
||||||
|
|
||||||
pub async fn on_start_cocoon_stage_cs_req(
|
pub async fn on_start_cocoon_stage_cs_req(
|
||||||
session: &mut PlayerSession,
|
session: &mut PlayerSession,
|
||||||
body: &StartCocoonStageCsReq,
|
body: &StartCocoonStageCsReq,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let player = tools::JsonData::load().await;
|
||||||
|
|
||||||
|
let mut battle_info = SceneBattleInfo {
|
||||||
|
stage_id: player.battle_config.stage_id,
|
||||||
|
logic_random_seed: 4444,
|
||||||
|
battle_id: 1,
|
||||||
|
kimmjioaodn: player.battle_config.cycle_count,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// avatars
|
||||||
|
for i in 0..4 {
|
||||||
|
let avatar_id = &player.lineups.get(&i).unwrap_or(&0);
|
||||||
|
if **avatar_id == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(avatar) = player.avatars.get(&avatar_id) {
|
||||||
|
let (battle_avatar, techs) = avatar.to_battle_avatar_proto(
|
||||||
|
i,
|
||||||
|
player
|
||||||
|
.lightcones
|
||||||
|
.iter()
|
||||||
|
.find(|v| v.equip_avatar == avatar.avatar_id),
|
||||||
|
player
|
||||||
|
.relics
|
||||||
|
.iter()
|
||||||
|
.filter(|v| v.equip_avatar == avatar.avatar_id)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
);
|
||||||
|
for tech in techs {
|
||||||
|
battle_info.buff_list.push(tech);
|
||||||
|
}
|
||||||
|
battle_info.battle_avatar_list.push(battle_avatar);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom stats for avatars
|
||||||
|
for stat in &player.battle_config.custom_stats {
|
||||||
|
for avatar in &mut battle_info.battle_avatar_list {
|
||||||
|
if avatar.relic_list.len() == 0 {
|
||||||
|
avatar.relic_list.push(BattleRelic {
|
||||||
|
id: 61011,
|
||||||
|
main_affix_id: 1,
|
||||||
|
level: 1,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sub_affix) = avatar.relic_list[0]
|
||||||
|
.sub_affix_list
|
||||||
|
.iter_mut()
|
||||||
|
.find(|v| v.affix_id == stat.sub_affix_id)
|
||||||
|
{
|
||||||
|
sub_affix.cnt = stat.count;
|
||||||
|
} else {
|
||||||
|
avatar.relic_list[0].sub_affix_list.push(RelicAffix {
|
||||||
|
affix_id: stat.sub_affix_id,
|
||||||
|
cnt: stat.count,
|
||||||
|
step: stat.step,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// blessings
|
||||||
|
for blessing in &player.battle_config.blessings {
|
||||||
|
let mut buffs = BattleBuff {
|
||||||
|
id: blessing.id,
|
||||||
|
level: blessing.level,
|
||||||
|
wave_flag: 0xffffffff,
|
||||||
|
owner_index: 0xffffffff,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
if let Some(dynamic_key) = &blessing.dynamic_key {
|
||||||
|
buffs
|
||||||
|
.dynamic_values
|
||||||
|
.insert(dynamic_key.key.clone(), dynamic_key.value as f32);
|
||||||
|
};
|
||||||
|
battle_info.buff_list.push(buffs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pf score object
|
||||||
|
if player.battle_config.battle_type == BattleType::PF {
|
||||||
|
let mut battle_target = Hbinjjdphdo::default();
|
||||||
|
battle_target.bgnpebhgelb.push(BattleTarget {
|
||||||
|
id: 10001,
|
||||||
|
progress: 0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
battle_info.ichnbmifjdi.insert(1, battle_target);
|
||||||
|
for i in 2..=4 {
|
||||||
|
battle_info
|
||||||
|
.ichnbmifjdi
|
||||||
|
.insert(i, Hbinjjdphdo::default());
|
||||||
|
}
|
||||||
|
battle_info.ichnbmifjdi.insert(
|
||||||
|
5,
|
||||||
|
Hbinjjdphdo {
|
||||||
|
bgnpebhgelb: vec![
|
||||||
|
BattleTarget {
|
||||||
|
id: 2001,
|
||||||
|
progress: 0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
BattleTarget {
|
||||||
|
id: 2002,
|
||||||
|
progress: 0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SU
|
||||||
|
if player.battle_config.battle_type == BattleType::SU {
|
||||||
|
battle_info
|
||||||
|
.mpobegkcikn
|
||||||
|
.push(Npjnkmmjfdf {
|
||||||
|
chgdaadjepi: player.battle_config.path_resonance_id,
|
||||||
|
status: Some(Agpocmnmmdi {
|
||||||
|
sp: Some(AmountInfo {
|
||||||
|
cur_amount: 10_000,
|
||||||
|
max_amount: 10_000,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// monsters
|
||||||
|
battle_info.monster_wave_list = Monster::to_scene_monster_waves(&player.battle_config.monsters);
|
||||||
|
|
||||||
let rsp = StartCocoonStageScRsp {
|
let rsp = StartCocoonStageScRsp {
|
||||||
retcode: 0,
|
retcode: 0,
|
||||||
prop_entity_id: body.prop_entity_id,
|
prop_entity_id: body.prop_entity_id,
|
||||||
cocoon_id: body.cocoon_id,
|
cocoon_id: body.cocoon_id,
|
||||||
wave: body.wave,
|
wave: body.wave,
|
||||||
battle_info: Some(SceneBattleInfo {
|
battle_info: Some(battle_info),
|
||||||
stage_id: 201012311,
|
|
||||||
logic_random_seed: 4444,
|
|
||||||
battle_id: 1,
|
|
||||||
battle_avatar_list: BATTLE_LINEUP
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, id)| BattleAvatar {
|
|
||||||
index: idx as u32,
|
|
||||||
id: *id,
|
|
||||||
level: 80,
|
|
||||||
promotion: 6,
|
|
||||||
rank: 6,
|
|
||||||
hp: 10000,
|
|
||||||
avatar_type: 3,
|
|
||||||
sp: Some(AmountInfo {
|
|
||||||
cur_amount: 10000,
|
|
||||||
max_amount: 10000,
|
|
||||||
}),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
monster_wave_list: vec![SceneMonsterWave {
|
|
||||||
monster_list: vec![SceneMonsterParam {
|
|
||||||
monster_id: 3013010,
|
|
||||||
..Default::default()
|
|
||||||
}],
|
|
||||||
..Default::default()
|
|
||||||
}],
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
session.send(CMD_START_COCOON_STAGE_SC_RSP, rsp).await
|
session.send(CMD_START_COCOON_STAGE_SC_RSP, rsp).await
|
||||||
|
|||||||
@@ -1,38 +1,31 @@
|
|||||||
use super::*;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
static STARTING_LINEUP: [u32; 4] = [1309, 1308, 1307, 1315];
|
use crate::net::tools::{self, AvatarJson};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
pub async fn on_get_all_lineup_data_cs_req(
|
pub async fn on_get_all_lineup_data_cs_req(
|
||||||
session: &mut PlayerSession,
|
session: &mut PlayerSession,
|
||||||
_body: &GetAllLineupDataCsReq,
|
_body: &GetAllLineupDataCsReq,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let player = tools::JsonData::load().await;
|
||||||
|
let lineup = LineupInfo {
|
||||||
|
extra_lineup_type: ExtraLineupType::LineupNone.into(),
|
||||||
|
name: "Squad 1".to_string(),
|
||||||
|
// mp: 5,
|
||||||
|
// leader_slot: 0,
|
||||||
|
// max_mp: 5,
|
||||||
|
avatar_list: AvatarJson::to_lineup_avatars(&player.lineups, &player.avatars),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
session
|
session
|
||||||
.send(
|
.send(
|
||||||
CMD_GET_ALL_LINEUP_DATA_SC_RSP,
|
CMD_GET_ALL_LINEUP_DATA_SC_RSP,
|
||||||
GetAllLineupDataScRsp {
|
GetAllLineupDataScRsp {
|
||||||
retcode: 0,
|
lineup_list: vec![lineup],
|
||||||
cur_index: 0,
|
|
||||||
lineup_list: vec![LineupInfo {
|
|
||||||
plane_id: 10001,
|
|
||||||
name: String::from("Lineup 1"),
|
|
||||||
index: 0,
|
|
||||||
avatar_list: STARTING_LINEUP
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, id)| LineupAvatar {
|
|
||||||
id: *id,
|
|
||||||
slot: idx as u32,
|
|
||||||
hp: 10000,
|
|
||||||
sp: Some(AmountInfo {
|
|
||||||
cur_amount: 10000,
|
|
||||||
max_amount: 10000,
|
|
||||||
}),
|
|
||||||
satiety: 100,
|
|
||||||
avatar_type: 3,
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}],
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -42,37 +35,142 @@ pub async fn on_get_cur_lineup_data_cs_req(
|
|||||||
session: &mut PlayerSession,
|
session: &mut PlayerSession,
|
||||||
_body: &GetCurLineupDataCsReq,
|
_body: &GetCurLineupDataCsReq,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let player = tools::JsonData::load().await;
|
||||||
|
let mut lineup = LineupInfo {
|
||||||
|
extra_lineup_type: ExtraLineupType::LineupNone.into(),
|
||||||
|
name: "Squad 1".to_string(),
|
||||||
|
// mp: 5,
|
||||||
|
// leader_slot: 0,
|
||||||
|
// max_mp: 5,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let avatar_ids = player
|
||||||
|
.avatars
|
||||||
|
.iter()
|
||||||
|
.map(|(_, v)| v.avatar_id)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut avatars = player
|
||||||
|
.lineups
|
||||||
|
.iter()
|
||||||
|
.filter(|(_slot, v)| v > &&0 && avatar_ids.contains(v))
|
||||||
|
.map(|(slot, avatar_id)| {
|
||||||
|
player
|
||||||
|
.avatars
|
||||||
|
.get(avatar_id)
|
||||||
|
.unwrap()
|
||||||
|
.to_lineup_avatar_proto(*slot)
|
||||||
|
})
|
||||||
|
.collect::<Vec<LineupAvatar>>();
|
||||||
|
|
||||||
|
lineup.avatar_list.append(&mut avatars);
|
||||||
|
|
||||||
|
|
||||||
session
|
session
|
||||||
.send(
|
.send(
|
||||||
CMD_GET_CUR_LINEUP_DATA_SC_RSP,
|
CMD_GET_CUR_LINEUP_DATA_SC_RSP,
|
||||||
GetCurLineupDataScRsp {
|
GetCurLineupDataScRsp {
|
||||||
retcode: 0,
|
lineup: Some(lineup),
|
||||||
lineup: Some(LineupInfo {
|
|
||||||
plane_id: 10001,
|
|
||||||
name: String::from("Lineup 1"),
|
|
||||||
index: 0,
|
|
||||||
avatar_list: STARTING_LINEUP
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, id)| LineupAvatar {
|
|
||||||
id: *id,
|
|
||||||
slot: idx as u32,
|
|
||||||
hp: 10000,
|
|
||||||
sp: Some(AmountInfo {
|
|
||||||
cur_amount: 10000,
|
|
||||||
max_amount: 10000,
|
|
||||||
}),
|
|
||||||
satiety: 100,
|
|
||||||
avatar_type: 3,
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn on_join_lineup_cs_req(
|
||||||
|
session: &mut PlayerSession,
|
||||||
|
body: &JoinLineupCsReq,
|
||||||
|
) -> Result<()> {
|
||||||
|
|
||||||
|
// update lineups
|
||||||
|
// TODO: FIX THESE SHIT
|
||||||
|
{
|
||||||
|
let mut player = tools::JsonData::load().await;
|
||||||
|
let lineups = &mut player.lineups;
|
||||||
|
lineups.insert(body.slot, body.base_avatar_id);
|
||||||
|
player.save_lineup().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let player = tools::JsonData::load().await;
|
||||||
|
let lineups = &player.lineups;
|
||||||
|
|
||||||
|
refresh_lineup(session, &lineups, &player.avatars).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.send(CMD_JOIN_LINEUP_SC_RSP, JoinLineupScRsp::default())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn on_replace_lineup_cs_req(
|
||||||
|
_session: &mut PlayerSession,
|
||||||
|
req: &ReplaceLineupCsReq,
|
||||||
|
) -> Result<()> {
|
||||||
|
{
|
||||||
|
let mut player = tools::JsonData::load().await;
|
||||||
|
|
||||||
|
let lineups = &mut player.lineups;
|
||||||
|
for (slot, avatar_id) in &mut *lineups {
|
||||||
|
if let Some(lineup) = req.jkifflmenfn.get(*slot as usize) {
|
||||||
|
*avatar_id = lineup.id;
|
||||||
|
} else {
|
||||||
|
*avatar_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.save_lineup().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let player = tools::JsonData::load().await;
|
||||||
|
let lineups = &player.lineups;
|
||||||
|
|
||||||
|
refresh_lineup(_session, &lineups, &player.avatars).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
_session.send(CMD_JOIN_LINEUP_SC_RSP, JoinLineupScRsp::default())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn on_quit_lineup_cs_req(
|
||||||
|
_session: &mut PlayerSession,
|
||||||
|
_: &QuitLineupCsReq,
|
||||||
|
) -> Result<()> {
|
||||||
|
_session.send(CMD_JOIN_LINEUP_SC_RSP, JoinLineupScRsp::default())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn refresh_lineup(
|
||||||
|
sess: &mut PlayerSession,
|
||||||
|
lineups: &BTreeMap<u32, u32>,
|
||||||
|
avatars: &BTreeMap<u32, AvatarJson>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let lineup = LineupInfo {
|
||||||
|
extra_lineup_type: ExtraLineupType::LineupNone.into(),
|
||||||
|
name: "Squad 1".to_string(),
|
||||||
|
|
||||||
|
avatar_list: AvatarJson::to_lineup_avatars(lineups, avatars),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
sess.send(
|
||||||
|
CMD_SYNC_LINEUP_NOTIFY,
|
||||||
|
SyncLineupNotify {
|
||||||
|
lineup: Some(lineup),
|
||||||
|
reason_list: vec![]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn on_change_lineup_leader_cs_req(
|
pub async fn on_change_lineup_leader_cs_req(
|
||||||
session: &mut PlayerSession,
|
session: &mut PlayerSession,
|
||||||
body: &ChangeLineupLeaderCsReq,
|
body: &ChangeLineupLeaderCsReq,
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ pub mod gateway;
|
|||||||
mod handlers;
|
mod handlers;
|
||||||
mod packet;
|
mod packet;
|
||||||
mod session;
|
mod session;
|
||||||
|
mod tools;
|
||||||
|
|
||||||
|
|
||||||
pub use packet::NetPacket;
|
pub use packet::NetPacket;
|
||||||
pub use session::PlayerSession;
|
pub use session::PlayerSession;
|
||||||
|
|||||||
@@ -641,18 +641,18 @@ trait_handler! {
|
|||||||
// ExtraLineupDestroyNotify 763;
|
// ExtraLineupDestroyNotify 763;
|
||||||
// GetLineupAvatarDataCsReq 768;
|
// GetLineupAvatarDataCsReq 768;
|
||||||
// SwitchLineupIndexScRsp 795;
|
// SwitchLineupIndexScRsp 795;
|
||||||
// JoinLineupCsReq 702;
|
JoinLineupCsReq 702;
|
||||||
// GetAllLineupDataScRsp 716;
|
// GetAllLineupDataScRsp 716;
|
||||||
// SetLineupNameCsReq 742;
|
// SetLineupNameCsReq 742;
|
||||||
// ChangeLineupLeaderScRsp 733;
|
// ChangeLineupLeaderScRsp 733;
|
||||||
ChangeLineupLeaderCsReq 706;
|
ChangeLineupLeaderCsReq 706;
|
||||||
// ReplaceLineupCsReq 785;
|
ReplaceLineupCsReq 785;
|
||||||
// SwapLineupCsReq 786;
|
// SwapLineupCsReq 786;
|
||||||
// QuitLineupScRsp 743;
|
// QuitLineupScRsp 743;
|
||||||
// GetLineupAvatarDataScRsp 796;
|
// GetLineupAvatarDataScRsp 796;
|
||||||
// ReplaceLineupScRsp 756;
|
// ReplaceLineupScRsp 756;
|
||||||
// GetStageLineupCsReq 734;
|
// GetStageLineupCsReq 734;
|
||||||
// QuitLineupCsReq 719;
|
QuitLineupCsReq 719;
|
||||||
// SetLineupNameScRsp 737;
|
// SetLineupNameScRsp 737;
|
||||||
// SwitchLineupIndexCsReq 759;
|
// SwitchLineupIndexCsReq 759;
|
||||||
GetCurLineupDataCsReq 762;
|
GetCurLineupDataCsReq 762;
|
||||||
|
|||||||
@@ -0,0 +1,608 @@
|
|||||||
|
use proto::{Avatar, AvatarSkillTree, BattleAvatar};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
use proto::*;
|
||||||
|
|
||||||
|
// AVATAR
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct AvatarJson {
|
||||||
|
#[serde(alias = "ownerUid")]
|
||||||
|
pub owner_uid: u32,
|
||||||
|
#[serde(alias = "avatarId")]
|
||||||
|
pub avatar_id: u32,
|
||||||
|
pub data: AvatarData,
|
||||||
|
pub level: u32,
|
||||||
|
pub promotion: u32,
|
||||||
|
// pub rank: u32,
|
||||||
|
#[serde(alias = "use_technique")]
|
||||||
|
#[serde(alias = "useTechnique")]
|
||||||
|
pub techniques: Vec<u32>,
|
||||||
|
#[serde(alias = "spValue")]
|
||||||
|
pub sp_value: Option<u32>,
|
||||||
|
#[serde(alias = "spMax")]
|
||||||
|
pub sp_max: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct AvatarData {
|
||||||
|
pub rank: u32,
|
||||||
|
pub skills: BTreeMap<u32, u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AvatarJson {
|
||||||
|
pub fn to_avatar_proto(
|
||||||
|
&self,
|
||||||
|
lightcone: Option<&Lightcone>,
|
||||||
|
relics: Vec<&Relic>,
|
||||||
|
) -> Avatar {
|
||||||
|
Avatar {
|
||||||
|
base_avatar_id: self.avatar_id,
|
||||||
|
exp: 0,
|
||||||
|
level: self.level,
|
||||||
|
promotion: self.promotion,
|
||||||
|
rank: self.data.rank,
|
||||||
|
skilltree_list: self
|
||||||
|
.data
|
||||||
|
.skills
|
||||||
|
.iter()
|
||||||
|
.map(|v| AvatarSkillTree {
|
||||||
|
point_id: *v.0,
|
||||||
|
level: *v.1,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
equipment_unique_id: if let Some(lc) = lightcone {
|
||||||
|
lc.internal_uid
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
amafpakcckf: relics
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_equipment_relic_proto())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_battle_avatar_proto(
|
||||||
|
&self,
|
||||||
|
index: u32,
|
||||||
|
lightcone: Option<&Lightcone>,
|
||||||
|
relics: Vec<&Relic>,
|
||||||
|
) -> (BattleAvatar, Vec<BattleBuff>) {
|
||||||
|
let battle_avatar = BattleAvatar {
|
||||||
|
index,
|
||||||
|
avatar_type: AvatarType::AvatarFormalType.into(),
|
||||||
|
id: self.avatar_id,
|
||||||
|
level: self.level,
|
||||||
|
rank: self.data.rank,
|
||||||
|
skilltree_list: self
|
||||||
|
.data
|
||||||
|
.skills
|
||||||
|
.iter()
|
||||||
|
.map(|v| AvatarSkillTree {
|
||||||
|
point_id: *v.0,
|
||||||
|
level: *v.1,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
equipment_list: if let Some(lc) = lightcone {
|
||||||
|
vec![lc.to_battle_equipment_proto()]
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
|
hp: 10_000,
|
||||||
|
promotion: self.promotion,
|
||||||
|
relic_list: relics
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_battle_relic_proto())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
world_level: 6,
|
||||||
|
sp: Some(AmountInfo {
|
||||||
|
cur_amount: self.sp_value.unwrap_or(10_000),
|
||||||
|
max_amount: self.sp_max.unwrap_or(10_000),
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut battle_buff = Vec::<BattleBuff>::new();
|
||||||
|
for buff_id in &self.techniques {
|
||||||
|
battle_buff.push(BattleBuff {
|
||||||
|
wave_flag: 0xffffffff,
|
||||||
|
owner_index: index as u32,
|
||||||
|
level: 1,
|
||||||
|
id: *buff_id,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(battle_avatar, battle_buff)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_lineup_avatar_proto(&self, slot: u32) -> LineupAvatar {
|
||||||
|
LineupAvatar {
|
||||||
|
id: self.avatar_id,
|
||||||
|
hp: 10_000,
|
||||||
|
satiety: 100,
|
||||||
|
avatar_type: AvatarType::AvatarFormalType.into(),
|
||||||
|
sp: Some(AmountInfo {
|
||||||
|
cur_amount: self.sp_value.unwrap_or(10_000),
|
||||||
|
max_amount: self.sp_max.unwrap_or(10_000),
|
||||||
|
}),
|
||||||
|
slot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_lineup_avatars(
|
||||||
|
lineups: &BTreeMap<u32, u32>,
|
||||||
|
avatars: &BTreeMap<u32, AvatarJson>,
|
||||||
|
) -> Vec<LineupAvatar> {
|
||||||
|
let avatar_ids = avatars.iter().map(|(_, v)| v.avatar_id).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
lineups
|
||||||
|
.iter()
|
||||||
|
.filter(|(_slot, v)| v > &&0 && avatar_ids.contains(v))
|
||||||
|
.map(|(slot, avatar_id)| {
|
||||||
|
avatars
|
||||||
|
.get(avatar_id)
|
||||||
|
.unwrap()
|
||||||
|
.to_lineup_avatar_proto(*slot)
|
||||||
|
})
|
||||||
|
.collect::<Vec<LineupAvatar>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_lineup_info(lineups: &BTreeMap<u32, u32>) -> LineupInfo {
|
||||||
|
let mut lineup_info = LineupInfo {
|
||||||
|
extra_lineup_type: ExtraLineupType::LineupNone.into(),
|
||||||
|
name: "Squad 1".to_string(),
|
||||||
|
// mp: 5,
|
||||||
|
// leader_slot: 0,
|
||||||
|
// max_mp: 5,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
for (_, id) in lineups {
|
||||||
|
if *id == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lineup_info.avatar_list.push(LineupAvatar {
|
||||||
|
id: *id,
|
||||||
|
hp: 10_000,
|
||||||
|
satiety: 100,
|
||||||
|
avatar_type: AvatarType::AvatarFormalType.into(),
|
||||||
|
sp: Some(AmountInfo {
|
||||||
|
cur_amount: 10_000,
|
||||||
|
max_amount: 10_000,
|
||||||
|
}),
|
||||||
|
slot: lineup_info.avatar_list.len() as u32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lineup_info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// LIGHTCONE
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Lightcone {
|
||||||
|
pub level: u32,
|
||||||
|
#[serde(alias = "itemId")]
|
||||||
|
pub item_id: u32,
|
||||||
|
#[serde(alias = "equipAvatar")]
|
||||||
|
pub equip_avatar: u32,
|
||||||
|
pub rank: u32,
|
||||||
|
pub promotion: u32,
|
||||||
|
#[serde(alias = "internalUid")]
|
||||||
|
pub internal_uid: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lightcone {
|
||||||
|
pub fn to_equipment_proto(&self) -> Equipment {
|
||||||
|
Equipment {
|
||||||
|
base_avatar_id: self.equip_avatar,
|
||||||
|
exp: 0,
|
||||||
|
is_protected: false,
|
||||||
|
level: self.level,
|
||||||
|
promotion: self.promotion,
|
||||||
|
rank: self.rank,
|
||||||
|
tid: self.item_id,
|
||||||
|
unique_id: self.internal_uid,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_battle_equipment_proto(&self) -> BattleEquipment {
|
||||||
|
BattleEquipment {
|
||||||
|
id: self.item_id,
|
||||||
|
level: self.level,
|
||||||
|
promotion: self.promotion,
|
||||||
|
rank: self.rank,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// RELIC
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct Relic {
|
||||||
|
pub level: u32,
|
||||||
|
#[serde(alias = "relicId")]
|
||||||
|
pub relic_id: u32,
|
||||||
|
#[serde(alias = "relicSetId")]
|
||||||
|
pub relic_set_id: u32,
|
||||||
|
#[serde(alias = "mainAffixId")]
|
||||||
|
pub main_affix_id: u32,
|
||||||
|
#[serde(alias = "subAffixes")]
|
||||||
|
pub sub_affixes: Vec<SubAffix>,
|
||||||
|
#[serde(alias = "internalUid")]
|
||||||
|
pub internal_uid: u32,
|
||||||
|
#[serde(alias = "equipAvatar")]
|
||||||
|
pub equip_avatar: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||||
|
pub struct SubAffix {
|
||||||
|
#[serde(alias = "subAffixId")]
|
||||||
|
pub sub_affix_id: u32,
|
||||||
|
pub count: u32,
|
||||||
|
pub step: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Relic {
|
||||||
|
pub fn to_relic_proto(&self) -> proto::Relic {
|
||||||
|
proto::Relic {
|
||||||
|
base_avatar_id: self.equip_avatar,
|
||||||
|
exp: 0,
|
||||||
|
is_protected: false,
|
||||||
|
level: self.level,
|
||||||
|
main_affix_id: self.main_affix_id,
|
||||||
|
tid: self.relic_id,
|
||||||
|
unique_id: self.internal_uid,
|
||||||
|
sub_affix_list: self
|
||||||
|
.sub_affixes
|
||||||
|
.iter()
|
||||||
|
.map(|v| RelicAffix {
|
||||||
|
affix_id: v.sub_affix_id,
|
||||||
|
cnt: v.count,
|
||||||
|
step: v.step,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_battle_relic_proto(&self) -> BattleRelic {
|
||||||
|
BattleRelic {
|
||||||
|
id: self.relic_id,
|
||||||
|
level: self.level,
|
||||||
|
main_affix_id: self.main_affix_id,
|
||||||
|
unique_id: self.internal_uid,
|
||||||
|
sub_affix_list: self
|
||||||
|
.sub_affixes
|
||||||
|
.iter()
|
||||||
|
.map(|v| RelicAffix {
|
||||||
|
affix_id: v.sub_affix_id,
|
||||||
|
cnt: v.count,
|
||||||
|
step: v.step,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_equipment_relic_proto(&self) -> EquipRelic {
|
||||||
|
EquipRelic {
|
||||||
|
ipnhjoomhdm: 0, //slot
|
||||||
|
llepdadmfdo: self.internal_uid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MONSTER
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct Monster {
|
||||||
|
pub level: u32,
|
||||||
|
#[serde(alias = "monsterId")]
|
||||||
|
pub monster_id: u32,
|
||||||
|
#[serde(default)]
|
||||||
|
pub max_hp: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
impl Monster {
|
||||||
|
fn to_scene_monster_info(&self) -> SceneMonsterParam {
|
||||||
|
SceneMonsterParam {
|
||||||
|
monster_id: self.monster_id,
|
||||||
|
max_hp: self.max_hp,
|
||||||
|
aiapcboelmg: self.max_hp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_scene_monster_wave(wave_index: u32, monsters: &Vec<Self>) -> SceneMonsterWave {
|
||||||
|
let mut wave_index = wave_index;
|
||||||
|
if wave_index <= 0 {
|
||||||
|
wave_index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneMonsterWave {
|
||||||
|
iilhbcalikm: wave_index, // wave indexx??
|
||||||
|
|
||||||
|
ejahmdkklbn: Some(Holldlkceof { // monster param
|
||||||
|
level: monsters.iter().map(|v| v.level).max().unwrap_or(95),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
|
||||||
|
monster_list: monsters
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_scene_monster_info())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_scene_monster_waves(monsters: &Vec<Vec<Self>>) -> Vec<SceneMonsterWave> {
|
||||||
|
monsters
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, v)| Self::to_scene_monster_wave(i as u32, v))
|
||||||
|
.collect::<_>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// BATTLE CONFIG
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct BattleConfig {
|
||||||
|
pub battle_type: BattleType,
|
||||||
|
pub monsters: Vec<Vec<Monster>>,
|
||||||
|
pub blessings: Vec<BattleBuffJson>,
|
||||||
|
pub stage_id: u32,
|
||||||
|
pub cycle_count: u32,
|
||||||
|
pub path_resonance_id: u32,
|
||||||
|
pub custom_stats: Vec<SubAffix>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BattleConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
battle_type: Default::default(),
|
||||||
|
monsters: vec![vec![Monster {
|
||||||
|
level: 60,
|
||||||
|
monster_id: 3014022,
|
||||||
|
max_hp: 0,
|
||||||
|
}]],
|
||||||
|
stage_id: 201012311,
|
||||||
|
blessings: Default::default(),
|
||||||
|
cycle_count: Default::default(),
|
||||||
|
path_resonance_id: Default::default(),
|
||||||
|
custom_stats: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
|
pub enum BattleType {
|
||||||
|
DEFAULT = 0,
|
||||||
|
MOC = 1,
|
||||||
|
PF = 2,
|
||||||
|
SU = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BattleType {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::DEFAULT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BATTLE BUFFS
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct BattleBuffJson {
|
||||||
|
pub level: u32,
|
||||||
|
pub id: u32,
|
||||||
|
pub dynamic_key: Option<DynamicKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct DynamicKey {
|
||||||
|
pub key: String,
|
||||||
|
pub value: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
impl BattleBuffJson {
|
||||||
|
pub fn to_battle_buff_proto(&self) -> proto::BattleBuff {
|
||||||
|
proto::BattleBuff {
|
||||||
|
id: self.id,
|
||||||
|
level: self.level,
|
||||||
|
wave_flag: 0xffffffff,
|
||||||
|
owner_index: 0xffffffff,
|
||||||
|
dynamic_values: if let Some(dyn_key) = &self.dynamic_key {
|
||||||
|
HashMap::from([(dyn_key.key.clone(), dyn_key.value as f32)])
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCENE
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Scene {
|
||||||
|
pub plane_id: u32,
|
||||||
|
pub floor_id: u32,
|
||||||
|
pub entry_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Scene {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
entry_id: 2032101,
|
||||||
|
plane_id: 20321,
|
||||||
|
floor_id: 20321001,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct Position {
|
||||||
|
pub x: i32,
|
||||||
|
pub y: i32,
|
||||||
|
pub z: i32,
|
||||||
|
pub rot_y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Position {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
return self.x == 0 && self.y == 0 && self.z == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_motion(&self) -> MotionInfo {
|
||||||
|
MotionInfo {
|
||||||
|
// rot
|
||||||
|
eiaoiankefd: Some(Vector {
|
||||||
|
baimdminomk: 0,
|
||||||
|
bemlopmcgch: self.rot_y,
|
||||||
|
bagloppgnpb: 0,
|
||||||
|
}),
|
||||||
|
// pos
|
||||||
|
aomilajjmii: Some(Vector {
|
||||||
|
baimdminomk: self.x,
|
||||||
|
bemlopmcgch: self.y,
|
||||||
|
bagloppgnpb: self.z,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FREESR-DATA.json
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct JsonData {
|
||||||
|
pub lightcones: Vec<Lightcone>,
|
||||||
|
pub relics: Vec<Relic>,
|
||||||
|
pub avatars: BTreeMap<u32, AvatarJson>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub battle_config: BattleConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub lineups: BTreeMap<u32, u32>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub position: Position,
|
||||||
|
#[serde(default)]
|
||||||
|
pub scene: Scene,
|
||||||
|
#[serde(default)]
|
||||||
|
pub main_character: MainCharacter,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct JsonData2 {
|
||||||
|
#[serde(default)]
|
||||||
|
pub lineups: BTreeMap<u32, u32>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub position: Position,
|
||||||
|
#[serde(default)]
|
||||||
|
pub scene: Scene,
|
||||||
|
#[serde(default)]
|
||||||
|
pub main_character: MainCharacter,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
|
||||||
|
pub enum MainCharacter {
|
||||||
|
MalePyhsical = 8001,
|
||||||
|
FemalePhysical = 8002,
|
||||||
|
MalePreservation = 8003,
|
||||||
|
FemalePreservation = 8004,
|
||||||
|
MaleHarmony = 8005,
|
||||||
|
FemaleHarmony = 8006,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MainCharacter {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::FemaleHarmony
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JsonData {
|
||||||
|
pub async fn load() -> Self {
|
||||||
|
|
||||||
|
let mut json: JsonData = match serde_json::from_str(&tokio::fs::read_to_string("freesr-data.json").await.unwrap_or_default()) {
|
||||||
|
Ok(db) => db,
|
||||||
|
Err(err) => {
|
||||||
|
println!("{:#?}", err);
|
||||||
|
Self::create_dummy().await
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let json2: JsonData2 = serde_json::from_str(&tokio::fs::read_to_string("persistent").await.unwrap_or_default()).unwrap_or_default();
|
||||||
|
|
||||||
|
json.lineups = json2.lineups;
|
||||||
|
json.position = json2.position;
|
||||||
|
json.scene = json2.scene;
|
||||||
|
json.main_character = json2.main_character;
|
||||||
|
|
||||||
|
json
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn create_dummy() -> Self {
|
||||||
|
let mut db = Self {
|
||||||
|
lightcones: vec![],
|
||||||
|
relics: vec![],
|
||||||
|
avatars: BTreeMap::<u32, AvatarJson>::new(),
|
||||||
|
lineups: BTreeMap::<u32, u32>::new(),
|
||||||
|
scene: Default::default(),
|
||||||
|
position: Default::default(),
|
||||||
|
battle_config: Default::default(),
|
||||||
|
main_character: Default::default(),
|
||||||
|
};
|
||||||
|
db.avatars.insert(
|
||||||
|
8004,
|
||||||
|
AvatarJson {
|
||||||
|
avatar_id: 8004,
|
||||||
|
level: 80,
|
||||||
|
promotion: 6,
|
||||||
|
sp_max: Some(10_000),
|
||||||
|
sp_value: Some(10_000),
|
||||||
|
owner_uid: 0,
|
||||||
|
techniques: vec![],
|
||||||
|
data: AvatarData {
|
||||||
|
rank: 6,
|
||||||
|
skills: BTreeMap::from([
|
||||||
|
(800401, 6),
|
||||||
|
(800402, 10),
|
||||||
|
(800403, 10),
|
||||||
|
(800404, 10),
|
||||||
|
(800405, 1),
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
db.lineups.insert(0, 8004);
|
||||||
|
|
||||||
|
db.save().await;
|
||||||
|
|
||||||
|
db
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn save_lineup(&self) {
|
||||||
|
self.save().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn save(&self) {
|
||||||
|
let json = serde_json::to_string_pretty(&self).unwrap();
|
||||||
|
let _ = tokio::fs::write("freesr-data.json", json.as_bytes()).await;
|
||||||
|
let _ = tokio::fs::write("persistent", serde_json::to_string_pretty(&JsonData2 {
|
||||||
|
lineups: self.lineups.clone(),
|
||||||
|
main_character: self.main_character,
|
||||||
|
position: self.position.clone(),
|
||||||
|
scene: self.scene.clone()
|
||||||
|
}).unwrap().as_bytes()).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"lineups": {
|
||||||
|
"0": 1315,
|
||||||
|
"1": 1309,
|
||||||
|
"2": 1303,
|
||||||
|
"3": 1217
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 34639,
|
||||||
|
"y": 192819,
|
||||||
|
"z": 435863,
|
||||||
|
"rot_y": 26508
|
||||||
|
},
|
||||||
|
"scene": {
|
||||||
|
"plane_id": 20313,
|
||||||
|
"floor_id": 20313001,
|
||||||
|
"entry_id": 2031301
|
||||||
|
},
|
||||||
|
"main_character": "FemaleHarmony"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user