use crate::logic::components::{Equip, WeaponSkin}; use crate::logic::ecs::component::ComponentContainer; use crate::logic::player::Player; use crate::logic::thread_mgr::NetContext; use crate::modify_component; use wicked_waifus_protocol::{ EntityEquipChangeNotify, EntityEquipSkinChangeNotify, EquipComponentPb, EquipTakeOnNotify, EquipTakeOnRequest, EquipTakeOnResponse, EquipWeaponSkinRequest, EquipWeaponSkinResponse, ErrorCode, LoadEquipData, SendEquipSkinRequest, SendEquipSkinResponse, WeaponSkinComponentPb, WeaponSkinDeleteNotify, WeaponSkinRequest, WeaponSkinResponse, }; pub fn on_weapon_skin_request( ctx: &NetContext, _request: WeaponSkinRequest, response: &mut WeaponSkinResponse, ) { response.equip_list = get_player_weapons(ctx.player); response.error_code = ErrorCode::Success.into(); } pub fn on_equip_weapon_skin_request( ctx: &mut NetContext, request: EquipWeaponSkinRequest, response: &mut EquipWeaponSkinResponse, ) { let Some(equip_data) = request.data else { return; }; let role = ctx.player.role_list.get_mut(&equip_data.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; }; // Verify Id exist in bindata let Some(skin_data) = wicked_waifus_data::weapon_skin_data::iter().find(|data| data.id == equip_data.skin_id) else { response.error_code = ErrorCode::WeaponSkinDataErr.into(); return; }; // Verify Skin is unlocked if !ctx .player .unlocked_skins .weapon_skins .contains(&skin_data.id) { response.error_code = ErrorCode::WeaponSkinUnLockErr.into(); return; } role.weapon_skin_id = equip_data.skin_id; let world = ctx.world.get_world_entity(); let entity_id = world.get_entity_id(equip_data.role_id); modify_component!( world.get_entity_components(entity_id as i32), WeaponSkin, |skin_component: &mut WeaponSkin| { skin_component.skin_id = equip_data.skin_id; } ); ctx.player.notify(EntityEquipSkinChangeNotify { entity_id, weapon_skin_component_pb: Some(WeaponSkinComponentPb { weapon_skin_id: equip_data.skin_id, }), }); // Is the all list needed or only the new one?? response.data_list = get_player_weapons(ctx.player); response.error_code = ErrorCode::Success.into(); } pub fn on_send_equip_skin_request( ctx: &mut NetContext, request: SendEquipSkinRequest, response: &mut SendEquipSkinResponse, ) { let role = ctx.player.role_list.get_mut(&request.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; }; let old_skin_id = role.weapon_skin_id; role.weapon_skin_id = 0; let world = ctx.world.get_world_entity(); let entity_id = world.get_entity_id(request.role_id); modify_component!( world.get_entity_components(entity_id as i32), WeaponSkin, |skin_component: &mut WeaponSkin| { skin_component.skin_id = 0; } ); ctx.player.notify(EntityEquipSkinChangeNotify { entity_id, weapon_skin_component_pb: Some(WeaponSkinComponentPb { weapon_skin_id: 0 }), }); ctx.player.notify(WeaponSkinDeleteNotify { role_id: request.role_id, skin_id: old_skin_id, }); response.error_code = ErrorCode::Success.into(); } pub fn on_equip_take_on_request( ctx: &mut NetContext, request: EquipTakeOnRequest, response: &mut EquipTakeOnResponse, ) { let Some(equip_data) = request.data else { return; }; // TODO: Add sanity checks(add from another role, a.k.a.: switch from roles) ctx.player.notify(EquipTakeOnNotify { data_list: vec![equip_data], }); let role = ctx.player.role_list.get_mut(&equip_data.role_id); let Some(role) = role else { response.error_code = ErrorCode::NotValidRole.into(); return; }; let Some((id, breach)) = ctx .player .inventory .get_weapon_equip_info(equip_data.equip_inc_id) else { response.error_code = ErrorCode::ErrItemNotFound.into(); return; }; role.equip_weapon = id; // TODO: Change attributes based on weapon (PbRolePropsNotify + buffs + CombatNotifyAttributeChangedNotify) // TODO: remove from old one if in scene in case of weapon switch let world = ctx.world.get_world_entity(); let entity_id = world.get_entity_id(equip_data.role_id); modify_component!( world.get_entity_components(entity_id as i32), Equip, |equip_component: &mut Equip| { equip_component.weapon_id = id; equip_component.weapon_breach_level = breach; } ); ctx.player.notify(EntityEquipChangeNotify { entity_id, equip_component: Some(EquipComponentPb { weapon_id: id, weapon_breach_level: breach, }), }); // TODO: Should we return all of them?? response.data_list = vec![equip_data]; response.error_code = ErrorCode::Success.into(); } #[inline(always)] fn get_player_weapons(player: &Player) -> Vec { player .role_list .values() .filter(|role| role.weapon_skin_id != 0) .map(|role| LoadEquipData { role_id: role.role_id, skin_id: role.weapon_skin_id, }) .collect() }