Weapons unlock & switching

This commit is contained in:
xeon 2024-04-13 17:34:52 +03:00
parent 8c1a42b9f4
commit 07348aed45
10 changed files with 10329 additions and 229 deletions

File diff suppressed because it is too large Load diff

View file

@ -72,6 +72,45 @@ pub struct AvatarFlycloakExcelConfig {
pub material_id: u32, pub material_id: u32,
} }
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct WeaponExcelConfig {
pub weapon_type: String,
pub rank_level: u32,
pub weapon_base_exp: u32,
pub skill_affix: Vec<u32>,
pub weapon_prop: Vec<WeaponProp>,
pub awaken_texture: String,
pub awaken_light_map_texture: String,
pub awaken_icon: String,
pub weapon_promote_id: u32,
pub story_id: u32,
pub awaken_costs: Vec<u32>,
pub gacha_card_name_hash: u64,
pub destroy_rule: String,
pub destroy_return_material: Vec<u32>,
pub destroy_return_material_count: Vec<u32>,
pub id: u32,
pub name_text_map_hash: u64,
pub desc_text_map_hash: u64,
pub icon: String,
pub item_type: String,
pub weight: u32,
pub rank: u32,
pub gadget_id: u32,
}
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct WeaponProp {
pub prop_type: String,
pub init_value: f32,
#[serde(rename = "type")]
pub type_field: String,
}
#[derive(Deserialize, Default)] #[derive(Deserialize, Default)]
#[serde(default)] #[serde(default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]

View file

@ -22,6 +22,7 @@ pub struct ExcelCollection {
pub avatar_configs: Vec<AvatarExcelConfig>, pub avatar_configs: Vec<AvatarExcelConfig>,
pub avatar_flycloak_configs: Vec<AvatarFlycloakExcelConfig>, pub avatar_flycloak_configs: Vec<AvatarFlycloakExcelConfig>,
pub avatar_costume_configs: Vec<AvatarCostumeExcelConfig>, pub avatar_costume_configs: Vec<AvatarCostumeExcelConfig>,
pub weapon_configs: Vec<WeaponExcelConfig>,
pub open_state_configs: Vec<OpenStateConfig>, pub open_state_configs: Vec<OpenStateConfig>,
} }
@ -44,6 +45,10 @@ impl ExcelCollection {
"assets/ExcelBinOutput/AvatarCostumeExcelConfigData.json", "assets/ExcelBinOutput/AvatarCostumeExcelConfigData.json",
)) ))
.unwrap(), .unwrap(),
weapon_configs: from_str(&load_asset(
"assets/ExcelBinOutput/WeaponExcelConfigData.json",
))
.unwrap(),
open_state_configs: from_str(&load_asset( open_state_configs: from_str(&load_asset(
"assets/ExcelBinOutput/OpenStateConfigData.json", "assets/ExcelBinOutput/OpenStateConfigData.json",
)) ))
@ -52,7 +57,7 @@ impl ExcelCollection {
} }
pub fn table_count(&self) -> usize { pub fn table_count(&self) -> usize {
4 5
} }
} }

View file

@ -1,7 +1,11 @@
use proto::*; use proto::*;
use super::*; use super::*;
use crate::{data, game::AvatarData, util}; use crate::{
data,
game::{AvatarData, WeaponData},
util,
};
pub struct SceneAvatar { pub struct SceneAvatar {
data: AvatarData, data: AvatarData,
@ -57,6 +61,10 @@ impl SceneAvatar {
} }
} }
pub fn change_weapon(&mut self, weapon: WeaponData) {
self.weapon = SceneWeapon::new(self.weapon.get_entity_id(), weapon);
}
pub fn ability_control_block(&self) -> AbilityControlBlock { pub fn ability_control_block(&self) -> AbilityControlBlock {
let mut control_block = AbilityControlBlock::default(); let mut control_block = AbilityControlBlock::default();

View file

@ -7,6 +7,7 @@ pub struct PlayerInfo {
pub uid: u32, pub uid: u32,
pub guid_manager: GUIDManager, pub guid_manager: GUIDManager,
pub avatars: Vec<AvatarData>, pub avatars: Vec<AvatarData>,
pub weapons: Vec<WeaponData>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -35,6 +36,7 @@ impl PlayerInfo {
uid: 1337, uid: 1337,
guid_manager: GUIDManager::new(), guid_manager: GUIDManager::new(),
avatars: Vec::new(), avatars: Vec::new(),
weapons: Vec::new(),
} }
} }
@ -42,12 +44,26 @@ impl PlayerInfo {
self.guid_manager.next() self.guid_manager.next()
} }
pub fn unlock_all_weapons(&mut self) {
self.weapons
.extend(EXCEL_COLLECTION.weapon_configs.iter().map(|w| WeaponData {
weapon_id: w.id,
guid: self.guid_manager.next(),
}));
}
pub fn unlock_all_avatars(&mut self) { pub fn unlock_all_avatars(&mut self) {
for config in EXCEL_COLLECTION for config in EXCEL_COLLECTION
.avatar_configs .avatar_configs
.iter() .iter()
.filter(|c| !DISABLED_AVATAR_LIST.contains(&c.id)) .filter(|c| !DISABLED_AVATAR_LIST.contains(&c.id))
{ {
let weapon = WeaponData {
weapon_id: config.initial_weapon,
guid: self.next_guid(),
};
self.weapons.push(weapon.clone());
let mut data = AvatarData { let mut data = AvatarData {
guid: self.next_guid(), guid: self.next_guid(),
avatar_id: config.id, avatar_id: config.id,
@ -55,10 +71,7 @@ impl PlayerInfo {
wearing_flycloak_id: 140001, wearing_flycloak_id: 140001,
costume_id: 0, costume_id: 0,
born_time: util::cur_timestamp() as u32, born_time: util::cur_timestamp() as u32,
weapon: WeaponData { weapon,
guid: self.next_guid(),
weapon_id: config.initial_weapon,
},
properties: Vec::new(), properties: Vec::new(),
fight_properties: Vec::new(), fight_properties: Vec::new(),
}; };
@ -156,6 +169,22 @@ impl AvatarData {
} }
} }
impl From<WeaponData> for Item {
fn from(value: WeaponData) -> Self {
Self {
item_id: value.weapon_id,
guid: value.guid,
detail: Some(item::Detail::Equip(Equip {
is_locked: false,
detail: Some(equip::Detail::Weapon(Weapon {
level: 1,
..Default::default()
})),
})),
}
}
}
impl From<AvatarData> for AvatarInfo { impl From<AvatarData> for AvatarInfo {
fn from(value: AvatarData) -> Self { fn from(value: AvatarData) -> Self {
Self { Self {

View file

@ -38,6 +38,7 @@ pub async fn on_get_player_token_req(
pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq) -> Result<()> { pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq) -> Result<()> {
session.player_info_mut().unlock_all_avatars(); session.player_info_mut().unlock_all_avatars();
session.player_info_mut().unlock_all_weapons();
let props = [ let props = [
(PROP_PLAYER_LEVEL, 5), (PROP_PLAYER_LEVEL, 5),
@ -83,11 +84,28 @@ pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq
.await?; .await?;
let player_info = session.player_info(); let player_info = session.player_info();
let player_store_notify = PlayerStoreNotify {
weight_limit: 30000,
store_type: StoreType::StorePack.into(),
item_list: player_info
.weapons
.clone()
.into_iter()
.map(Item::from)
.collect(),
};
session
.send(PLAYER_STORE_NOTIFY, player_store_notify)
.await?;
let avatar_data_notify = AvatarDataNotify { let avatar_data_notify = AvatarDataNotify {
avatar_list: player_info avatar_list: player_info
.avatars .avatars
.iter() .clone()
.map(|a| Into::<AvatarInfo>::into(a.clone())) .into_iter()
.map(AvatarInfo::from)
.collect(), .collect(),
cur_avatar_team_id: 1, cur_avatar_team_id: 1,
choose_avatar_guid: 228, choose_avatar_guid: 228,

View file

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use super::*; use super::*;
use crate::game::entity::Entity; use crate::game::entity::{Entity, SceneWeapon};
pub async fn on_change_avatar_req(session: &PlayerSession, body: &ChangeAvatarReq) -> Result<()> { pub async fn on_change_avatar_req(session: &PlayerSession, body: &ChangeAvatarReq) -> Result<()> {
let mut scene = session.context.scene.borrow_mut(); let mut scene = session.context.scene.borrow_mut();
@ -139,6 +139,70 @@ pub async fn on_avatar_wear_flycloak_req(
.await .await
} }
pub async fn on_wear_equip_req(session: &PlayerSession, body: &WearEquipReq) -> Result<()> {
let mut player = session.player_info_mut();
let weapon = player
.weapons
.iter()
.find(|w| w.guid == body.equip_guid)
.map(|w| w.clone());
let avatar = player
.avatars
.iter_mut()
.find(|a| a.guid == body.avatar_guid);
let (Some(weapon), Some(avatar)) = (weapon, avatar) else {
return session
.send(
WEAR_EQUIP_RSP,
WearEquipRsp {
retcode: -1,
..Default::default()
},
)
.await;
};
avatar.weapon = weapon;
session
.send(
AVATAR_EQUIP_CHANGE_NOTIFY,
AvatarEquipChangeNotify {
avatar_guid: body.avatar_guid,
equip_guid: body.equip_guid,
item_id: avatar.weapon.weapon_id,
equip_type: 6,
weapon: Some(SceneWeapon::new(0, avatar.weapon.clone()).scene_weapon_info()),
reliquary: None,
},
)
.await?;
let mut scene = session.context.scene.borrow_mut();
if let Some(avatar_entity) = scene
.avatars
.iter_mut()
.find(|a| a.avatar_guid() == body.avatar_guid)
{
avatar_entity.update_data(&avatar);
avatar_entity.change_weapon(avatar.weapon.clone());
}
session
.send(
WEAR_EQUIP_RSP,
WearEquipRsp {
retcode: 0,
equip_guid: body.equip_guid,
avatar_guid: body.avatar_guid,
},
)
.await
}
pub async fn on_set_up_avatar_team_req( pub async fn on_set_up_avatar_team_req(
session: &PlayerSession, session: &PlayerSession,
body: &SetUpAvatarTeamReq, body: &SetUpAvatarTeamReq,

View file

@ -140,4 +140,5 @@ trait_handler! {
GetSceneAreaReq 5114; GetSceneAreaReq 5114;
AvatarChangeCostumeReq 24368; AvatarChangeCostumeReq 24368;
AvatarWearFlycloakReq 27466; AvatarWearFlycloakReq 27466;
WearEquipReq 21829;
} }

File diff suppressed because it is too large Load diff

View file

@ -27,3 +27,6 @@ pub const AVATAR_CHANGE_COSTUME_RSP: u16 = 21748;
pub const AVATAR_CHANGE_COSTUME_NOTIFY: u16 = 8370; pub const AVATAR_CHANGE_COSTUME_NOTIFY: u16 = 8370;
pub const AVATAR_WEAR_FLYCLOAK_RSP: u16 = 25960; pub const AVATAR_WEAR_FLYCLOAK_RSP: u16 = 25960;
pub const AVATAR_FLYCLOAK_CHANGE_NOTIFY: u16 = 23818; pub const AVATAR_FLYCLOAK_CHANGE_NOTIFY: u16 = 23818;
pub const PLAYER_STORE_NOTIFY: u16 = 20155;
pub const WEAR_EQUIP_RSP: u16 = 9831;
pub const AVATAR_EQUIP_CHANGE_NOTIFY: u16 = 9280;