380 lines
12 KiB
C++
380 lines
12 KiB
C++
#include "precompile.h"
|
|
|
|
#include "stats.h"
|
|
#include "human.h"
|
|
#include "room.h"
|
|
#include "battledatacontext.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);
|
|
}
|
|
}
|