aozhiwei 994e841017 1
2022-05-31 21:38:49 +08:00

266 lines
8.9 KiB
C++

#include "precompile.h"
#include <math.h>
#include "metamgr.h"
#include "human.h"
float* GetAttrAbsPtr(std::array<float, kHAT_End>& attr, int attr_id)
{
if (!IsValidHumanAttr(attr_id)) {
return nullptr;
}
return &attr[attr_id];
}
float* GetAttrRatePtr(std::array<float, kHAT_End>& attr, int attr_id)
{
if (!IsValidHumanAttr(attr_id)) {
return nullptr;
}
return &attr[attr_id];
}
void BattleDataContext::Clear()
{
hero_attr_abs_ = {};
hero_attr_rate_ = {};
weapon1_attr_abs_ = {};
weapon1_attr_rate_ = {};
weapon2_attr_abs_ = {};
weapon2_attr_rate_ = {};
}
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 (obj.HasKey("hero_dto") && obj.At("hero_dto")->IsObject()) {
hero_dto = obj.At("hero_dto");
hero_uniid_ = hero_dto->Get("hero_uniid", "");
if (hero_dto->HasKey("attr") && hero_dto->IsArray()) {
ApplyAttr(hero_attr_abs_,
hero_attr_rate_,
hero_dto->At("attr"));
}
}
if (obj.HasKey("weapon_dto1") && obj.At("weapon_dto1")->IsObject()) {
weapon_dto1 = obj.At("weapon_dto1");
weapon_uniid1_ = weapon_dto1->Get("gun_uniid", 0);
if (weapon_dto1->HasKey("attr") && weapon_dto1->IsArray()) {
ApplyAttr(weapon1_attr_abs_,
weapon1_attr_rate_,
weapon_dto1->At("attr"));
}
}
if (obj.HasKey("weapon_dto2") && obj.At("weapon_dto2")->IsObject()) {
weapon_dto2 = obj.At("weapon_dto2");
weapon_uniid2_ = weapon_dto2->Get("gun_uniid", 0);
if (weapon_dto2->HasKey("attr") && weapon_dto2->IsArray()) {
ApplyAttr(weapon2_attr_abs_,
weapon2_attr_rate_,
weapon_dto2->At("attr"));
}
}
}
float BattleDataContext::GetHeroAttrAbs(long long hero_uniid, int attr_id)
{
if (hero_uniid && hero_uniid == hero_uniid_) {
if (IsValidHumanAttr(attr_id)) {
return hero_attr_abs_[attr_id];
}
}
return 0;
}
float BattleDataContext::GetHeroAttrRate(long long hero_uniid, int attr_id)
{
if (hero_uniid && hero_uniid == hero_uniid_) {
if (IsValidHumanAttr(attr_id)) {
return hero_attr_rate_[attr_id]/ 100.0f;
}
}
return 0;
}
float BattleDataContext::GetWeaponAttrAbs(long long weapon_uniid, int attr_id)
{
if (!weapon_uniid) {
return 0;
}
if (IsValidHumanAttr(attr_id)) {
if (weapon_uniid == weapon_uniid1_) {
return weapon1_attr_abs_[attr_id];
} else if (weapon_uniid == weapon_uniid2_) {
return weapon2_attr_abs_[attr_id];
}
}
return 0;
}
float BattleDataContext::GetWeaponAttrRate(long long weapon_uniid, int attr_id)
{
if (!weapon_uniid) {
return 0;
}
if (IsValidHumanAttr(attr_id)) {
if (weapon_uniid == weapon_uniid1_) {
return weapon1_attr_rate_[attr_id];
} else if (weapon_uniid == weapon_uniid2_) {
return weapon2_attr_rate_[attr_id];
}
}
return 0;
}
void BattleDataContext::ApplyAttr(std::array<float, kHAT_End>& attr_abs,
std::array<float, kHAT_End>& attr_rate,
std::shared_ptr<a8::XObject> obj)
{
if (obj->IsArray()) {
for (int i = 0; i < obj->Size(); ++i) {
std::shared_ptr<a8::XObject> obj = obj->At(i);
if (obj->IsObject()) {
int attr_id = obj->Get("attr_id", 0);
int type = obj->Get("type", 0);
int val = obj->Get("val", 0);
if (type == 1) {
float* p = GetAttrAbsPtr(attr_abs, attr_id);
if (p) {
*p = val;
}
} else if (type == 2) {
float* p = GetAttrRatePtr(attr_rate, attr_id);
if (p) {
*p = val;
}
}
}
}
}
}
void BattleDataContext::GetHeroLvQualit(int& hero_lv, int& quality)
{
hero_lv = 0;
quality = 0;
if (hero_uniid_) {
hero_lv = hero_dto->Get("hero_lv", 0).GetInt();
quality = hero_dto->Get("quality", 0).GetInt();
}
}
void BattleDataContext::GetWeaponLvQualit(int& weapon_lv, int& quality)
{
weapon_lv = 0;
quality = 0;
if (weapon_uniid1_) {
weapon_lv += weapon_dto1->Get("gun_lv", 0).GetInt();
quality += weapon_dto1->Get("quality", 0).GetInt();
}
if (weapon_uniid2_) {
weapon_lv += weapon_dto2->Get("gun_lv", 0).GetInt();
quality += weapon_dto2->Get("quality", 0).GetInt();
}
}
void BattleDataContext::CalcBattleStat(struct PlayerStats* stats)
{
auto CalcHeroPvpCeg =
[] (long long ceg_uplimit, struct PlayerStats* stats) -> long long
{
MetaData::FormulaPvp* meta = MetaMgr::Instance()->GetFormulaPvp(stats->ranked_topx);
if (!meta) {
return 0;
}
long long ceg = round
(
ceg_uplimit *
(
(0.5 * stats->ranked_topx * meta->i->ranked_topx()) +
(0.25 * stats->kills_topx * meta->i->kills_topx()) +
(0.15 * stats->hero_topx * meta->i->hero_topx()) +
(0.5 * stats->weapon_topx * meta->i->weapon_topx()) +
(0.5 * stats->survival_topx * meta->i->survival_topx())
)
);
return ceg;
};
auto CalcWeaponPvpCeg =
[] (long long ceg_uplimit, struct PlayerStats* stats) -> long long
{
MetaData::FormulaPvp* meta = MetaMgr::Instance()->GetFormulaPvp(stats->ranked_topx);
if (!meta) {
return 0;
}
long long ceg = round
(
ceg_uplimit *
(
(0.5 * stats->ranked_topx * meta->i->ranked_topx()) +
(0.25 * stats->kills_topx * meta->i->kills_topx()) +
(0.15 * stats->hero_topx * meta->i->hero_topx()) +
(0.5 * stats->weapon_topx * meta->i->weapon_topx()) +
(0.5 * stats->survival_topx * meta->i->survival_topx())
)
);
return ceg;
};
if (hero_uniid_) {
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();
MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(hero_id);
MetaData::HeroQuality* quality_meta = MetaMgr::Instance()->GetHeroQuality(quality);
stats->pb_hero_stats.set_hero_uniid(a8::XValue(hero_uniid_).GetString());
stats->pb_hero_stats.set_hero_id(hero_id);
stats->pb_hero_stats.set_hero_name(hero_meta ? hero_meta->i->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.set_ceg_uplimit(up_limit);
stats->pb_hero_stats.set_today_get_ceg
(std::min(up_limit, today_get_gold + finaly_ceg));
stats->pb_hero_stats.set_reward_ceg(finaly_ceg);
}
}
std::vector<std::shared_ptr<a8::XObject>> 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();
MetaData::Item* item_meta = MetaMgr::Instance()->GetItem(gun_id);
MetaData::GunQuality* quality_meta = MetaMgr::Instance()->GetGunQuality(quality);
auto p = stats->pb_weapons_stats.Add();
p->set_weapon_uniid(gun_uniid);
p->set_weapon_id(gun_id);
p->set_weapon_name(item_meta ? item_meta->i->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->set_ceg_uplimit(up_limit);
p->set_today_get_ceg
(std::min(up_limit, today_get_gold + finaly_ceg));
p->set_reward_ceg(finaly_ceg);
}
}
}