Implement WeaponLevelUp
This commit is contained in:
parent
a7a2747eba
commit
19b54b04df
5 changed files with 195 additions and 63 deletions
|
@ -7,7 +7,7 @@ pub use equip::EquipItem;
|
||||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
pub use weapon::WeaponItem;
|
pub use weapon::WeaponItem;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum EItemType {
|
pub enum EItemType {
|
||||||
Currency = 1,
|
Currency = 1,
|
||||||
|
@ -18,6 +18,7 @@ pub enum EItemType {
|
||||||
Equip = 7,
|
Equip = 7,
|
||||||
Buddy = 8,
|
Buddy = 8,
|
||||||
AvatarLevelUpMaterial = 12,
|
AvatarLevelUpMaterial = 12,
|
||||||
|
WeaponLevelUpMaterial = 13,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
#[derive(Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
||||||
|
|
|
@ -1664,6 +1664,23 @@ pub struct WeaponUnDressScRsp {
|
||||||
pub retcode: i32,
|
pub retcode: i32,
|
||||||
}
|
}
|
||||||
#[derive(Clone, PartialEq, ::proto_derive::Message, ::proto_derive::NetCmd)]
|
#[derive(Clone, PartialEq, ::proto_derive::Message, ::proto_derive::NetCmd)]
|
||||||
|
#[cmd_id(6184)]
|
||||||
|
pub struct WeaponLevelUpCsReq {
|
||||||
|
#[prost(uint32, tag = "15", xor = "9837")]
|
||||||
|
pub weapon_uid: u32,
|
||||||
|
#[prost(map = "uint32, uint32", tag = "4")]
|
||||||
|
pub exp_materials: ::std::collections::HashMap<u32, u32>,
|
||||||
|
}
|
||||||
|
#[derive(Clone, PartialEq, ::proto_derive::Message, ::proto_derive::NetCmd)]
|
||||||
|
#[derive(::proto_derive::NetResponse)]
|
||||||
|
#[cmd_id(9680)]
|
||||||
|
pub struct WeaponLevelUpScRsp {
|
||||||
|
#[prost(int32, tag = "3", xor = "8188")]
|
||||||
|
pub retcode: i32,
|
||||||
|
#[prost(message, repeated, tag = "5")]
|
||||||
|
pub return_item_list: ::prost::alloc::vec::Vec<ItemRewardInfo>,
|
||||||
|
}
|
||||||
|
#[derive(Clone, PartialEq, ::proto_derive::Message, ::proto_derive::NetCmd)]
|
||||||
#[cmd_id(3101)]
|
#[cmd_id(3101)]
|
||||||
pub struct TalentSwitchCsReq {
|
pub struct TalentSwitchCsReq {
|
||||||
#[prost(uint32, tag = "5", xor = "10791")]
|
#[prost(uint32, tag = "5", xor = "10791")]
|
||||||
|
|
|
@ -63,20 +63,11 @@ impl AvatarHandler {
|
||||||
item_util::use_item(context.player, id, count);
|
item_util::use_item(context.player, id, count);
|
||||||
});
|
});
|
||||||
|
|
||||||
let added_exp = request
|
let added_exp = item_util::materials_to_exp(
|
||||||
.exp_materials
|
&request.exp_materials,
|
||||||
.iter()
|
EItemType::AvatarLevelUpMaterial,
|
||||||
.filter_map(|(&id, &count)| {
|
context.resources,
|
||||||
let template = context
|
);
|
||||||
.resources
|
|
||||||
.templates
|
|
||||||
.item_template_tb()
|
|
||||||
.find(|tmpl| tmpl.id() == id)?;
|
|
||||||
|
|
||||||
(template.class() == EItemType::AvatarLevelUpMaterial.into())
|
|
||||||
.then(|| template.parameters().unwrap().get(0) * count)
|
|
||||||
})
|
|
||||||
.sum::<u32>();
|
|
||||||
|
|
||||||
let avatar = context
|
let avatar = context
|
||||||
.player
|
.player
|
||||||
|
@ -112,50 +103,24 @@ impl AvatarHandler {
|
||||||
avatar.level += 1;
|
avatar.level += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rsp = AvatarLevelUpScRsp::default();
|
AvatarLevelUpScRsp {
|
||||||
|
retcode: 0,
|
||||||
if avatar.level == max_level {
|
return_item_list: if avatar.level == max_level {
|
||||||
while avatar.exp > 0 {
|
item_util::exp_to_materials(
|
||||||
let Some(return_material) = context
|
&mut avatar.exp,
|
||||||
.resources
|
EItemType::AvatarLevelUpMaterial,
|
||||||
.templates
|
context.resources,
|
||||||
.item_template_tb()
|
)
|
||||||
.filter(|tmpl| {
|
.into_iter()
|
||||||
tmpl.class() == EItemType::AvatarLevelUpMaterial.into()
|
.map(|(item_id, amount)| {
|
||||||
&& tmpl.parameters().unwrap().get(0) <= avatar.exp
|
item_util::add_item(context.player, item_id, amount);
|
||||||
})
|
ItemRewardInfo { item_id, amount }
|
||||||
.max_by_key(|tmpl| tmpl.parameters().unwrap().get(0))
|
})
|
||||||
else {
|
.collect()
|
||||||
avatar.exp = 0;
|
} else {
|
||||||
break;
|
Vec::new()
|
||||||
};
|
},
|
||||||
|
|
||||||
let exp_amount = return_material.parameters().unwrap().get(0);
|
|
||||||
|
|
||||||
rsp.return_item_list.push(ItemRewardInfo {
|
|
||||||
item_id: return_material.id(),
|
|
||||||
amount: avatar.exp / exp_amount,
|
|
||||||
});
|
|
||||||
|
|
||||||
let cur = context
|
|
||||||
.player
|
|
||||||
.item_model
|
|
||||||
.item_count_map
|
|
||||||
.get(&return_material.id())
|
|
||||||
.copied()
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
context
|
|
||||||
.player
|
|
||||||
.item_model
|
|
||||||
.item_count_map
|
|
||||||
.insert(return_material.id(), cur + (avatar.exp / exp_amount) as i32);
|
|
||||||
|
|
||||||
avatar.exp %= exp_amount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rsp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_weapon_dress_cs_req(
|
pub fn on_weapon_dress_cs_req(
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
use yixuan_codegen::{handlers, required_state};
|
use yixuan_codegen::{handlers, required_state};
|
||||||
|
use yixuan_logic::item::EItemType;
|
||||||
use yixuan_proto::{
|
use yixuan_proto::{
|
||||||
GetEquipDataCsReq, GetEquipDataScRsp, GetItemDataCsReq, GetItemDataScRsp, GetWeaponDataCsReq,
|
GetEquipDataCsReq, GetEquipDataScRsp, GetItemDataCsReq, GetItemDataScRsp, GetWeaponDataCsReq,
|
||||||
GetWeaponDataScRsp, GetWishlistDataCsReq, GetWishlistDataScRsp,
|
GetWeaponDataScRsp, GetWishlistDataCsReq, GetWishlistDataScRsp, ItemRewardInfo,
|
||||||
|
WeaponLevelUpCsReq, WeaponLevelUpScRsp,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::sync::SyncType;
|
use crate::{sync::SyncType, util::item_util};
|
||||||
|
|
||||||
use super::NetContext;
|
use super::NetContext;
|
||||||
|
|
||||||
|
@ -55,4 +57,103 @@ impl ItemHandler {
|
||||||
.sync_helper
|
.sync_helper
|
||||||
.remove_sync_response(SyncType::BasicData)
|
.remove_sync_response(SyncType::BasicData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_weapon_level_up_cs_req(
|
||||||
|
context: &mut NetContext,
|
||||||
|
request: WeaponLevelUpCsReq,
|
||||||
|
) -> WeaponLevelUpScRsp {
|
||||||
|
if !context
|
||||||
|
.player
|
||||||
|
.item_model
|
||||||
|
.weapon_map
|
||||||
|
.contains_key(&request.weapon_uid)
|
||||||
|
{
|
||||||
|
return WeaponLevelUpScRsp {
|
||||||
|
retcode: 1,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if !request
|
||||||
|
.exp_materials
|
||||||
|
.iter()
|
||||||
|
.all(|(&id, &count)| item_util::has_enough_items(context.player, id, count))
|
||||||
|
{
|
||||||
|
return WeaponLevelUpScRsp {
|
||||||
|
retcode: 1,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
request.exp_materials.iter().for_each(|(&id, &count)| {
|
||||||
|
item_util::use_item(context.player, id, count);
|
||||||
|
});
|
||||||
|
|
||||||
|
let added_exp = item_util::materials_to_exp(
|
||||||
|
&request.exp_materials,
|
||||||
|
EItemType::WeaponLevelUpMaterial,
|
||||||
|
context.resources,
|
||||||
|
);
|
||||||
|
|
||||||
|
let weapon = context
|
||||||
|
.player
|
||||||
|
.item_model
|
||||||
|
.weapon_map
|
||||||
|
.get_mut(&request.weapon_uid)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
weapon.exp += added_exp;
|
||||||
|
|
||||||
|
let weapon_rarity = context
|
||||||
|
.resources
|
||||||
|
.templates
|
||||||
|
.item_template_tb()
|
||||||
|
.find(|tmpl| tmpl.id() == weapon.id)
|
||||||
|
.map(|tmpl| tmpl.rarity())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let max_level = context
|
||||||
|
.resources
|
||||||
|
.templates
|
||||||
|
.weapon_star_template_tb()
|
||||||
|
.find(|tmpl| tmpl.rarity() == weapon_rarity && tmpl.star() == weapon.star)
|
||||||
|
.unwrap()
|
||||||
|
.max_level();
|
||||||
|
|
||||||
|
while weapon.level < max_level {
|
||||||
|
let required_exp = context
|
||||||
|
.resources
|
||||||
|
.templates
|
||||||
|
.weapon_level_template_tb()
|
||||||
|
.find(|tmpl| tmpl.rarity() == weapon_rarity && tmpl.level() == weapon.level)
|
||||||
|
.unwrap()
|
||||||
|
.exp();
|
||||||
|
|
||||||
|
if weapon.exp < required_exp {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
weapon.exp -= required_exp;
|
||||||
|
weapon.level += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeaponLevelUpScRsp {
|
||||||
|
retcode: 0,
|
||||||
|
return_item_list: if weapon.level == max_level {
|
||||||
|
item_util::exp_to_materials(
|
||||||
|
&mut weapon.exp,
|
||||||
|
EItemType::WeaponLevelUpMaterial,
|
||||||
|
context.resources,
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(item_id, amount)| {
|
||||||
|
item_util::add_item(context.player, item_id, amount);
|
||||||
|
ItemRewardInfo { item_id, amount }
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use config::WeaponTemplate;
|
use config::WeaponTemplate;
|
||||||
use rand::{RngCore, seq::IteratorRandom};
|
use rand::{RngCore, seq::IteratorRandom};
|
||||||
use yixuan_logic::item::WeaponItem;
|
use yixuan_logic::item::{EItemType, WeaponItem};
|
||||||
|
|
||||||
use crate::player::Player;
|
use crate::{player::Player, resources::NapResources};
|
||||||
|
|
||||||
pub fn add_items_on_first_login(player: &mut Player) {
|
pub fn add_items_on_first_login(player: &mut Player) {
|
||||||
player.item_model.item_count_map.insert(10, 10_000_000);
|
player.item_model.item_count_map.insert(10, 10_000_000);
|
||||||
|
@ -139,7 +139,7 @@ pub fn add_weapon(player: &mut Player, template: &WeaponTemplate) -> u32 {
|
||||||
id: template.item_id(),
|
id: template.item_id(),
|
||||||
level: 0,
|
level: 0,
|
||||||
exp: 0,
|
exp: 0,
|
||||||
star: 1,
|
star: 0,
|
||||||
refine_level: 0,
|
refine_level: 0,
|
||||||
lock: false,
|
lock: false,
|
||||||
},
|
},
|
||||||
|
@ -190,3 +190,51 @@ pub fn use_item(player: &mut Player, item_id: u32, amount: u32) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn materials_to_exp(
|
||||||
|
materials: &HashMap<u32, u32>,
|
||||||
|
material_type: EItemType,
|
||||||
|
res: &NapResources,
|
||||||
|
) -> u32 {
|
||||||
|
materials
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(&id, &count)| {
|
||||||
|
let template = res
|
||||||
|
.templates
|
||||||
|
.item_template_tb()
|
||||||
|
.find(|tmpl| tmpl.id() == id)?;
|
||||||
|
|
||||||
|
(template.class() == material_type.into())
|
||||||
|
.then(|| template.parameters().unwrap().get(0) * count)
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exp_to_materials(
|
||||||
|
exp: &mut u32,
|
||||||
|
material_type: EItemType,
|
||||||
|
res: &NapResources,
|
||||||
|
) -> HashMap<u32, u32> {
|
||||||
|
let mut materials = HashMap::new();
|
||||||
|
|
||||||
|
while *exp > 0 {
|
||||||
|
let Some(return_material) = res
|
||||||
|
.templates
|
||||||
|
.item_template_tb()
|
||||||
|
.filter(|tmpl| {
|
||||||
|
tmpl.class() == material_type.into() && tmpl.parameters().unwrap().get(0) <= *exp
|
||||||
|
})
|
||||||
|
.max_by_key(|tmpl| tmpl.parameters().unwrap().get(0))
|
||||||
|
else {
|
||||||
|
*exp = 0;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
let exp_amount = return_material.parameters().unwrap().get(0);
|
||||||
|
materials.insert(return_material.id(), *exp / exp_amount);
|
||||||
|
|
||||||
|
*exp %= exp_amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
materials
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue