aozhiwei 424752982e 1
2023-04-02 20:44:22 +08:00

380 lines
12 KiB
C++

#include "precompile.h"
#include "stats.h"
#include "human.h"
#include "room.h"
#include "netdata.h"
static double TopXFunc (Human* sender,
std::function<int (Human*, Human*)> cmpFunc,
bool need_group,
std::function<bool (Human*)> validFunc)
{
std::vector<std::vector<Human*>> rank_list;
double topx = 0.0f;
#if 0
sender->room->TraverseHumanList
(a8::XParams(),
[cmpFunc, &rank_list, need_group] (Human* hum, a8::XParams& param) -> bool
{
bool found = false;
if (need_group) {
for (auto& list : rank_list) {
if (cmpFunc(list[0], hum) == 0) {
list.push_back(hum);
found = true;
}
}
}
if (!found) {
rank_list.push_back(std::vector<Human*>({hum}));
}
return true;
});
std::sort
(rank_list.begin(), rank_list.end(),
[cmpFunc] (const std::vector<Human*>& a, const std::vector<Human*>& b )
{
a8::XPrintf("id1:%d dead:%d id2:%d dead:%d cmpRet:%d\n",
{
a[0]->GetUniId(),
a[0]->dead ? 1 :0,
b[0]->GetUniId(),
b[0]->dead ? 1 :0,
cmpFunc(a[0], b[0])
});
return cmpFunc(a[0], b[0]) > 0;
});
int rank = rank_list.size();
for (int i = 0; i < rank_list.size(); ++i){
bool found = false;
for (Human* hum : rank_list[i]) {
if (hum == sender){
rank = i + 1;
found = true;
break;
}
}
if (found) {
break;
}
}
#if 1
double topx = (double)rank / 40.0f;
if (!validFunc(sender)) {
topx = 40.0f / 40.0f;
}
#else
double topx = (double)rank / rank_list.size();
#endif
#endif
return topx;
};
void PlayerStats::Statement(Human* sender)
{
sender->stats->ranked_topx = (double)sender->stats->rank / sender->room->GetHumanNum();
sender->stats->kills_topx = TopXFunc
(
sender,
[] (Human* a, Human* b) -> int
{
if (a->stats->kills == b->stats->kills) {
return 0;
} else if (a->stats->kills > b->stats->kills) {
return 1;
} else {
return -1;
}
},
true,
[] (Human* hum)
{
return hum->stats->kills > 0;
}
);
sender->stats->hero_topx = TopXFunc
(
sender,
[] (Human* a, Human* b) -> int
{
long long a_value = 0;
long long b_value = 0;
if (a->GetBattleContext()) {
long long hero_uniid = 0;
int hero_lv = 0;
int quality = 0;
a->GetBattleContext()->GetHeroLvQuality(hero_uniid, hero_lv, quality);
a_value = hero_lv + quality;
}
if (b->GetBattleContext()) {
long long hero_uniid = 0;
int hero_lv = 0;
int quality = 0;
b->GetBattleContext()->GetHeroLvQuality(hero_uniid, hero_lv, quality);
b_value = hero_lv + quality;
}
if (a_value == b_value) {
return 0;
} else if (a_value > b_value) {
return 1;
} else {
return -1;
}
},
true,
[] (Human* hum)
{
if (hum->GetBattleContext()) {
long long hero_uniid = 0;
int hero_lv = 0;
int quality = 0;
hum->GetBattleContext()->GetHeroLvQuality(hero_uniid, hero_lv, quality);
return hero_lv + quality > 0;
}
return false;
}
);
sender->stats->weapon_topx = TopXFunc
(
sender,
[] (Human* a, Human* b) -> int
{
long long a_value = 0;
long long b_value = 0;
if (a->GetBattleContext()) {
long long weapon_uniid = 0;
int weapon_lv = 0;
int quality = 0;
a->GetBattleContext()->GetWeaponLvQuality(weapon_uniid, weapon_lv, quality);
a_value = weapon_lv + quality;
}
if (b->GetBattleContext()) {
long long weapon_uniid = 0;
int weapon_lv = 0;
int quality = 0;
b->GetBattleContext()->GetWeaponLvQuality(weapon_uniid, weapon_lv, quality);
b_value = weapon_lv + quality;
}
if (a_value == b_value) {
return 0;
} else if (a_value > b_value) {
return 1;
} else {
return -1;
}
},
true,
[] (Human* hum)
{
if (hum->GetBattleContext()) {
long long weapon_uniid = 0;
int weapon_lv = 0;
int quality = 0;
hum->GetBattleContext()->GetWeaponLvQuality(weapon_uniid, weapon_lv, quality);
return weapon_lv + quality > 0;
}
return false;
}
);
sender->stats->survival_topx = TopXFunc
(
sender,
[] (Human* a, Human* b) -> int
{
if (a->dead && b->dead) {
if (a->dead_frameno == b->dead_frameno) {
return 0;
} else if (a->dead_frameno > b->dead_frameno) {
return 1;
} else {
return -1;
}
} else {
if (!a->dead && !b->dead) {
return 0;
} else {
if (!a->dead) {
return 1;
} else {
return -1;
}
}
}
},
true,
[] (Human* hum)
{
return true;
}
);
if (sender->GetBattleContext()) {
sender->GetBattleContext()->CalcBattleStat(this);
}
game_time = time(nullptr);
statemented = 1;
}
WeaponStats& PlayerStats::MustBeWeapon(int weapon_id)
{
auto itr = weapon_stats.find(weapon_id);
if (itr == weapon_stats.end()){
WeaponStats weapon;
weapon_stats[weapon_id] = weapon;
itr = weapon_stats.find(weapon_id);
}
return itr->second;
}
void PlayerStats::IncWeaponKills(int weapon_id, int val)
{
MustBeWeapon(weapon_id).kills += val;
}
void PlayerStats::IncWeaponDamageOut(int weapon_id, int val)
{
MustBeWeapon(weapon_id).damage_out += val;
}
void PlayerStats::IncWeaponObtainCount(int weapon_id, int val)
{
MustBeWeapon(weapon_id).obtain_count += val;
}
void PlayerStats::IncWeaponUseTimes(int weapon_id, int val)
{
MustBeWeapon(weapon_id).use_times += val;
}
HeroStats& PlayerStats::MustBeHero(int hero_id)
{
auto itr = hero_stats.find(hero_id);
if (itr == hero_stats.end()){
HeroStats hero;
hero_stats[hero_id] = hero;
itr = hero_stats.find(hero_id);
}
return itr->second;
}
void PlayerStats::SetHeroSkillLv(int hero_id, int skill_lv)
{
MustBeHero(hero_id).skill_lv = std::max(MustBeHero(hero_id).skill_lv, skill_lv);
}
void PlayerStats::SetHeroWeaponLv(int hero_id, int weapon_lv)
{
MustBeHero(hero_id).weapon_lv = std::max(MustBeHero(hero_id).weapon_lv, weapon_lv);
}
void PlayerStats::ParseReward(Human* hum, a8::XObject& xobj)
{
if (!xobj.IsObject()) {
AdjustRewardData();
return;
}
auto reward_xobj = xobj.At("reward");
if (!reward_xobj || !reward_xobj->IsObject()) {
AdjustRewardData();
return;
}
over_reward.total_ceg = reward_xobj->At("total_ceg")->AsXValue().GetString();
{
auto hero_xobj = reward_xobj->At("hero");
if (hero_xobj && hero_xobj->IsObject()) {
over_reward.hero.curr_gold = hero_xobj->At("curr_ceg") ?
hero_xobj->At("curr_ceg")->AsXValue().GetString() : "0";
over_reward.hero.obtain_gold = hero_xobj->At("obtain_ceg")->AsXValue().GetString();
over_reward.hero.gold_limit = hero_xobj->At("ceg_uplimit")->AsXValue().GetString();
if (hum->GetBattleContext()->hero_dto &&
hum->GetBattleContext()->hero_dto->IsObject()) {
over_reward.hero.id = hum->GetBattleContext()->hero_dto->At("hero_id")->AsXValue();
}
}
}
{
auto weapon_xobj = reward_xobj->At("weapon1");
if (weapon_xobj && weapon_xobj->IsObject()) {
over_reward.weapon1.curr_gold = weapon_xobj->At("curr_ceg") ?
weapon_xobj->At("curr_ceg")->AsXValue().GetString() : "";
over_reward.weapon1.obtain_gold = weapon_xobj->At("obtain_ceg")->AsXValue().GetString();
over_reward.weapon1.gold_limit = weapon_xobj->At("ceg_uplimit")->AsXValue().GetString();
if (hum->GetBattleContext()->weapon_dto1 &&
hum->GetBattleContext()->weapon_dto1->IsObject()) {
over_reward.weapon1.id = hum->GetBattleContext()->weapon_dto1->At("gun_id")->AsXValue();
}
}
}
{
auto weapon_xobj = reward_xobj->At("weapon2");
if (weapon_xobj && weapon_xobj->IsObject()) {
over_reward.weapon2.curr_gold = weapon_xobj->At("curr_ceg") ?
weapon_xobj->At("curr_ceg")->AsXValue().GetString() : "0";
over_reward.weapon2.obtain_gold = weapon_xobj->At("obtain_ceg")->AsXValue().GetString();
over_reward.weapon2.gold_limit = weapon_xobj->At("ceg_uplimit")->AsXValue().GetString();
if (hum->GetBattleContext()->weapon_dto2 &&
hum->GetBattleContext()->weapon_dto2->IsObject()) {
over_reward.weapon2.id = hum->GetBattleContext()->weapon_dto2->At("gun_id")->AsXValue();
}
}
}
{
auto items_xobj = reward_xobj->At("items");
if (items_xobj && items_xobj->IsArray()) {
for (int i = 0; i < items_xobj->Size(); ++i) {
auto item_xobj = items_xobj->At(i);
if (item_xobj && item_xobj->IsObject()) {
over_reward.items.push_back
(std::make_tuple
(
item_xobj->At("item_id")->AsXValue(),
item_xobj->At("item_num")->AsXValue()
)
);
}
}
}
}
{
auto score_info_xobj = xobj.At("score_info");
if (score_info_xobj && score_info_xobj->IsObject()) {
old_rank = score_info_xobj->At("old_rank")->AsXValue();
new_rank = score_info_xobj->At("new_rank")->AsXValue();
old_score = score_info_xobj->At("old_score")->AsXValue();
new_score = score_info_xobj->At("new_score")->AsXValue();
}
}
AdjustRewardData();
}
void PlayerStats::AdjustRewardData()
{
auto EmptyStrToZero =
[] (std::string& str) {
if (str.empty()) {
str = "0";
}
};
EmptyStrToZero(over_reward.total_ceg);
{
EmptyStrToZero(over_reward.hero.curr_gold);
EmptyStrToZero(over_reward.hero.obtain_gold);
EmptyStrToZero(over_reward.hero.gold_limit);
}
{
EmptyStrToZero(over_reward.weapon1.curr_gold);
EmptyStrToZero(over_reward.weapon1.obtain_gold);
EmptyStrToZero(over_reward.weapon1.gold_limit);
}
{
EmptyStrToZero(over_reward.weapon2.curr_gold);
EmptyStrToZero(over_reward.weapon2.obtain_gold);
EmptyStrToZero(over_reward.weapon2.gold_limit);
}
}