#include "precompile.h" #include #include "netdata.h" #include "human.h" #include "creature.h" #include "types.h" #include "bullet.h" #include "app.h" #include "room.h" #include "explosion.h" #include "roommgr.h" #include "ability.h" #include "stats.h" #include "android.h" #include "skill.h" #include "buff/distance_dmg_addition.h" #include "mt/Param.h" #include "mt/Item.h" #include "mt/Hero.h" #include "mt/HeroQuality.h" #include "mt/GunQuality.h" #include "mt/NpcStandard.h" #include "mt/PveGemini.h" #include "mt/PveGeminiContent.h" #include "mt/Equip.h" #include "mt/Skill.h" #include "mt/SkillNumber.h" #include "mt/FormulaPvp.h" #include "mt/Robot.h" #include "mt/BattleBasicAttribute.h" #include "attrhelper.h" struct CalcDmgContext { int is_crit = 0; float crit_dmg = 0.0f; }; static CalcDmgContext g_calc_dmg_context = {0}; class HeroAbility { public: long long hero_uniid_ = 0; const mt::Hero* hero_meta = nullptr; std::shared_ptr hero_dto; int spec_skill_id = 0; int main_skill_id = 0; const mt::NpcStandard* standard_meta = nullptr; float GetHP() { return hp_; } float GetAtk() { return atk_; } float GetDef() { return def_; } float GetCrit() { return crit_; } float GetBlock() { return block_; } float GetBrainLifePct() { return brain_life_pct_; } float GetSkillCdPct() { return skill_cd_pct_; } float GetRescueTimePct() { return rescue_time_pct_; } float GetDrugTimePct() { return durg_time_pct_; } float GetDrugEfficacyPct() { return durg_eff_pct_; } float GetTenacityPct() { return tenacity_pct_; } float GetRecoverHpAdd() { return recover_hp_add_pct_; } void Init(Creature* c) { #ifdef NEW_NUM DefaultInit(c); #else if (hero_dto) { DtoInit(c); } else { DefaultInit(c); } #endif } private: void DefaultInit(Creature* c) { { float pHealRateAm = 0.0f; //加基础点数属性绝对值 float pHealthAm_Add = 0.0f; //buff或者养成的属性 pHealRateAm += pHealthAm_Add; float pHealthRateSe = 0.0f; float pHealthRateSe_Add = 0.0f; //buff或者养成的属性 pHealthRateSe += pHealthRateSe_Add; float pHealthRateIn = 0.0f; float pHealthRateIn_Add = 0.0f; //buff或者养成的属性 pHealthRateIn = (1 + pHealthRateIn) * (1 + pHealthRateIn_Add) - 1; float pHealth = (hero_meta->GetBasicMeta()->pOrigHealth() + pHealRateAm) * (1 + pHealthRateSe) * (1 + pHealthRateIn); float vHealthAm = 0.0f; float vHealthAm_Add = 0.0f; //buff或者养成的属性 vHealthAm += vHealthAm_Add; float vHealthRateSe = 0.0f; float vHealthRateSe_Add = 0.0f; //buff或者养成的属性 vHealthRateSe += vHealthRateSe_Add; float vHealthRateIn = 0.0f; float vHealthRateIn_Add = 0.0f; //buff或者养成的属性 vHealthRateIn = (1 + vHealthRateIn) * (1 + vHealthRateIn_Add) - 1; hp_ = (hero_meta->GetBasicMeta()->vOrigHealth() * (1 + pHealth / hero_meta->GetBasicMeta()->pBaseHealth() + vHealthAm)) * (1 + vHealthRateSe) * (1 + vHealthRateIn); } { float pAttackAm = 0.0f; float pAttackAm_Add = 0.0f; pAttackAm += pAttackAm_Add; float pAttackRateSe = 0.0f; float pAttackRateSe_Add = 0.0f; pAttackRateSe += pAttackRateSe_Add; float pAttackRateIn = 0.0f; float pAttackRateIn_Add = 0.0f; pAttackRateIn = (1 + pAttackRateIn) * ( 1 + pAttackRateIn_Add) - 1; float vAttackAm = 0.0f; float vAttackAm_Add = 0.0f; vAttackAm += vAttackAm_Add; float vAttackRateSe = 0.0f; float vAttackRateSe_Add = 0.0f; vAttackRateSe += vAttackRateSe_Add; float vAttackRateIn = 0.0f; float vAttackRateIn_Add = 0.0f; vAttackRateIn = (1 + vAttackRateIn) * (1 + vAttackRateIn_Add) - 1; float pAttack = 0.0f; pAttack = (hero_meta->GetBasicMeta()->vOrigAttack() + pAttackAm) * (1 + pAttackRateSe) * (1 + pAttackRateIn); atk_ = (hero_meta->GetBasicMeta()->vOrigAttack() * (1 + pAttack / hero_meta->GetBasicMeta()->pBaseAttack()) + vAttackAm) * (1 + vAttackRateSe) * (1 + vAttackRateIn); } { float pDefendAm = 0.0f; float pDefendAm_Add = 0.0f; pDefendAm += pDefendAm_Add; float pDefendRateSe = 0.0f; float pDefendRateSe_Add = 0.0f; pDefendRateSe += pDefendRateSe_Add; float pDefendRateIn = 0.0f; float pDefendRateIn_Add = 0.0f; pDefendRateIn = (1 + pDefendRateIn) * (1 + pDefendRateIn_Add) - 1; def_ = (hero_meta->GetBasicMeta()->vOrigDefend() + pDefendAm) * (1 + pDefendRateSe) * (1 + pDefendRateIn); } { float pBlockAm = 0.0f; float pBlockAm_Add = 0.0f; pBlockAm += pBlockAm_Add; float pBlockRateSe = 0.0f; float pBlockRateSe_Add = 0.0f; pBlockRateSe += pBlockRateSe_Add; float pBlockRateIn = 0.0f; float pBlockRateIn_Add = 0.0f; pBlockRateIn = (1 + pBlockRateIn) * (1 + pBlockRateIn_Add) - 1; float pBlock = 0.0f; pBlock = (hero_meta->GetBasicMeta()->pOrigBlock() +pBlockAm) * (1 + pBlockRateSe) * (1 + pBlockRateIn); float vBlock = 1 - (1 - hero_meta->GetBasicMeta()->vOrigBlock()) / (1 + pBlock / hero_meta->GetBasicMeta()->pBaseBlock()); block_ = vBlock; } { float pCritAm = 0.0f; float pCritAm_Add = 0.0f; pCritAm += pCritAm_Add; float pCritRateSe = 0.0f; float pCritRateSe_Add = 0.0f; pCritRateSe += pCritRateSe_Add; float pCritRateIn = 0.0f; float pCritRateIn_Add = 0.0f; pCritRateIn = (1 + pCritRateIn) * (1 + pCritRateIn_Add) - 1; float pCrit = 0.0f; pCrit = (hero_meta->GetBasicMeta()->pOrigCrit() + pCritAm) * (1 + pCritRateSe) * (1 + pCritRateIn); float vCrit = 0.0f; vCrit = (1 + hero_meta->GetBasicMeta()->vOrigCrit()) * (1 + pCrit / hero_meta->GetBasicMeta()->pBaseCrit()) - 1; crit_ = vCrit; } } void DtoInit(Creature* c) { std::array base_attr_abs = {0}; std::array base_attr_rate = {0}; std::array pro_attr_abs = {0}; std::array pro_attr_rate = {0}; std::array skill_attr_abs = {0}; std::array skill_attr_rate = {0}; std::array chip_attr_abs = {0}; std::array chip_attr_rate = {0}; std::array core_attr_abs = {0}; std::array core_attr_rate = {0}; { std::shared_ptr attr_base_xobj = hero_dto->At("attr_base"); if (attr_base_xobj && attr_base_xobj->IsArray()) { AttrHelper::ParseAttr(attr_base_xobj, base_attr_abs, base_attr_rate); } } { std::shared_ptr attr_base_xobj = hero_dto->At("rand_attr"); if (attr_base_xobj && attr_base_xobj->IsArray()) { AttrHelper::ParseAttr(attr_base_xobj, base_attr_abs, base_attr_rate); } } { std::shared_ptr attr_pro_xobj = hero_dto->At("attr_pro"); if (attr_pro_xobj && attr_pro_xobj->IsArray()) { AttrHelper::ParseAttr(attr_pro_xobj, pro_attr_abs, pro_attr_rate); } } { std::shared_ptr attr_skill_xobj = hero_dto->At("attr_skill"); if (attr_skill_xobj && attr_skill_xobj->IsArray()) { AttrHelper::ParseAttr(attr_skill_xobj, skill_attr_abs, skill_attr_rate); } } { std::shared_ptr attr_chip_xobj = hero_dto->At("attr_chip"); if (attr_chip_xobj && attr_chip_xobj->IsArray()) { AttrHelper::ParseAttr(attr_chip_xobj, chip_attr_abs, chip_attr_rate); } } { std::shared_ptr attr_core_xobj = hero_dto->At("attr_core"); if (attr_core_xobj && attr_core_xobj->IsArray()) { AttrHelper::ParseAttr(attr_core_xobj, core_attr_abs, core_attr_rate); } } std::array finaly_attr_abs = base_attr_abs; std::array finaly_attr_rate = base_attr_rate; for (int i = 0; i < kNHAT_End; ++i) { if (pro_attr_abs[i] > 0.000f) { finaly_attr_abs[i] = pro_attr_abs[i]; } if (pro_attr_rate[i] > 0.000f) { finaly_attr_rate[i] = pro_attr_rate[i]; } finaly_attr_abs[i] += skill_attr_abs[i]; finaly_attr_rate[i] += skill_attr_rate[i]; finaly_attr_abs[i] += chip_attr_abs[i]; finaly_attr_rate[i] += chip_attr_rate[i]; finaly_attr_abs[i] += core_attr_abs[i]; finaly_attr_rate[i] += core_attr_rate[i]; } } private: float hp_ = 0.0f; float atk_ = 0.0f; float def_ = 0.0f; float brain_life_pct_ = 0.0f; float skill_cd_pct_ = 0.0f; float rescue_time_pct_ = 0.0f; float durg_time_pct_ = 0.0f; float durg_eff_pct_ = 0.0f; float tenacity_pct_ = 0.0f; float recover_hp_add_pct_ = 0.0f; float crit_ = 0.0f; float block_ = 0.0f; }; class WeaponAbility { public: long long weapon_uniid = 0; int weapon_lv = 1; int quality = 1; const mt::Equip* weapon_meta = nullptr; std::shared_ptr weapon_dto; float GetAtk() { return atk_; } float GetCritAtk() { return crit_atk_; } float GetCritAtkRatio() { return crit_atk_ratio_; } int GetClipVolume() { return clip_volume_; } int GetFireRate() { return fire_rate_; } int GetReloadTime() { return reload_time_; } void Init(Creature* c) { #ifdef NEW_NUM DefaultInit(c); #else if (weapon_dto) { DtoInit(c); } else { DefaultInit(c); } #endif } private: void DefaultInit(Creature* c) { atk_ = weapon_meta->_atk; crit_atk_ = weapon_meta->critical(); crit_atk_ratio_ = weapon_meta->cri_damage(); clip_volume_ = weapon_meta->clip_volume(); fire_rate_ = weapon_meta->fire_rate(); reload_time_ = weapon_meta->reload_time(); } void DtoInit(Creature* c) { std::array base_attr_abs = {0}; std::array base_attr_rate = {0}; std::array pro_attr_abs = {0}; std::array pro_attr_rate = {0}; std::array chip_attr_abs = {0}; std::array chip_attr_rate = {0}; std::array core_attr_abs = {0}; std::array core_attr_rate = {0}; { std::shared_ptr attr_base_xobj = weapon_dto->At("attr_base"); if (attr_base_xobj && attr_base_xobj->IsArray()) { AttrHelper::ParseAttr(attr_base_xobj, base_attr_abs, base_attr_rate); } } { std::shared_ptr attr_base_xobj = weapon_dto->At("rand_attr"); if (attr_base_xobj && attr_base_xobj->IsArray()) { AttrHelper::ParseAttr(attr_base_xobj, base_attr_abs, base_attr_rate); } } { std::shared_ptr attr_pro_xobj = weapon_dto->At("attr_pro"); if (attr_pro_xobj && attr_pro_xobj->IsArray()) { AttrHelper::ParseAttr(attr_pro_xobj, pro_attr_abs, pro_attr_rate); } } { std::shared_ptr attr_chip_xobj = weapon_dto->At("attr_chip"); if (attr_chip_xobj && attr_chip_xobj->IsArray()) { AttrHelper::ParseAttr(attr_chip_xobj, chip_attr_abs, chip_attr_rate); } } { std::shared_ptr attr_core_xobj = weapon_dto->At("attr_core"); if (attr_core_xobj && attr_core_xobj->IsArray()) { AttrHelper::ParseAttr(attr_core_xobj, core_attr_abs, core_attr_rate); } } std::array finaly_attr_abs = base_attr_abs; std::array finaly_attr_rate = base_attr_rate; for (int i = 0; i < kNHAT_End; ++i) { if (pro_attr_abs[i] > 0.000f) { finaly_attr_abs[i] = pro_attr_abs[i]; } if (pro_attr_rate[i] > 0.000f) { finaly_attr_rate[i] = pro_attr_rate[i]; } finaly_attr_abs[i] += chip_attr_abs[i]; finaly_attr_rate[i] += chip_attr_rate[i]; finaly_attr_abs[i] += core_attr_abs[i]; finaly_attr_rate[i] += core_attr_rate[i]; } } private: float atk_ = 0.0f; float crit_atk_ = 0.0f; float crit_atk_ratio_ = 0.0f; int clip_volume_ = 0; int fire_rate_ = 0; int reload_time_ = 0; }; BattleDataContext::BattleDataContext() { hero_ability_ = std::make_shared(); hero_ability_->hero_meta = mt::Param::s().human_meta; } void BattleDataContext::Clear() { } void BattleDataContext::ParseResult(a8::XObject& obj) { is_valid_battle = obj.Get("is_valid_battle"); payload = obj.Get("payload").GetString(); errcode = obj.Get("errcode"); errmsg = obj.Get("errmsg").GetString(); if (errcode == 0) { revive_coin_ = obj.Get("revive_coin"); match_mode_ = obj.Get("match_mode"); rank_ = obj.Get("rank"); elo_ = obj.Get("elo"); battle_times_ = obj.Get("battle_times"); current_get_star_ = obj.Get("current_get_star"); } level_ = obj.HasKey("level") ? obj.Get("level").GetInt() : 1; skin_id_ = obj.HasKey("hero_skin") ? obj.Get("hero_skin").GetInt() : 0; if (obj.HasKey("hero_dto") && obj.At("hero_dto")->IsObject()) { hero_dto = obj.At("hero_dto"); hero_ability_->hero_uniid_ = hero_dto->Get("hero_uniid", ""); hero_ability_->spec_skill_id = obj.Get("skill_id", ""); hero_ability_->main_skill_id = obj.Get("skill_id", ""); hero_ability_->hero_dto = hero_dto; hero_lv_ = hero_dto->HasKey("hero_lv") ? hero_dto->Get("hero_lv").GetInt() : 1; const mt::Hero* meta = mt::Hero::GetById(hero_dto->Get("hero_id", "")); if (meta) { hero_ability_->hero_meta = meta; } if (hero_dto->HasKey("avatar_info") && hero_dto->At("avatar_info")->IsArray()) { if (hero_dto->At("avatar_info")->Size() > 0) { avatars_.push_back(290001); } } } if (obj.HasKey("honor_info") && obj.At("honor_info")->IsArray()) { auto honor_info = obj.At("honor_info"); for (int i = 0; i < honor_info->Size(); ++i) { auto info = honor_info->At(i); if (info->IsObject()) { if (info->HasKey("token_type") && info->HasKey("state") && info->At("token_type")->IsSimple() && info->At("state")->IsSimple() ) { int token_type = info->Get("token_type").GetInt(); int state = info->Get("state").GetInt(); if (token_type == 6 && state) { honor_ = 1; } } } } } #if 1 if (hero_ability_->hero_meta) { const mt::Item* item_meta = mt::Item::GetById(hero_ability_->hero_meta->default_weapon()); if (item_meta) { const mt::Equip* meta = mt::Equip::GetById(item_meta->relationship()); if (meta) { weapon1_ability_ = std::make_shared(); weapon1_ability_->weapon_uniid = 0; weapon1_ability_->weapon_lv = 1; weapon1_ability_->quality = 1; weapon1_ability_->weapon_meta = meta; } } } #else if (obj.HasKey("weapon_dto1") && obj.At("weapon_dto1")->IsObject()) { weapon_dto1 = obj.At("weapon_dto1"); const mt::Item* item_meta = mt::Item::GetById(weapon_dto1->Get("gun_id", 0)); if (item_meta) { const mt::Equip* meta = mt::Equip::GetById(item_meta->relationship()); if (meta) { weapon1_ability_ = std::make_shared(); weapon1_ability_->weapon_uniid = weapon_dto1->Get("gun_uniid", 0); weapon1_ability_->weapon_lv = weapon_dto1->Get("gun_lv", 1); weapon1_ability_->quality = weapon_dto1->Get("quality", 1); weapon1_ability_->weapon_meta = meta; weapon1_ability_->weapon_dto = weapon_dto1; } } } if (obj.HasKey("weapon_dto2") && obj.At("weapon_dto2")->IsObject()) { weapon_dto2 = obj.At("weapon_dto2"); const mt::Item* item_meta = mt::Item::GetById(weapon_dto2->Get("gun_id", 0)); if (item_meta) { const mt::Equip* meta = mt::Equip::GetById(item_meta->relationship()); if (meta) { weapon2_ability_ = std::make_shared(); weapon2_ability_->weapon_uniid = weapon_dto2->Get("gun_uniid", 0); weapon2_ability_->weapon_lv = weapon_dto2->Get("gun_lv", 1); weapon2_ability_->quality = weapon_dto2->Get("quality", 1); weapon2_ability_->weapon_meta = meta; weapon2_ability_->weapon_dto = weapon_dto2; } } } #endif parse_ok = hero_ability_->hero_meta != nullptr; } void BattleDataContext::GetHeroLvQuality(long long& hero_uniid, int& hero_lv, int& quality) { hero_uniid = 0; hero_lv = 1; quality = 1; #if 1 { #else if (owner_.Get()->IsPlayer()) { #endif if (hero_ability_ && hero_dto && hero_dto->IsObject()) { hero_uniid = hero_dto->Get("hero_uniid", 0).GetInt64(); hero_lv = hero_dto->Get("hero_lv", 0).GetInt(); quality = hero_dto->Get("quality", 0).GetInt(); } } } void BattleDataContext::GetWeaponLvQuality(long long weapon_uniid, int& weapon_lv, int& quality) { weapon_lv = 1; quality = 1; if (owner_.Get()->IsPlayer() && weapon_uniid) { if (weapon1_ability_ && weapon_uniid == weapon1_ability_->weapon_uniid) { weapon_lv = weapon1_ability_->weapon_lv; quality = weapon1_ability_->quality; } if (weapon2_ability_ && weapon_uniid == weapon2_ability_->weapon_uniid) { weapon_lv = weapon2_ability_->weapon_lv; quality = weapon2_ability_->quality; } } } int BattleDataContext::GetWeaponMaxLv() { int max_weapon_lv = 1; if (weapon1_ability_) { max_weapon_lv = std::max(max_weapon_lv, weapon_dto1->Get("gun_lv", 0).GetInt()); } if (weapon2_ability_) { max_weapon_lv = std::max(max_weapon_lv, weapon_dto2->Get("gun_lv", 0).GetInt()); } return std::max(1, max_weapon_lv); } void BattleDataContext::CalcBattleStat(struct PlayerStats* stats) { if (!owner_.Get()->IsPlayer()) { return; } auto CalcHeroPvpCeg = [] (long long ceg_uplimit, struct PlayerStats* stats) -> long long { const mt::FormulaPvp* meta = mt::FormulaPvp::GetByTopx(stats->ranked_topx); if (!meta) { return 0; } long long ceg = round ( ceg_uplimit * ( (0.5 * stats->ranked_topx * meta->ranked_topx()) + (0.25 * stats->kills_topx * meta->kills_topx()) + (0.15 * stats->hero_topx * meta->hero_topx()) + (0.5 * stats->weapon_topx * meta->weapon_topx()) + (0.5 * stats->survival_topx * meta->survival_topx()) ) ); return ceg; }; auto CalcWeaponPvpCeg = [] (long long ceg_uplimit, struct PlayerStats* stats) -> long long { const mt::FormulaPvp* meta = mt::FormulaPvp::GetByTopx(stats->ranked_topx); if (!meta) { return 0; } long long ceg = round ( ceg_uplimit * ( (0.5 * stats->ranked_topx * meta->ranked_topx()) + (0.25 * stats->kills_topx * meta->kills_topx()) + (0.15 * stats->hero_topx * meta->hero_topx()) + (0.5 * stats->weapon_topx * meta->weapon_topx()) + (0.5 * stats->survival_topx * meta->survival_topx()) ) ); return ceg; }; if (hero_ability_ && hero_dto && hero_dto->IsObject()) { int hero_id = hero_dto->Get("hero_id", 0).GetInt(); int quality = hero_dto->Get("quality", 0).GetInt(); int today_get_gold = hero_dto->Get("today_get_gold", 0).GetInt(); const mt::Hero* hero_meta = mt::Hero::GetById(hero_id); const mt::HeroQuality* quality_meta = mt::HeroQuality::GetById(quality); stats->pb_hero_stats.hero_uniid = a8::XValue(hero_ability_->hero_uniid_).GetString(); stats->pb_hero_stats.hero_id = hero_id; stats->pb_hero_stats.hero_name = hero_meta ? hero_meta->name() : ""; if (quality_meta) { int up_limit = quality_meta->GetPvpCegUpLimit(); int ceg = CalcHeroPvpCeg(up_limit, stats); int new_ceg = std::min(up_limit, today_get_gold + ceg); int finaly_ceg = std::max(0, new_ceg - today_get_gold); stats->pb_hero_stats.ceg_uplimit = up_limit; stats->pb_hero_stats.today_get_ceg = std::min(up_limit, today_get_gold + finaly_ceg); stats->pb_hero_stats.reward_ceg = finaly_ceg; } } std::vector> weapons; if (weapon_dto1) { weapons.push_back(weapon_dto1); } if (weapon_dto2) { weapons.push_back(weapon_dto2); } for (auto& weapon_dto : weapons) { std::string gun_uniid = weapon_dto->Get("gun_uniid", 0).GetString(); int gun_id = weapon_dto->Get("gun_id", 0).GetInt(); int quality = weapon_dto->Get("quality", 0).GetInt(); int today_get_gold = weapon_dto->Get("today_get_gold", 0).GetInt(); const mt::Item* item_meta = mt::Item::GetById(gun_id); const mt::GunQuality* quality_meta = mt::GunQuality::GetById(quality); auto& p = a8::FastAppend(stats->pb_weapons_stats); p.weapon_uniid = gun_uniid; p.weapon_id = gun_id; p.weapon_name = item_meta ? item_meta->name() : ""; if (quality_meta) { int up_limit = quality_meta->GetPvpCegUpLimit(); int ceg = CalcWeaponPvpCeg(up_limit, stats); int new_ceg = std::min(up_limit, today_get_gold + ceg); int finaly_ceg = std::max(0, new_ceg - today_get_gold); p.ceg_uplimit = up_limit; p.today_get_ceg = std::min(up_limit, today_get_gold + finaly_ceg); p.reward_ceg = finaly_ceg; } } } static float ProEffect(float p, float b) { if (p * b > -1 && b > 0.00001f) { float x = std::floor(p) *b; float y = std::max(x + b, -1.0f); float q = (p * b - y) / (x - y); float rnd = (float)rand() / (float)RAND_MAX; return rnd < q ? x : y; } else { return 0.0f; } } float BattleDataContext::CalcDmg(Creature* target, IBullet* bullet) { g_calc_dmg_context = {0}; g_calc_dmg_context.is_crit = 0; float vEbc = 1.0f; float vEd = 1 - target->GetNetData()->GetDef(); float X = (1 + hero_ability_->GetCrit()) * (1 - target->GetNetData()->GetBlock()) - 1; if (X > 0.00001f) { //触发暴击 float vCritBon = hero_ability_->hero_meta->GetBasicMeta()->vOrigCriBon(); float E = ProEffect(X, vCritBon); //E >= 0 if (E > 0.00001f) { vEbc = 1 + E; } } else { //触发格挡 0,-1 float vBlock = target->GetNetData()->GetHeroAbility()->hero_meta->GetBasicMeta()->vOrigBloDef(); float E = ProEffect(X, -vBlock); //E >= 0 if (E < 0.00001f) { vEbc = 1 + E; } } float vAttack = GetHeroTotalAtk(); float vBullet = GetWeaponAtk(bullet); float BDM = 100; float vNormalDamageDealtRateIn = 0.0f; float vNormalDamageTakenRateIn = 0.0f; float vDmg = vAttack * vBullet / BDM * (1 + vNormalDamageDealtRateIn) * ( 1 + vNormalDamageTakenRateIn); float DDR = 0.0f; float DTR = 0.0f; float finaly_dmg = vDmg * vEbc * vEd * (1 + DDR) * (1 + DTR); return std::max(1.0f, std::round(finaly_dmg)); } float BattleDataContext::CalcDmg(Obstacle* target, IBullet* bullet) { g_calc_dmg_context = {0}; g_calc_dmg_context.is_crit = 0; #ifdef NEW_NUM return GetTotalAtk(bullet); #else g_calc_dmg_context.is_crit = IsCrit(bullet) ? 1 : 0; float total_atk = GetTotalAtk(bullet); float normal_dmg = total_atk * (1 - 0 / 1000); float crit = g_calc_dmg_context.is_crit ? GetCritRate(bullet) : 0; float finaly_dmg = normal_dmg * (1.0f + crit); #ifdef MYDEBUG if (owner_.Get()->IsPlayer()) { std::string data = a8::Format ("数值: 子弹攻击物件 total_atk:%f normal_dmg:%f crit:%f finaly_dmg:%f target_def:%f", { total_atk, normal_dmg, crit, finaly_dmg, 0 }); owner_.Get()->SendDebugMsg(data); } #endif if (g_calc_dmg_context.is_crit) { g_calc_dmg_context.crit_dmg = finaly_dmg; } return finaly_dmg; #endif } float BattleDataContext::CalcReceiveDmg(Creature* sender, float normal_dmg) { float finaly_dmg = normal_dmg * (1 - owner_.Get()->GetNetData()->GetDef() / (sender->GetNetData()->GetDef() + 200)); finaly_dmg *= (1 + sender->GetAbility()->GetAttrAddition(kHVAT_Dmg)); //连加 #if 1 if (owner_.Get()->GetAbility()->GetAttrRuduce(kHVAT_Dmg) > 0.0001) { finaly_dmg *= owner_.Get()->GetAbility()->GetAttrRuduce(kHVAT_Dmg); //(1-减免) 连乘 } #else finaly_dmg *= (1 - owner_.Get()->GetAbility()->GetAttrRuduce(kHVAT_Dmg)); //(1-减免) 连乘 #endif finaly_dmg = std::max(1.0f, finaly_dmg); return std::round(finaly_dmg); } float BattleDataContext::CalcSkillReceiveDmg(Creature* sender, float normal_dmg) { g_calc_dmg_context = {0}; g_calc_dmg_context.is_crit = 0; float vEbc = 1.0f; float vEd = 1 - GetDef(); float X = (1 + sender->GetNetData()->GetHeroAbility()->GetCrit()) * (1 - GetBlock()) - 1; if (X > 0.00001f) { //触发暴击 float vCritBon = sender->GetNetData()->GetHeroAbility()->hero_meta->GetBasicMeta()->vOrigCriBon(); float E = ProEffect(X, vCritBon); //E >= 0 if (E > 0.00001f) { vEbc = 1 + E; } } else { //触发格挡 0,-1 float vBlock = GetHeroAbility()->hero_meta->GetBasicMeta()->vOrigBloDef(); float E = ProEffect(X, -vBlock); //E >= 0 if (E < 0.00001f) { vEbc = 1 + E; } } float BDM = 100; float vSkillDamageDealtRateIn = 0.0f; float vSkillDamageTakenRateIn = 0.0f; float vDmg = normal_dmg * (1 + vSkillDamageDealtRateIn) * (1 + vSkillDamageTakenRateIn); float DDR = 0.0f; float DTR = 0.0f; float finaly_dmg = vDmg * vEbc * vEd * (1 + DDR) * (1 + DTR); return std::max(1.0f, std::round(finaly_dmg)); } float BattleDataContext::CalcDmg(Explosion* e) { g_calc_dmg_context = {0}; float finaly_dmg = e->GetDmg(); #ifdef MYDEBUG if (owner_.Get()->IsPlayer()) { std::string data = a8::Format ("数值: 爆炸伤害 finaly_dmg:%f def:%f", { finaly_dmg, GetDef() }); owner_.Get()->SendDebugMsg(data); } #endif return finaly_dmg; } float BattleDataContext::GetTotalAtk(IBullet* bullet) { float direct_atk = owner_.Get()->GetAbility()->GetAttrDirect(kXHAT_Atk); if (direct_atk > 0.001f) { return direct_atk; } else { float total_atk = (GetHeroTotalAtk() / 100) * GetWeaponAtk(bullet); return total_atk; } } float BattleDataContext::GetMaxHP() { float hp = hero_ability_->GetHP(); hp += owner_.Get()->GetAbility()->GetAttrAbs(kXHAT_Hp); hp *= 1.0f + owner_.Get()->GetAbility()->GetAttrRate(kXHAT_Hp); hp *= 1.0f + owner_.Get()->GetAbility()->GetAttrAddition(kXHAT_Hp) - owner_.Get()->GetAbility()->GetAttrRuduce(kXHAT_Hp); return hp; } float BattleDataContext::GetDef() { float def = hero_ability_->GetDef(); return def; } float BattleDataContext::GetHeroTotalAtk() { float atk = hero_ability_->GetAtk(); return atk; } float BattleDataContext::GetWeaponAtk(IBullet* bullet) { float atk = 0.0f; auto weapon = GetWeaponByUniId(bullet->GetWeaponUniId()); if (weapon) { atk = weapon->GetAtk(); } else { atk = bullet->GetGunMeta()->_atk; } atk *= (1 + owner_.Get()->GetAbility()->GetAttrAddition(kHVAT_WeaponAtk)); return atk; } std::shared_ptr BattleDataContext::GetWeaponByUniId(long long weapon_uuid) { if (weapon1_ability_ && weapon1_ability_->weapon_uniid == weapon_uuid) { return weapon1_ability_; } if (weapon2_ability_ && weapon2_ability_->weapon_uniid == weapon_uuid) { return weapon2_ability_; } return nullptr; } void BattleDataContext::ForceInit(long long hero_uniid, const mt::Hero* hum_meta, long long weapon1_uniid, const mt::Equip* weapon1_meta, long long weapon2_uniid, const mt::Equip* weapon2_meta) { hero_ability_->hero_uniid_ = hero_uniid; hero_ability_->hero_meta = hum_meta; if (weapon1_uniid && weapon1_meta) { weapon1_ability_ = std::make_shared(); weapon1_ability_->weapon_uniid = weapon1_uniid; weapon1_ability_->weapon_meta = weapon1_meta; } if (weapon2_uniid && weapon2_meta) { weapon2_ability_ = std::make_shared(); weapon2_ability_->weapon_uniid = weapon2_uniid; weapon2_ability_->weapon_meta = weapon2_meta; } } void BattleDataContext::Init(Creature* c) { owner_ = c->GetWeakPtrRef(); if (!hero_ability_->hero_uniid_) { hero_ability_->hero_uniid_ = App::Instance()->AllocTempHeroUniId(); } hero_ability_->Init(c); if (weapon1_ability_) { weapon1_ability_->Init(c); } if (weapon2_ability_) { weapon2_ability_->Init(c); } if (skin_id_ && c->IsHuman()) { const mt::Item* item_meta = mt::Item::GetById(skin_id_); if (item_meta) { Skin* skin = c->AsHuman()->GetSkinByIdx(0); skin->skin_id = item_meta->skinid(); } } if (c->IsPlayer()) { std::array, 2> weapons = {weapon1_ability_, weapon2_ability_}; for (auto weapon : weapons) { if (weapon) { Weapon& spec_weapon = a8::FastAppend(c->AsHuman()->spec_weapons); spec_weapon.weapon_uniid = a8::XValue(weapon->weapon_uniid); spec_weapon.weapon_id = weapon->weapon_meta->id(); spec_weapon.meta = weapon->weapon_meta; spec_weapon.Recalc(); spec_weapon.ammo = spec_weapon.GetClipVolume(c); } } } auto match_conf = owner_.Get()->room->GetRankMatchConf(); if (owner_.Get()->IsAndroid() && match_conf) { } c->NetInitOk(); } void BattleDataContext::GetSkillList(std::vector& skill_list) { const mt::Skill* spec_skill = mt::Skill::GetById(hero_ability_->spec_skill_id); const mt::Skill* skill1 = mt::Skill::GetById(hero_ability_->hero_meta->skill1list()); const mt::Skill* skill2 = mt::Skill::GetById(hero_ability_->hero_meta->skill2list()); const mt::Skill* skill3 = mt::Skill::GetById(hero_ability_->hero_meta->skill3list()); if (owner_.Get()->IsHuman()) { if (skill1 && skill2 && skill3 && skill1_lv > 0 && skill2_lv > 0 && skill3_lv > 0) { if (mt::Skill::GetById(skill1->skill_id() + skill1_lv - 1)) { skill_list.push_back(skill1->skill_id() + skill1_lv - 1); } else { skill_list.push_back(skill1->skill_id()); } //替换翻滚 if (spec_skill) { skill_list.push_back(spec_skill->skill_id()); } else { if (mt::Skill::GetById(skill2->skill_id() + skill2_lv - 2)) { skill_list.push_back(skill2->skill_id() + skill2_lv - 2); } else { skill_list.push_back(skill2->skill_id()); } } if (mt::Skill::GetById(skill3->skill_id() + skill3_lv - 3)) { skill_list.push_back(skill3->skill_id() + skill3_lv - 3); } else { skill_list.push_back(skill3->skill_id()); } } } else { std::vector skills = {skill1, skill2, skill3}; for (auto skill_meta : skills) { if (skill_meta) { skill_list.push_back(skill_meta->skill_id()); } } } } int BattleDataContext::GetClipVolume(Creature* c, Weapon* weapon) { if (!weapon->meta) { return 0; } auto p = GetWeaponByUniId(weapon->weapon_uniid); return p ? p->GetClipVolume() : weapon->meta->clip_volume(); } int BattleDataContext::GetFireRate(Creature* c, Weapon* weapon) { if (!weapon->meta) { return 0; } auto p = GetWeaponByUniId(weapon->weapon_uniid); return p ? p->GetFireRate() : weapon->meta->fire_rate(); } int BattleDataContext::GetReloadTime(Creature* c, Weapon* weapon) { if (!weapon->meta) { return 0; } auto p = GetWeaponByUniId(weapon->weapon_uniid); return p ? p->GetReloadTime() : weapon->meta->reload_time(); } float BattleDataContext::GetExtRecoverHp() { return 0; } void BattleDataContext::SetReviveCoin(int num) { revive_coin_ = num; } int BattleDataContext::GetReviveCoin() { return revive_coin_; } void BattleDataContext::SetMatchMode(int match_mode) { match_mode_ = match_mode; } int BattleDataContext::GetMatchMode() { return match_mode_; } bool BattleDataContext::IsCrit() { return g_calc_dmg_context.is_crit ? 1 : 0; } float BattleDataContext::GetCritDmg() { return g_calc_dmg_context.crit_dmg; } int BattleDataContext::GetSkinId() { return skin_id_; } int BattleDataContext::GetLevel() { return std::max(level_, 1); } float BattleDataContext::GetBrainLifePct() { return hero_ability_->GetBrainLifePct(); } float BattleDataContext::GetSkillCdPct() { return hero_ability_->GetSkillCdPct() + owner_.Get()->GetAbility()->GetAttrAddition(kXHAT_SkillTime); } float BattleDataContext::GetRescueTimePct() { return hero_ability_->GetRescueTimePct(); } float BattleDataContext::GetDrugTimePct() { return hero_ability_->GetDrugTimePct(); } float BattleDataContext::GetDrugEfficacyPct() { return hero_ability_->GetDrugEfficacyPct(); } float BattleDataContext::GetTenacityPct() { return hero_ability_->GetTenacityPct(); } float BattleDataContext::GetRecoverHpAdd() { return hero_ability_->GetRecoverHpAdd(); } int BattleDataContext::GetHeroLevel() { if (!owner_.Get()->IsPlayer() && hero_ability_ && hero_ability_->standard_meta) { return hero_ability_->standard_meta->level(); } return std::max(hero_lv_, 1); } int BattleDataContext::GetHeroId() { if (hero_ability_) { return hero_ability_->hero_meta->id(); } A8_ABORT(); } bool BattleDataContext::IsMainSkill(Skill* skill) { if (skill->meta->_base_skill_meta) { return hero_ability_->hero_meta->skill1list() == skill->meta->_base_skill_meta->skill_id(); } else { return hero_ability_->hero_meta->skill1list() == skill->meta->skill_id(); } } int BattleDataContext::GetRank() { return rank_; } int BattleDataContext::GetCurrentGetStar() { return current_get_star_; } int BattleDataContext::GetBattleTimes() { return battle_times_; } int BattleDataContext::GetHonor() { return honor_; } float BattleDataContext::GetBlock() { return hero_ability_->GetBlock(); }