Add property calculations
This commit is contained in:
parent
f89b49f903
commit
60b3523f0c
12 changed files with 4469 additions and 48 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3599,6 +3599,7 @@ name = "trigger-battle-server"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"dashmap 6.1.0",
|
||||
"num_enum",
|
||||
"paste",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
@ -6,6 +6,7 @@ version.workspace = true
|
|||
[dependencies]
|
||||
tokio.workspace = true
|
||||
|
||||
num_enum.workspace = true
|
||||
paste.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use trigger_protocol::DungeonEquipInfo;
|
||||
|
||||
pub struct AvatarUnit {
|
||||
pub avatar_id: u32,
|
||||
pub properties: HashMap<u32, i32>,
|
||||
}
|
||||
|
||||
pub struct BuddyUnit {
|
||||
|
@ -29,6 +32,7 @@ impl Dungeon {
|
|||
.iter()
|
||||
.map(|unit| AvatarUnitInfo {
|
||||
avatar_id: unit.avatar_id,
|
||||
properties: unit.properties.clone(),
|
||||
})
|
||||
.collect(),
|
||||
buddy_list: self
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
mod dungeon;
|
||||
mod property_util;
|
||||
|
||||
pub use dungeon::*;
|
||||
pub mod scene;
|
||||
|
@ -39,7 +40,10 @@ impl GameState {
|
|||
quest_id: *quest_id,
|
||||
avatar_list: avatar_id_list
|
||||
.iter()
|
||||
.map(|&avatar_id| AvatarUnit { avatar_id })
|
||||
.map(|&avatar_id| AvatarUnit {
|
||||
avatar_id,
|
||||
properties: property_util::calculate_for_avatar(avatar_id, filecfg, dungeon_equip),
|
||||
})
|
||||
.collect(),
|
||||
buddy_list: vec![BuddyUnit {
|
||||
buddy_type: 0,
|
||||
|
@ -71,7 +75,10 @@ impl GameState {
|
|||
quest_id: *quest_id,
|
||||
avatar_list: avatar_id_list
|
||||
.iter()
|
||||
.map(|&avatar_id| AvatarUnit { avatar_id })
|
||||
.map(|&avatar_id| AvatarUnit {
|
||||
avatar_id,
|
||||
properties: property_util::calculate_for_avatar(avatar_id, filecfg, dungeon_equip),
|
||||
})
|
||||
.collect(),
|
||||
buddy_list: vec![BuddyUnit {
|
||||
buddy_type: 0,
|
||||
|
|
565
crates/battle-server/src/logic/property_util.rs
Normal file
565
crates/battle-server/src/logic/property_util.rs
Normal file
|
@ -0,0 +1,565 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use trigger_fileconfig::{AvatarBattleTemplate, AvatarLevelAdvanceTemplate, AvatarPassiveSkillTemplate, NapFileCfg, WeaponLevelTemplate, WeaponStarTemplate, WeaponTemplate};
|
||||
use trigger_logic::skill::EAvatarSkillType;
|
||||
use trigger_protocol::{Avatar, DungeonEquipInfo, Equip, Weapon};
|
||||
|
||||
struct AvatarFileCfg<'a> {
|
||||
pub avatar_battle_template: AvatarBattleTemplate<'a>,
|
||||
pub avatar_passive_skill_templates: Vec<AvatarPassiveSkillTemplate<'a>>,
|
||||
pub avatar_level_advances: Vec<AvatarLevelAdvanceTemplate<'a>>,
|
||||
}
|
||||
|
||||
struct WeaponFileCfg<'a> {
|
||||
pub weapon_template: WeaponTemplate<'a>,
|
||||
pub weapon_level_template: WeaponLevelTemplate<'a>,
|
||||
pub weapon_star_template: WeaponStarTemplate<'a>,
|
||||
}
|
||||
|
||||
const BEN_AVATAR_ID: u32 = 1121;
|
||||
const BEN_CORE_PASSIVE_PERCENTAGE: [i32;7] = [40, 46, 52, 60, 66, 72, 80];
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(num_enum::IntoPrimitive, num_enum::TryFromPrimitive)]
|
||||
pub enum EPropertyType {
|
||||
HpMax = 111,
|
||||
Atk = 121,
|
||||
BreakStun = 122,
|
||||
Def = 131,
|
||||
Crit = 201,
|
||||
CritDmg = 211,
|
||||
Pen = 231,
|
||||
PenValue = 232,
|
||||
SpRecover = 305,
|
||||
ElementMystery = 312,
|
||||
ElementAbnormalPower = 314,
|
||||
AddedDamageRatioPhysics = 315,
|
||||
AddedDamageRatioFire = 316,
|
||||
AddedDamageRatioIce = 317,
|
||||
AddedDamageRatioElec = 318,
|
||||
AddedDamageRatioEther = 319,
|
||||
// battle
|
||||
HpMaxBattle = 1111,
|
||||
AtkBattle = 1121,
|
||||
BreakStunBattle = 1122,
|
||||
DefBattle = 1131,
|
||||
CritBattle = 1201,
|
||||
CritDmgBattle = 1211,
|
||||
PenRatioBattle = 1231,
|
||||
PenDeltaBattle = 1232,
|
||||
SpRecoverBattle = 1305,
|
||||
ElementMysteryBattle = 1312,
|
||||
ElementAbnormalPowerBattle = 1314,
|
||||
AddedDamageRatioPhysicsBattle = 1315,
|
||||
AddedDamageRatioFireBattle = 1316,
|
||||
AddedDamageRatioIceBattle = 1317,
|
||||
AddedDamageRatioElecBattle = 1318,
|
||||
AddedDamageRatioEtherBattle = 1319,
|
||||
// base
|
||||
HpMaxBase = 11101,
|
||||
AtkBase = 12101,
|
||||
BreakStunBase = 12201,
|
||||
DefBase = 13101,
|
||||
CritBase = 20101,
|
||||
CritDmgBase = 21101,
|
||||
PenBase = 23101,
|
||||
PenValueBase = 23201,
|
||||
SpRecoverBase = 30501,
|
||||
ElementMysteryBase = 31201,
|
||||
ElementAbnormalPowerBase = 31401,
|
||||
// ratio
|
||||
HpMaxRatio = 11102,
|
||||
AtkRatio = 12102,
|
||||
BreakStunRatio = 12202,
|
||||
DefRatio = 13102,
|
||||
SpRecoverRatio = 30502,
|
||||
ElementAbnormalPowerRatio = 31402,
|
||||
// delta
|
||||
HpMaxDelta = 11103,
|
||||
AtkDelta = 12103,
|
||||
BreakStunDelta = 12203,
|
||||
DefDelta = 13103,
|
||||
CritDelta = 20103,
|
||||
CritDmgDelta = 21103,
|
||||
PenDelta = 23103,
|
||||
PenValueDelta = 23203,
|
||||
SpRecoverDelta = 30503,
|
||||
ElementMysteryDelta = 31203,
|
||||
ElementAbnormalPowerDelta = 31403,
|
||||
// damage ratios 1/3
|
||||
AddedDamageRatioPhysics1 = 31501,
|
||||
AddedDamageRatioPhysics3 = 31503,
|
||||
AddedDamageRatioFire1 = 31601,
|
||||
AddedDamageRatioFire3 = 31603,
|
||||
AddedDamageRatioIce1 = 31701,
|
||||
AddedDamageRatioIce3 = 31703,
|
||||
AddedDamageRatioElec1 = 31801,
|
||||
AddedDamageRatioElec3 = 31803,
|
||||
AddedDamageRatioEther1 = 31901,
|
||||
AddedDamageRatioEther3 = 31903,
|
||||
// --- custom
|
||||
// growth
|
||||
HpMaxGrowth = 9999_111_0,
|
||||
AtkGrowth = 9999_121_0,
|
||||
DefGrowth = 9999_131_0,
|
||||
// advance
|
||||
HpMaxAdvance = 9999_111_1,
|
||||
AtkAdvance = 9999_121_1,
|
||||
DefAdvance = 9999_131_1,
|
||||
}
|
||||
|
||||
pub fn calculate_for_avatar(
|
||||
avatar_id: u32,
|
||||
filecfg: &'static NapFileCfg,
|
||||
dungeon_equip: &DungeonEquipInfo,
|
||||
) -> HashMap<u32, i32> {
|
||||
let mut calculated_properties = HashMap::<_, _>::new();
|
||||
let Some(player_avatar) = dungeon_equip.avatar_list.iter().find(|a| (*a).id == avatar_id) else { return calculated_properties; };
|
||||
let Some(avatar_file_cfg) = get_avatar_filecfg(avatar_id, filecfg) else { return calculated_properties; };
|
||||
insert_avatar_battle_template_properties(&avatar_file_cfg, &mut calculated_properties);
|
||||
insert_avatar_battle_level_advance_properties(&avatar_file_cfg, player_avatar, &mut calculated_properties);
|
||||
perform_avatar_growth_promotion_calculations(player_avatar, &mut calculated_properties);
|
||||
add_avatar_passive_skill_properties(&avatar_file_cfg, player_avatar, &mut calculated_properties);
|
||||
let player_weapon = dungeon_equip.weapon_list.iter().find(|w| w.uid == player_avatar.cur_weapon_uid);
|
||||
if player_weapon.is_some() {
|
||||
match get_weapon_filecfg(player_weapon.unwrap(), filecfg) {
|
||||
Some(weapon_file_cfg) => {
|
||||
add_weapon_template_properties(&weapon_file_cfg, &mut calculated_properties);
|
||||
},
|
||||
None => {},
|
||||
};
|
||||
}
|
||||
let player_dressed_equip_uids: Vec<u32> = player_avatar.dressed_equip_list.iter().map(|de| de.equip_uid).collect();
|
||||
let player_equips: Vec<&Equip> = dungeon_equip.equip_list.iter().filter(|e| player_dressed_equip_uids.contains(&e.uid)).collect();
|
||||
if player_equips.len() > 0 {
|
||||
add_player_equip_properties(&player_equips, filecfg, &mut calculated_properties);
|
||||
add_equipment_suit_properties(&player_equips, filecfg, &mut calculated_properties);
|
||||
}
|
||||
calculate_final_properties(&mut calculated_properties);
|
||||
add_ben_core_passive(avatar_id, player_avatar, &mut calculated_properties);
|
||||
remove_custom_properties(&mut calculated_properties);
|
||||
set_battle_properties(&mut calculated_properties);
|
||||
|
||||
calculated_properties
|
||||
}
|
||||
|
||||
fn get_avatar_filecfg(
|
||||
avatar_id: u32,
|
||||
filecfg: &'static NapFileCfg,
|
||||
) -> Option<AvatarFileCfg<'static>> {
|
||||
let Some(avatar_battle_template) = filecfg.avatar_battle_template_tb().data().unwrap()
|
||||
.iter()
|
||||
.find(|tmpl| tmpl.id() == avatar_id as i32)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let avatar_passive_skill_templates: Vec<AvatarPassiveSkillTemplate> = filecfg.avatar_passive_skill_template_tb().data().unwrap()
|
||||
.iter()
|
||||
.filter(|tmpl| tmpl.avatar_id() == avatar_id as i32)
|
||||
.collect();
|
||||
if avatar_passive_skill_templates.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let avatar_level_advances: Vec<AvatarLevelAdvanceTemplate> = filecfg.avatar_level_advance_template_tb().data().unwrap()
|
||||
.iter()
|
||||
.filter(|tmpl| tmpl.avatar_id() == avatar_id as i32)
|
||||
.collect();
|
||||
if avatar_level_advances.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(AvatarFileCfg {
|
||||
avatar_battle_template,
|
||||
avatar_passive_skill_templates,
|
||||
avatar_level_advances,
|
||||
})
|
||||
}
|
||||
|
||||
fn insert_avatar_battle_template_properties(
|
||||
avatar_file_cfg: &AvatarFileCfg,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
properties.insert(EPropertyType::HpMaxBase.into(), avatar_file_cfg.avatar_battle_template.hp_max());
|
||||
properties.insert(EPropertyType::HpMaxGrowth.into(), avatar_file_cfg.avatar_battle_template.health_growth());
|
||||
properties.insert(EPropertyType::AtkBase.into(), avatar_file_cfg.avatar_battle_template.attack());
|
||||
properties.insert(EPropertyType::AtkGrowth.into(), avatar_file_cfg.avatar_battle_template.attack_growth());
|
||||
properties.insert(EPropertyType::BreakStunBase.into(), avatar_file_cfg.avatar_battle_template.break_stun());
|
||||
properties.insert(EPropertyType::DefBase.into(), avatar_file_cfg.avatar_battle_template.defence());
|
||||
properties.insert(EPropertyType::DefGrowth.into(), avatar_file_cfg.avatar_battle_template.defence_growth());
|
||||
properties.insert(EPropertyType::CritBase.into(), avatar_file_cfg.avatar_battle_template.crit());
|
||||
properties.insert(EPropertyType::CritDmgBase.into(), avatar_file_cfg.avatar_battle_template.crit_damage());
|
||||
properties.insert(EPropertyType::PenBase.into(), avatar_file_cfg.avatar_battle_template.pen_rate());
|
||||
properties.insert(EPropertyType::PenValueBase.into(), avatar_file_cfg.avatar_battle_template.pen_delta());
|
||||
properties.insert(EPropertyType::SpRecoverBase.into(), avatar_file_cfg.avatar_battle_template.sp_recover());
|
||||
properties.insert(EPropertyType::ElementMysteryBase.into(), avatar_file_cfg.avatar_battle_template.element_mystery());
|
||||
properties.insert(EPropertyType::ElementAbnormalPowerBase.into(), avatar_file_cfg.avatar_battle_template.element_abnormal_power());
|
||||
}
|
||||
|
||||
fn insert_avatar_battle_level_advance_properties(
|
||||
avatar_file_cfg: &AvatarFileCfg,
|
||||
player_avatar: &Avatar,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
let Some(avatar_level_advance) = avatar_file_cfg.avatar_level_advances
|
||||
.iter()
|
||||
.find(|tmpl| tmpl.id() == player_avatar.rank as i32)
|
||||
else {
|
||||
properties.insert(EPropertyType::HpMaxAdvance.into(), 0);
|
||||
properties.insert(EPropertyType::AtkAdvance.into(), 0);
|
||||
properties.insert(EPropertyType::DefAdvance.into(), 0);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
properties.insert(EPropertyType::HpMaxAdvance.into(), avatar_level_advance.hp_max());
|
||||
properties.insert(EPropertyType::AtkAdvance.into(), avatar_level_advance.attack());
|
||||
properties.insert(EPropertyType::DefAdvance.into(), avatar_level_advance.defence());
|
||||
}
|
||||
|
||||
fn perform_avatar_growth_promotion_calculations(
|
||||
player_avatar: &Avatar,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
properties.insert(
|
||||
EPropertyType::HpMaxBase.into(),
|
||||
properties.get(&EPropertyType::HpMaxBase.into()).unwrap()
|
||||
+ (((player_avatar.level - 1) as f32 * *properties.get(&EPropertyType::HpMaxGrowth.into()).unwrap() as f32) / 10000f32) as i32
|
||||
+ properties.get(&EPropertyType::HpMaxAdvance.into()).unwrap()
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::AtkBase.into(),
|
||||
properties.get(&EPropertyType::AtkBase.into()).unwrap()
|
||||
+ (((player_avatar.level - 1) as f32 * *properties.get(&EPropertyType::AtkGrowth.into()).unwrap() as f32) / 10000f32) as i32
|
||||
+ properties.get(&EPropertyType::AtkAdvance.into()).unwrap()
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::DefBase.into(),
|
||||
properties.get(&EPropertyType::DefBase.into()).unwrap()
|
||||
+ (((player_avatar.level - 1) as f32 * *properties.get(&EPropertyType::DefGrowth.into()).unwrap() as f32) / 10000f32) as i32
|
||||
+ properties.get(&EPropertyType::DefAdvance.into()).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
fn add_avatar_passive_skill_properties(
|
||||
avatar_file_cfg: &AvatarFileCfg,
|
||||
player_avatar: &Avatar,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
let passive_skill_level = player_avatar.skill_type_level.iter()
|
||||
.find(|s| s.skill_type == EAvatarSkillType::CoreSkill as u32)
|
||||
.unwrap()
|
||||
.level;
|
||||
|
||||
avatar_file_cfg.avatar_passive_skill_templates
|
||||
.iter()
|
||||
.find(|a| a.unlock_passive_skill_level() == passive_skill_level as i32)
|
||||
.map(|tmpl| tmpl.propertys().unwrap())
|
||||
.unwrap()
|
||||
.iter()
|
||||
.for_each(|p| {
|
||||
properties.insert(
|
||||
p.property() as u32,
|
||||
properties.get(&(p.property() as u32)).unwrap_or(&0)
|
||||
+ p.value()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn get_weapon_filecfg(
|
||||
player_weapon: &Weapon,
|
||||
filecfg: &'static NapFileCfg,
|
||||
) -> Option<WeaponFileCfg<'static>> {
|
||||
let Some(weapon_template) = filecfg.weapon_template_tb().data().unwrap()
|
||||
.iter()
|
||||
.find(|tmpl| tmpl.item_id() == player_weapon.id as i32)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let Some(weapon_level_template) = filecfg.weapon_level_template_tb().data().unwrap()
|
||||
.iter()
|
||||
.find(|tmpl| tmpl.level() == player_weapon.level as i32)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let Some(weapon_star_template) = filecfg.weapon_star_template_tb().data().unwrap()
|
||||
.iter()
|
||||
.find(|tmpl| tmpl.star() == player_weapon.star as i32)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(WeaponFileCfg {
|
||||
weapon_template,
|
||||
weapon_level_template,
|
||||
weapon_star_template,
|
||||
})
|
||||
}
|
||||
|
||||
fn add_weapon_template_properties(
|
||||
weapon_file_cfg: &WeaponFileCfg,
|
||||
properties: &mut HashMap<u32, i32>,
|
||||
) {
|
||||
let base_property = weapon_file_cfg.weapon_template.base_property().unwrap();
|
||||
let base_property_value = base_property.value()
|
||||
+ (base_property.value() as f32 * weapon_file_cfg.weapon_level_template.rate() as f32 / 10000f32) as i32
|
||||
+ (base_property.value() as f32 * weapon_file_cfg.weapon_star_template.star_rate() as f32 / 10000f32) as i32
|
||||
;
|
||||
properties.insert(
|
||||
base_property.property() as u32,
|
||||
*properties.get(&(base_property.property() as u32)).unwrap_or(&0)
|
||||
+ base_property_value
|
||||
);
|
||||
let rand_property = weapon_file_cfg.weapon_template.rand_property().unwrap();
|
||||
let rand_property_value = rand_property.value()
|
||||
+ (rand_property.value() as f32 * weapon_file_cfg.weapon_star_template.rand_rate() as f32 / 10000f32) as i32
|
||||
;
|
||||
properties.insert(
|
||||
rand_property.property() as u32,
|
||||
*properties.get(&(rand_property.property() as u32)).unwrap_or(&0)
|
||||
+ rand_property_value
|
||||
);
|
||||
}
|
||||
|
||||
fn add_player_equip_properties(
|
||||
player_equips: &Vec<&Equip>,
|
||||
filecfg: &'static NapFileCfg,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
player_equips.iter().for_each(|pe| {
|
||||
let equip_rarity = (pe.id / 10) % 10;
|
||||
let property_rate = filecfg.equipment_level_template_tb()
|
||||
.data().unwrap()
|
||||
.iter().find(|tmpl|
|
||||
tmpl.rarity() == equip_rarity as i32
|
||||
&& tmpl.level() == pe.level as i32
|
||||
).map(|tmpl| tmpl.property_rate())
|
||||
.unwrap_or(1);
|
||||
pe.propertys
|
||||
.iter()
|
||||
.for_each(|p| {
|
||||
properties.insert(
|
||||
p.key,
|
||||
properties.get(&p.key).unwrap_or(&0)
|
||||
+ p.base_value as i32
|
||||
+ (p.base_value as f32 * property_rate as f32 / 10000f32) as i32
|
||||
);
|
||||
});
|
||||
pe.sub_propertys.iter()
|
||||
.for_each(|p| {
|
||||
properties.insert(
|
||||
p.key,
|
||||
properties.get(&p.key).unwrap_or(&0)
|
||||
+ (p.base_value as f32 * p.add_value as f32) as i32
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn add_equipment_suit_properties(
|
||||
player_equips: &Vec<&Equip>,
|
||||
filecfg: &'static NapFileCfg,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
let mut suit_counts = HashMap::<i32, i32>::new();
|
||||
player_equips.iter().for_each(|pe| {
|
||||
let suit_id = pe.id as i32 / 100 * 100;
|
||||
suit_counts.insert(
|
||||
suit_id,
|
||||
*suit_counts.get(&suit_id).unwrap_or(&0) + 1
|
||||
);
|
||||
});
|
||||
suit_counts.iter().for_each(|sc| {
|
||||
let Some(equipment_suit_template) = filecfg.equipment_suit_template_tb()
|
||||
.data().unwrap()
|
||||
.iter().find(|tmpl| tmpl.id() == *sc.0)
|
||||
else { return; };
|
||||
if equipment_suit_template.primary_condition() <= *sc.1 {
|
||||
equipment_suit_template.primary_suit_propertys().unwrap()
|
||||
.iter().for_each(|p| {
|
||||
properties.insert(
|
||||
p.property() as u32,
|
||||
properties.get(&(p.property() as u32)).unwrap_or(&0)
|
||||
+ p.value()
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
fn calculate_final_properties(
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
|
||||
properties.insert(
|
||||
EPropertyType::HpMax.into(),
|
||||
properties.get(&EPropertyType::HpMaxBase.into()).unwrap()
|
||||
+ (
|
||||
*properties.get(&EPropertyType::HpMaxBase.into()).unwrap() as f32
|
||||
* *properties.get(&EPropertyType::HpMaxRatio.into()).unwrap_or(&0) as f32
|
||||
/ 10000f32
|
||||
).ceil() as i32
|
||||
+ properties.get(&EPropertyType::HpMaxDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::Atk.into(),
|
||||
properties.get(&EPropertyType::AtkBase.into()).unwrap()
|
||||
+ (
|
||||
*properties.get(&EPropertyType::AtkBase.into()).unwrap() as f32
|
||||
* *properties.get(&EPropertyType::AtkRatio.into()).unwrap_or(&0) as f32
|
||||
/ 10000f32
|
||||
) as i32
|
||||
+ properties.get(&EPropertyType::AtkDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::BreakStun.into(),
|
||||
properties.get(&EPropertyType::BreakStunBase.into()).unwrap()
|
||||
+ (
|
||||
*properties.get(&EPropertyType::BreakStunBase.into()).unwrap() as f32
|
||||
* *properties.get(&EPropertyType::BreakStunRatio.into()).unwrap_or(&0) as f32
|
||||
/ 10000f32
|
||||
) as i32
|
||||
+ properties.get(&EPropertyType::BreakStunDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::Def.into(),
|
||||
properties.get(&EPropertyType::DefBase.into()).unwrap()
|
||||
+ (
|
||||
*properties.get(&EPropertyType::DefBase.into()).unwrap() as f32
|
||||
* *properties.get(&EPropertyType::DefRatio.into()).unwrap_or(&0) as f32
|
||||
/ 10000f32
|
||||
) as i32
|
||||
+ properties.get(&EPropertyType::DefDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::Crit.into(),
|
||||
properties.get(&EPropertyType::CritBase.into()).unwrap()
|
||||
+ properties.get(&EPropertyType::CritDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::CritDmg.into(),
|
||||
properties.get(&EPropertyType::CritDmgBase.into()).unwrap()
|
||||
+ properties.get(&EPropertyType::CritDmgDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::Pen.into(),
|
||||
properties.get(&EPropertyType::PenBase.into()).unwrap()
|
||||
+ properties.get(&EPropertyType::PenDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::PenValue.into(),
|
||||
properties.get(&EPropertyType::PenValueBase.into()).unwrap()
|
||||
+ properties.get(&EPropertyType::PenValueDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::SpRecover.into(),
|
||||
properties.get(&EPropertyType::SpRecoverBase.into()).unwrap()
|
||||
+ (
|
||||
*properties.get(&EPropertyType::SpRecoverBase.into()).unwrap() as f32
|
||||
* *properties.get(&EPropertyType::SpRecoverRatio.into()).unwrap_or(&0) as f32
|
||||
/ 10000f32
|
||||
) as i32
|
||||
+ properties.get(&EPropertyType::SpRecoverDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::ElementMystery.into(),
|
||||
properties.get(&EPropertyType::ElementMysteryBase.into()).unwrap()
|
||||
+ properties.get(&EPropertyType::ElementMysteryDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::ElementAbnormalPower.into(),
|
||||
properties.get(&EPropertyType::ElementAbnormalPowerBase.into()).unwrap()
|
||||
+ (
|
||||
*properties.get(&EPropertyType::ElementAbnormalPowerBase.into()).unwrap() as f32
|
||||
* *properties.get(&EPropertyType::ElementAbnormalPowerRatio.into()).unwrap_or(&0) as f32
|
||||
/ 10000f32
|
||||
) as i32
|
||||
+ properties.get(&EPropertyType::ElementAbnormalPowerDelta.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::AddedDamageRatioPhysics.into(),
|
||||
properties.get(&EPropertyType::AddedDamageRatioPhysics1.into()).unwrap_or(&0)
|
||||
+ properties.get(&EPropertyType::AddedDamageRatioPhysics3.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::AddedDamageRatioFire.into(),
|
||||
properties.get(&EPropertyType::AddedDamageRatioFire1.into()).unwrap_or(&0)
|
||||
+ properties.get(&EPropertyType::AddedDamageRatioFire3.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::AddedDamageRatioIce.into(),
|
||||
properties.get(&EPropertyType::AddedDamageRatioIce1.into()).unwrap_or(&0)
|
||||
+ properties.get(&EPropertyType::AddedDamageRatioIce3.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::AddedDamageRatioElec.into(),
|
||||
properties.get(&EPropertyType::AddedDamageRatioElec1.into()).unwrap_or(&0)
|
||||
+ properties.get(&EPropertyType::AddedDamageRatioElec3.into()).unwrap_or(&0)
|
||||
);
|
||||
properties.insert(
|
||||
EPropertyType::AddedDamageRatioEther.into(),
|
||||
properties.get(&EPropertyType::AddedDamageRatioEther1.into()).unwrap_or(&0)
|
||||
+ properties.get(&EPropertyType::AddedDamageRatioEther3.into()).unwrap_or(&0)
|
||||
);
|
||||
}
|
||||
|
||||
fn add_ben_core_passive(
|
||||
avatar_id: u32,
|
||||
player_avatar: &Avatar,
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
if avatar_id != BEN_AVATAR_ID {
|
||||
return;
|
||||
}
|
||||
let core_level = player_avatar.skill_type_level.iter().find(|sl| sl.skill_type == EAvatarSkillType::CoreSkill as u32).unwrap().level as usize;
|
||||
let def_atk_bonus = match core_level {
|
||||
1..=7 => {
|
||||
*properties.get(&EPropertyType::Def.into()).unwrap_or(&0)
|
||||
* BEN_CORE_PASSIVE_PERCENTAGE[core_level - 1]
|
||||
/ 100
|
||||
},
|
||||
_ => 0,
|
||||
};
|
||||
properties.insert(
|
||||
EPropertyType::Atk.into(),
|
||||
*properties.get(&EPropertyType::Atk.into()).unwrap_or(&0)
|
||||
+ def_atk_bonus
|
||||
);
|
||||
}
|
||||
|
||||
fn remove_custom_properties(
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
properties.remove(&EPropertyType::HpMaxGrowth.into());
|
||||
properties.remove(&EPropertyType::AtkGrowth.into());
|
||||
properties.remove(&EPropertyType::DefGrowth.into());
|
||||
properties.remove(&EPropertyType::HpMaxAdvance.into());
|
||||
properties.remove(&EPropertyType::AtkAdvance.into());
|
||||
properties.remove(&EPropertyType::DefAdvance.into());
|
||||
}
|
||||
|
||||
fn set_battle_properties(
|
||||
properties: &mut HashMap<u32, i32>
|
||||
) {
|
||||
properties.insert(EPropertyType::HpMaxBattle.into(), *properties.get(&EPropertyType::HpMax.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::AtkBattle.into(), *properties.get(&EPropertyType::Atk.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::BreakStunBattle.into(), *properties.get(&EPropertyType::BreakStun.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::DefBattle.into(), *properties.get(&EPropertyType::Def.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::CritBattle.into(), *properties.get(&EPropertyType::Crit.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::CritDmgBattle.into(), *properties.get(&EPropertyType::CritDmg.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::PenRatioBattle.into(), *properties.get(&EPropertyType::Pen.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::PenDeltaBattle.into(), *properties.get(&EPropertyType::PenValue.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::SpRecoverBattle.into(), *properties.get(&EPropertyType::SpRecover.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::ElementMysteryBattle.into(), *properties.get(&EPropertyType::ElementMystery.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::ElementAbnormalPowerBattle.into(), *properties.get(&EPropertyType::ElementAbnormalPower.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::AddedDamageRatioPhysicsBattle.into(), *properties.get(&EPropertyType::AddedDamageRatioPhysics.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::AddedDamageRatioFireBattle.into(), *properties.get(&EPropertyType::AddedDamageRatioFire.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::AddedDamageRatioIceBattle.into(), *properties.get(&EPropertyType::AddedDamageRatioIce.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::AddedDamageRatioElecBattle.into(), *properties.get(&EPropertyType::AddedDamageRatioElec.into()).unwrap_or(&0));
|
||||
properties.insert(EPropertyType::AddedDamageRatioEtherBattle.into(), *properties.get(&EPropertyType::AddedDamageRatioEther.into()).unwrap_or(&0));
|
||||
|
||||
}
|
|
@ -3,9 +3,9 @@ use std::path::Path;
|
|||
fn main() {
|
||||
println!("cargo:rerun-if-changed=fbs");
|
||||
|
||||
let _ = flatc_rust::run(flatc_rust::Args {
|
||||
flatc_rust::run(flatc_rust::Args {
|
||||
inputs: &[Path::new("fbs/tables.fbs")],
|
||||
out_dir: Path::new("gen_flatbuffers"),
|
||||
..Default::default()
|
||||
});
|
||||
}).expect("Couldn't compile tables.fbs");
|
||||
}
|
||||
|
|
|
@ -215,17 +215,32 @@ table EquipmentSuitTemplate {
|
|||
id: int;
|
||||
name: string;
|
||||
primary_condition: int;
|
||||
primary_suit_propertys: [Property];
|
||||
unk_3: int;
|
||||
primary_suit_ability: int;
|
||||
primary_description: string;
|
||||
secondary_condition: int;
|
||||
secondary_suit_propertys: [Property];
|
||||
unk_7: int;
|
||||
secondary_suit_ability: int;
|
||||
secondary_description: string;
|
||||
suit_item_icon: string;
|
||||
suit_icon: string;
|
||||
suit_story: string;
|
||||
suit_filter_option: string;
|
||||
suit_icon: string;
|
||||
suit_item_icon: string;
|
||||
unk_14: int;
|
||||
order: int;
|
||||
unk_16: int;
|
||||
unk_17: int;
|
||||
unk_18: int;
|
||||
unk_19: int;
|
||||
unk_20: int;
|
||||
unk_21: int;
|
||||
primary_suit_propertys: [Property];
|
||||
unk_23: [int];
|
||||
unk_24: int;
|
||||
unk_25: [int];
|
||||
unk_26: [int];
|
||||
unk_27: [int];
|
||||
tag: string;
|
||||
}
|
||||
|
||||
table HollowConfigTemplate {
|
||||
|
@ -380,6 +395,160 @@ table ConditionConfigTemplate {
|
|||
type: int;
|
||||
}
|
||||
|
||||
table AvatarBattleTemplate {
|
||||
id: int;
|
||||
unk_1: [int];
|
||||
unk_2: [int];
|
||||
unk_3: [int];
|
||||
unk_4: [int];
|
||||
unk_5: [int];
|
||||
unk_6: [int];
|
||||
unk_7: [int];
|
||||
unk_8: int;
|
||||
unk_9: int;
|
||||
unk_10: int;
|
||||
avatar_piece_id: int;
|
||||
unk_12: int;
|
||||
unk_13: int;
|
||||
hp_max: int;
|
||||
health_growth: int;
|
||||
unk_16: int;
|
||||
unk_17: int;
|
||||
unk_18: int;
|
||||
unk_19: int;
|
||||
unk_20: int;
|
||||
attack: int;
|
||||
attack_growth: int;
|
||||
defence: int;
|
||||
defence_growth: int;
|
||||
crit: int;
|
||||
crit_damage: int;
|
||||
crit_res: int;
|
||||
crit_damage_res: int;
|
||||
pen_rate: int;
|
||||
pen_delta: int;
|
||||
luck: int;
|
||||
stun: int;
|
||||
break_stun: int;
|
||||
element_abnormal_power: int;
|
||||
sp_bar_point: int;
|
||||
sp_recover: int;
|
||||
element_mystery: int;
|
||||
rbl: int;
|
||||
rbl_correction_factor: int;
|
||||
rbl_probability: int;
|
||||
unk_41: int;
|
||||
unk_42: int;
|
||||
unk_43: int;
|
||||
unk_44: int;
|
||||
unk_45: int;
|
||||
unk_46: int;
|
||||
unk_47: int;
|
||||
unk_48: int;
|
||||
unk_49: int;
|
||||
unk_50: int;
|
||||
unk_51: int;
|
||||
unk_52: int;
|
||||
unk_53: int;
|
||||
unk_54: int;
|
||||
unk_55: int;
|
||||
unk_56: int;
|
||||
unk_57: int;
|
||||
unk_58: int;
|
||||
unk_59: int;
|
||||
unk_60: int;
|
||||
unk_61: int;
|
||||
unk_62: int;
|
||||
unk_63: int;
|
||||
unk_64: int;
|
||||
unk_65: int;
|
||||
unk_66: int;
|
||||
tags: [string];
|
||||
unk_68: [int];
|
||||
unk_69: [int];
|
||||
unk_70: int;
|
||||
unk_71: int;
|
||||
element: [int];
|
||||
hit_type: [int];
|
||||
unk_element_camp: [string];
|
||||
unk_75: int;
|
||||
unk_76: short;
|
||||
}
|
||||
|
||||
table AvatarLevelAdvanceTemplate {
|
||||
avatar_id: int;
|
||||
id: int;
|
||||
min_level: int;
|
||||
max_level: int;
|
||||
hp_max: int;
|
||||
unk_5: int;
|
||||
unk_6: int;
|
||||
attack: int;
|
||||
defence: int;
|
||||
unk_9: int;
|
||||
unk_10: int;
|
||||
unk_11: int;
|
||||
unk_12: int;
|
||||
unk_13: int;
|
||||
unk_14: int;
|
||||
unk_15: int;
|
||||
unk_16: int;
|
||||
unk_17: int;
|
||||
unk_18: [int];
|
||||
promotion_costs: [RefineCost];
|
||||
}
|
||||
|
||||
table WeaponLevelTemplate {
|
||||
rarity: int;
|
||||
level: int;
|
||||
rate: int;
|
||||
exp: int;
|
||||
}
|
||||
|
||||
table WeaponStarTemplate {
|
||||
rarity: int;
|
||||
star: int;
|
||||
min_level: int;
|
||||
max_level: int;
|
||||
star_rate: int;
|
||||
rand_rate: int;
|
||||
unk_6: int;
|
||||
unk_7: int;
|
||||
unk_8: int;
|
||||
unk_9: int;
|
||||
unk_10: int;
|
||||
unk_11: int;
|
||||
unk_12: int;
|
||||
}
|
||||
|
||||
table AvatarPassiveSkillTemplate {
|
||||
skill_id: int;
|
||||
avatar_id: int;
|
||||
min_avatar_level: int;
|
||||
min_passive_skill_level: int;
|
||||
unlock_passive_skill_level: int;
|
||||
unk_5: int;
|
||||
unk_levelup: string;
|
||||
unk_7: int;
|
||||
unk_8: int;
|
||||
unk_9: int;
|
||||
unk_10: int;
|
||||
propertys: [Property];
|
||||
names: [string];
|
||||
descriptions: [string];
|
||||
materials_costs: [RefineCost];
|
||||
}
|
||||
|
||||
table EquipmentLevelTemplate {
|
||||
rarity: int;
|
||||
level: int;
|
||||
property_rate: int;
|
||||
unk_3: int;
|
||||
unk_4: int;
|
||||
unk_5: int;
|
||||
unk_6: int;
|
||||
}
|
||||
|
||||
table AvatarBaseTemplateTb {
|
||||
data: [AvatarBaseTemplate];
|
||||
}
|
||||
|
@ -451,3 +620,27 @@ table TeleportConfigTemplateTb {
|
|||
table ConditionConfigTemplateTb {
|
||||
data: [ConditionConfigTemplate];
|
||||
}
|
||||
|
||||
table AvatarBattleTemplateTb {
|
||||
data: [AvatarBattleTemplate];
|
||||
}
|
||||
|
||||
table AvatarLevelAdvanceTemplateTb {
|
||||
data: [AvatarLevelAdvanceTemplate];
|
||||
}
|
||||
|
||||
table WeaponLevelTemplateTb {
|
||||
data: [WeaponLevelTemplate];
|
||||
}
|
||||
|
||||
table WeaponStarTemplateTb {
|
||||
data: [WeaponStarTemplate];
|
||||
}
|
||||
|
||||
table AvatarPassiveSkillTemplateTb {
|
||||
data: [AvatarPassiveSkillTemplate];
|
||||
}
|
||||
|
||||
table EquipmentLevelTemplateTb {
|
||||
data: [EquipmentLevelTemplate];
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -58,4 +58,10 @@ file_cfg! {
|
|||
BattleGroupConfigTemplateTb;
|
||||
MusicPlayerConfigTemplateTb;
|
||||
TeleportConfigTemplateTb;
|
||||
AvatarBattleTemplateTb;
|
||||
AvatarLevelAdvanceTemplateTb;
|
||||
WeaponLevelTemplateTb;
|
||||
WeaponStarTemplateTb;
|
||||
AvatarPassiveSkillTemplateTb;
|
||||
EquipmentLevelTemplateTb;
|
||||
}
|
||||
|
|
|
@ -833,6 +833,8 @@ pub struct BeginArchiveBattleQuestScRsp {
|
|||
pub struct BuddyUnitInfo {
|
||||
#[prost(enumeration = "BuddyTeamType", tag = "6")]
|
||||
pub r#type: i32,
|
||||
#[prost(map = "uint32, int32", tag = "15")]
|
||||
pub properties: ::std::collections::HashMap<u32, i32>,
|
||||
#[xor(4322)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub buddy_id: u32,
|
||||
|
@ -1265,6 +1267,8 @@ pub struct GetWishlistDataCsReq {}
|
|||
#[derive(trigger_protobuf_derive::XorFields)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct AvatarUnitInfo {
|
||||
#[prost(map = "uint32, int32", tag = "9")]
|
||||
pub properties: ::std::collections::HashMap<u32, i32>,
|
||||
#[xor(3561)]
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub avatar_id: u32,
|
||||
|
|
|
@ -4630,6 +4630,11 @@ impl From<::trigger_protocol::GetWishlistDataCsReq> for GetWishlistDataCsReq {
|
|||
impl From<AvatarUnitInfo> for ::trigger_protocol::AvatarUnitInfo {
|
||||
fn from(value: AvatarUnitInfo) -> Self {
|
||||
Self {
|
||||
properties: value
|
||||
.properties
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.into(), v.into()))
|
||||
.collect(),
|
||||
avatar_id: value.avatar_id.into(),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -4639,6 +4644,11 @@ impl From<AvatarUnitInfo> for ::trigger_protocol::AvatarUnitInfo {
|
|||
impl From<::trigger_protocol::AvatarUnitInfo> for AvatarUnitInfo {
|
||||
fn from(value: ::trigger_protocol::AvatarUnitInfo) -> Self {
|
||||
Self {
|
||||
properties: value
|
||||
.properties
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.into(), v.into()))
|
||||
.collect(),
|
||||
avatar_id: value.avatar_id.into(),
|
||||
..Default::default()
|
||||
}
|
||||
|
|
|
@ -357,6 +357,7 @@ pub struct DungeonEquipInfo {
|
|||
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
|
||||
pub struct AvatarUnitInfo {
|
||||
pub avatar_id: u32,
|
||||
pub properties: HashMap<u32, i32>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
|
||||
|
|
Loading…
Reference in a new issue