diff --git a/crates/game-server/src/logic/player/equip.rs b/crates/game-server/src/logic/player/equip.rs index 5808f5e..dc83205 100644 --- a/crates/game-server/src/logic/player/equip.rs +++ b/crates/game-server/src/logic/player/equip.rs @@ -31,6 +31,23 @@ impl EquipModel { self.weapons.contains_key(&uid) } + pub fn is_signature_weapon(&self, uid: i32, avatar_id: i32) -> bool { + self.weapons + .get(&uid) + .map_or( + false, + |weapon| self.context.filecfg.weapon_template_tb + .data() + .unwrap() + .iter() + .find(|tmpl| tmpl.item_id() == weapon.weapon_id) + .map_or( + false, + |tmpl| tmpl.avatar_id() == avatar_id + ) + ) + } + pub fn equipment_exists(&self, uid: i32) -> bool { self.equipment.contains_key(&uid) } diff --git a/crates/game-server/src/logic/player/role.rs b/crates/game-server/src/logic/player/role.rs index bfcae10..f4c1719 100644 --- a/crates/game-server/src/logic/player/role.rs +++ b/crates/game-server/src/logic/player/role.rs @@ -34,7 +34,12 @@ impl RoleModel { } } - pub async fn weapon_dress(&mut self, avatar_id: u32, weapon_uid: i32) -> Option<[u32; 2]> { + pub async fn weapon_dress( + &mut self, + avatar_id: u32, + weapon_uid: i32, + is_signature_weapon: bool, + ) -> Option<[u32; 2]> { if !self.avatar_map.contains_key(&avatar_id) { return None; } @@ -59,10 +64,17 @@ impl RoleModel { let prev_weapon = avatar.cur_weapon_uid; updated_avatars[0] = avatar.avatar_id as u32; + let show_weapon_type = if is_signature_weapon { + 1 + } else { + avatar.show_weapon_type + }; + self.avatar_map.insert( avatar.avatar_id as u32, avatar::ActiveModel { cur_weapon_uid: Set(weapon_uid), + show_weapon_type: Set(show_weapon_type), ..avatar.into() } .update(self.context.database) @@ -222,6 +234,28 @@ impl RoleModel { false } + pub async fn toggle_weapon_show(&mut self, avatar_id: u32, show_weapon_type: i16) -> bool { + let Some(mut avatar) = self.avatar_map.remove(&avatar_id) else { + return false; + }; + + avatar + .show_weapon_type = show_weapon_type; + + self.avatar_map.insert( + avatar_id, + avatar::ActiveModel { + show_weapon_type: Set(show_weapon_type), + ..avatar.into() + } + .update(self.context.database) + .await + .expect("avatar::update failed"), + ); + + true + } + pub async fn change_avatar_properties( &mut self, changes: AvatarPropertyChanges, @@ -331,7 +365,7 @@ impl RoleModel { cur_weapon_uid: 0, taken_rank_up_reward_list: Vec::with_capacity(0), first_get_time: time_util::cur_timestamp_seconds(), - show_weapon_type: 0, + show_weapon_type: 1, avatar_skin_id: 0, equip_slot_list: Vec::with_capacity(0), }) @@ -446,7 +480,7 @@ impl RoleModel { cur_weapon_uid: 0, taken_rank_up_reward_list: Vec::with_capacity(0), first_get_time: time_util::cur_timestamp_seconds(), - show_weapon_type: 0, + show_weapon_type: 1, avatar_skin_id: 0, equip_slot_list: Vec::with_capacity(0), }, diff --git a/crates/game-server/src/session/message/avatar.rs b/crates/game-server/src/session/message/avatar.rs index 4b872a3..2982afb 100644 --- a/crates/game-server/src/session/message/avatar.rs +++ b/crates/game-server/src/session/message/avatar.rs @@ -29,7 +29,11 @@ mod avatar_module { if equip_model.weapon_exists(request.weapon_uid as i32) { if let Some(updated_avatars) = role_model - .weapon_dress(request.avatar_id, request.weapon_uid as i32) + .weapon_dress( + request.avatar_id, + request.weapon_uid as i32, + equip_model.is_signature_weapon(request.weapon_uid as i32, request.avatar_id as i32) + ) .await { let avatar_list = role_model.get_protocol_avatar_list(&updated_avatars); @@ -51,7 +55,7 @@ mod avatar_module { ) -> WeaponUnDressScRsp { let role_model = &mut context.player.role_model; - if let Some(updated_avatars) = role_model.weapon_dress(request.avatar_id, 0).await { + if let Some(updated_avatars) = role_model.weapon_dress(request.avatar_id, 0, false).await { let avatar_list = role_model.get_protocol_avatar_list(&updated_avatars); context.add_notify(PlayerSyncScNotify { avatar_sync: Some(AvatarSync { avatar_list }), @@ -168,4 +172,26 @@ mod avatar_module { TalentSwitchScRsp { retcode: 1 } } + + pub async fn on_toggle_weapon_show( + context: &mut MessageContext<'_, '_>, + request: ToggleWeaponShowCsReq, + ) -> ToggleWeaponShowScRsp { + let role_model = &mut context.player.role_model; + + if role_model + .toggle_weapon_show(request.avatar_id, request.show_weapon_type as i16) + .await + { + let avatar_list = role_model.get_protocol_avatar_list(&[request.avatar_id]); + context.add_notify(PlayerSyncScNotify { + avatar_sync: Some(AvatarSync { avatar_list }), + ..Default::default() + }); + + return ToggleWeaponShowScRsp { retcode: 0 }; + } + + ToggleWeaponShowScRsp { retcode: 1 } + } } diff --git a/crates/trigger-protobuf/out/_.rs b/crates/trigger-protobuf/out/_.rs index 77b2857..44a52bf 100644 --- a/crates/trigger-protobuf/out/_.rs +++ b/crates/trigger-protobuf/out/_.rs @@ -1454,6 +1454,17 @@ pub struct TalentSwitchCsReq { pub talent_switch_list: ::prost::alloc::vec::Vec, } #[derive(trigger_protobuf_derive::CmdID)] +#[cmdid(1981)] +#[derive(trigger_protobuf_derive::XorFields)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct ToggleWeaponShowCsReq { + #[prost(enumeration = "AvatarShowWeaponType", tag = "2")] + pub show_weapon_type: i32, + #[xor(3418)] + #[prost(uint32, tag = "4")] + pub avatar_id: u32, +} +#[derive(trigger_protobuf_derive::CmdID)] #[derive(trigger_protobuf_derive::XorFields)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AbyssGroup { diff --git a/crates/trigger-protobuf/out/protocol_map.rs b/crates/trigger-protobuf/out/protocol_map.rs index 429c215..a9658ff 100644 --- a/crates/trigger-protobuf/out/protocol_map.rs +++ b/crates/trigger-protobuf/out/protocol_map.rs @@ -819,6 +819,14 @@ pub fn pb_to_common_protocol_unit( ); Ok(Some(common_protocol_message.into())) } + ToggleWeaponShowCsReq::CMD_ID => { + let mut pb_message = ToggleWeaponShowCsReq::decode(pb)?; + pb_message.xor_fields(); + let common_protocol_message = ::trigger_protocol::ToggleWeaponShowCsReq::from( + pb_message, + ); + Ok(Some(common_protocol_message.into())) + } GetEquipDataScRsp::CMD_ID => { let mut pb_message = GetEquipDataScRsp::decode(pb)?; pb_message.xor_fields(); @@ -1970,6 +1978,14 @@ pub fn common_protocol_unit_to_pb( pb_message.xor_fields(); Ok(Some((TalentSwitchCsReq::CMD_ID, pb_message.encode_to_vec()))) } + ::trigger_protocol::ToggleWeaponShowCsReq::CMD_ID => { + let common_protocol_message = ::trigger_protocol::ToggleWeaponShowCsReq::decode( + &mut ::std::io::Cursor::new(&unit.blob), + )?; + let mut pb_message = ToggleWeaponShowCsReq::from(common_protocol_message); + pb_message.xor_fields(); + Ok(Some((ToggleWeaponShowCsReq::CMD_ID, pb_message.encode_to_vec()))) + } ::trigger_protocol::GetEquipDataScRsp::CMD_ID => { let common_protocol_message = ::trigger_protocol::GetEquipDataScRsp::decode( &mut ::std::io::Cursor::new(&unit.blob), @@ -4916,6 +4932,26 @@ impl From<::trigger_protocol::TalentSwitchCsReq> for TalentSwitchCsReq { } } #[allow(unused)] +impl From for ::trigger_protocol::ToggleWeaponShowCsReq { + fn from(value: ToggleWeaponShowCsReq) -> Self { + Self { + show_weapon_type: value.show_weapon_type.into(), + avatar_id: value.avatar_id.into(), + ..Default::default() + } + } +} +#[allow(unused)] +impl From<::trigger_protocol::ToggleWeaponShowCsReq> for ToggleWeaponShowCsReq { + fn from(value: ::trigger_protocol::ToggleWeaponShowCsReq) -> Self { + Self { + show_weapon_type: value.show_weapon_type.into(), + avatar_id: value.avatar_id.into(), + ..Default::default() + } + } +} +#[allow(unused)] impl From for ::trigger_protocol::AbyssGroup { fn from(value: AbyssGroup) -> Self { Self { ..Default::default() } diff --git a/crates/trigger-protocol/src/lib.rs b/crates/trigger-protocol/src/lib.rs index ead5c4a..5367db7 100644 --- a/crates/trigger-protocol/src/lib.rs +++ b/crates/trigger-protocol/src/lib.rs @@ -953,6 +953,19 @@ pub struct DressEquipmentSuitScRsp { pub retcode: i32, } +#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)] +#[id(815)] +pub struct ToggleWeaponShowCsReq { + pub show_weapon_type: i32, + pub avatar_id: u32, +} + +#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)] +#[id(816)] +pub struct ToggleWeaponShowScRsp { + pub retcode: i32, +} + #[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)] #[id(840)] pub struct GetAvatarRecommendEquipCsReq {