From 7894df25e00badff5e3dc77ece075757960a635c Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Sun, 29 May 2022 12:54:53 +0800 Subject: [PATCH] 1 --- server/gameserver/human.cc | 124 ++++++++++++++---------- server/gameserver/human.h | 2 + server/gameserver/metadata.cc | 44 +++++++++ server/gameserver/metadata.h | 8 ++ server/gameserver/metamgr.cc | 28 ++++++ server/gameserver/metamgr.h | 1 + server/gameserver/types.cc | 94 ++++++++++++++++++ server/gameserver/types.h | 2 + server/tools/protobuild/cs_proto.proto | 22 ++--- server/tools/protobuild/metatable.proto | 13 +++ 10 files changed, 277 insertions(+), 61 deletions(-) diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 611736ee..e4d4c327 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -40,57 +40,57 @@ const int kReviveTimeAdd = 12; const int kSkinNum = 4; +static double TopXFunc (Human* sender, std::function cmpFunc) +{ + std::vector> rank_list; + sender->room->TraverseHumanList + (a8::XParams(), + [cmpFunc, &rank_list] (Human* hum, a8::XParams& param) -> bool + { + bool found = false; + 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({hum})); + } + return true; + }); + std::sort + (rank_list.begin(), rank_list.end(), + [cmpFunc] (const std::vector& a, const std::vector& b ) + { + 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; + } + } + + double topx = (double)rank / rank_list.size(); + return topx; +}; + void PlayerStats::Statement(Human* sender) { - auto topxFunc = - [sender] (std::function cmpFunc) -> double - { - std::vector> rank_list; - sender->room->TraverseHumanList - (a8::XParams(), - [cmpFunc, &rank_list] (Human* hum, a8::XParams& param) -> bool - { - bool found = false; - 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({hum})); - } - return true; - }); - std::sort - (rank_list.begin(), rank_list.end(), - [cmpFunc] (const std::vector& a, const std::vector& b ) - { - 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; - } - } - - double topx = (double)rank / rank_list.size(); - return topx; - }; - sender->stats.ranked_topx = (double)sender->stats.rank / sender->room->GetHumanNum(); - sender->stats.kills_topx = topxFunc + sender->stats.kills_topx = TopXFunc ( + sender, [] (Human* a, Human* b) -> int { if (a->stats.kills == b->stats.kills) { @@ -102,8 +102,9 @@ void PlayerStats::Statement(Human* sender) } } ); - sender->stats.hero_topx = topxFunc + sender->stats.hero_topx = TopXFunc ( + sender, [] (Human* a, Human* b) -> int { long long a_value = 0; @@ -129,8 +130,9 @@ void PlayerStats::Statement(Human* sender) } } ); - sender->stats.weapon_topx = topxFunc + sender->stats.weapon_topx = TopXFunc ( + sender, [] (Human* a, Human* b) -> int { long long a_value = 0; @@ -156,8 +158,9 @@ void PlayerStats::Statement(Human* sender) } } ); - sender->stats.survival_topx = topxFunc + sender->stats.survival_topx = TopXFunc ( + sender, [] (Human* a, Human* b) -> int { if (a->dead && b->dead) { @@ -185,6 +188,9 @@ void PlayerStats::Statement(Human* sender) } } ); + if (sender->GetBattleContext()) { + sender->GetBattleContext()->CalcBattleStat(this); + } statemented = 1; } @@ -629,6 +635,8 @@ void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb) skin.ToPB(pb_skin); } } + *stats_pb->mutable_hero_stats() = stats.pb_hero_stats; + *stats_pb->mutable_weapons_stats() = stats.pb_weapons_stats; } void Human::GetAabbBox(AabbCollider& aabb_box) @@ -2113,6 +2121,22 @@ void Human::GenBattleReportData(a8::MutableXObject* params) params->SetVal("hero_topx", stats.hero_topx); params->SetVal("weapon_topx", stats.weapon_topx); params->SetVal("survival_topx", stats.survival_topx); + + params->SetVal("hero_stats_uniid", stats.pb_hero_stats.hero_uniid()); + params->SetVal("hero_stats_name", stats.pb_hero_stats.hero_name()); + params->SetVal("hero_stats_hero_id", stats.pb_hero_stats.hero_id()); + params->SetVal("hero_stats_reward_ceg", stats.pb_hero_stats.reward_ceg()); + params->SetVal("hero_stats_ceg_uplimit", stats.pb_hero_stats.ceg_uplimit()); + + for (int i = 0; i < stats.pb_weapons_stats.size(); ++i) { + auto& p = stats.pb_weapons_stats.Get(i); + std::string i_str = a8::XValue(i).GetString(); + params->SetVal("weapon_stats_uniid" + i_str, p.weapon_uniid()); + params->SetVal("weapon_stats_name" + i_str, p.weapon_name()); + params->SetVal("weapon_stats_weapon_id" + i_str, p.weapon_id()); + params->SetVal("weapon_stats_reward_ceg" + i_str, p.reward_ceg()); + params->SetVal("weapon_stats_ceg_uplimit" + i_str, p.ceg_uplimit()); + } } } diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 6a11b2a1..140e7250 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -107,6 +107,8 @@ struct PlayerStats double hero_topx = 0; double weapon_topx = 0; double survival_topx = 0; + ::cs::MFHeroStats pb_hero_stats; + ::google::protobuf::RepeatedPtrField<::cs::MFWeaponStats> pb_weapons_stats; WeaponStats& MustBeWeapon(int weapon_id); void IncWeaponKills(int weapon_id, int val); diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index adec64a7..c3125335 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -1565,4 +1565,48 @@ namespace MetaData } + long long HeroQuality::GetPvpCegUpLimit() + { + double sys_param = 0; + double lucky = i->lucky(); + long long up_limit = round + ( + ( + 0.0402*pow(i->quality(),3) - + 0.9459*pow(i->quality(),2) + + 11.9664*i->quality() + + 4.01892 + ) + + ( + 0.0268*pow(lucky, 3) - + 2.15712*pow(lucky, 2) + + 60.944*lucky - + 560.24 + ) + ) + sys_param; + return up_limit; + } + + long long GunQuality::GetPvpCegUpLimit() + { + double sys_param = 0; + double lucky = i->lucky(); + long long up_limit = round + ( + ( + 0.0111*pow(i->quality(),3) - + 0.25974*pow(i->quality(),2) + + 3.29292*i->quality() + + 1.3389 + ) + + ( + 0.0074*pow(lucky, 3) - + 0.59396*pow(lucky, 2) + + 16.7708*lucky - + 153.964 + ) + ) + sys_param; + return up_limit; + } + } diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index d553b5a2..eae1a76b 100644 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -323,6 +323,11 @@ namespace MetaData const metatable::KillPoint* i = nullptr; }; + struct FormulaPvp + { + const metatable::FormulaPvp* i = nullptr; + }; + struct GunTalentGrow { const metatable::GunTalentGrow* i = nullptr; @@ -335,11 +340,14 @@ namespace MetaData struct HeroQuality { const metatable::HeroQuality* i = nullptr; + + long long GetPvpCegUpLimit(); }; struct GunQuality { const metatable::GunQuality* i = nullptr; + long long GetPvpCegUpLimit(); }; struct AI diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index b369c261..0cbd94e2 100644 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -190,6 +190,9 @@ public: std::list text_meta_list; std::list terrain_meta_list; std::list talent_meta_list; + std::list formula_pvp_meta_list; + std::list hero_quality_meta_list; + std::list gun_quality_meta_list; std::map parameter_hash; std::map gamemap_hash; @@ -228,6 +231,8 @@ public: std::map text_hash; std::map> talent_hash; std::map>> text_element_hash; + std::map hero_quality_hash; + std::map gun_quality_hash; int curr_group_id = 1001; std::map weapon_group_hash; @@ -278,6 +283,9 @@ public: f8::ReadCsvMetaFile(res_path + "ai@ai.csv", ai_meta_list); f8::ReadCsvMetaFile(res_path + "text@text.csv", text_meta_list); f8::ReadCsvMetaFile(res_path + "gunTalentGrow@gunTalentGrow.csv", talent_meta_list); + f8::ReadCsvMetaFile(res_path + "pvp@formula.csv", formula_pvp_meta_list); + f8::ReadCsvMetaFile(res_path + "heroQuality@heroQuality.csv", hero_quality_meta_list); + f8::ReadCsvMetaFile(res_path + "gunQuality@gunQuality.csv", gun_quality_meta_list); f8::ReadJsonMetaFile(res_path + "terrain.json", terrain_meta_list); BindToMetaData(); #if 1 @@ -907,6 +915,18 @@ private: talent_hash[a8::MakeInt64(meta.talent_id(), meta.talent_lv())] = item; } + for (auto& meta : hero_quality_meta_list) { + MetaData::HeroQuality item; + item.i = &meta; + hero_quality_hash[meta.quality()] = item; + } + + for (auto& meta : gun_quality_meta_list) { + MetaData::GunQuality item; + item.i = &meta; + gun_quality_hash[meta.quality()] = item; + } + } private: @@ -1251,3 +1271,11 @@ MetaData::GunQuality* MetaMgr::GetGunQuality(int quality) { return nullptr; } + +MetaData::FormulaPvp* MetaMgr::GetFormulaPvp(float ranked_topx) +{ + for (auto& meta : loader_->formula_pvp_meta_list) { + + } + return nullptr; +} diff --git a/server/gameserver/metamgr.h b/server/gameserver/metamgr.h index 3d32ba28..dff24357 100644 --- a/server/gameserver/metamgr.h +++ b/server/gameserver/metamgr.h @@ -65,6 +65,7 @@ class MetaMgr : public a8::Singleton MetaData::AI* GetHeroAI(int id); MetaData::HeroQuality* GetHeroQuality(int quality); MetaData::GunQuality* GetGunQuality(int quality); + MetaData::FormulaPvp* GetFormulaPvp(float ranked_topx); std::string GetText(const std::string& textid, const std::string& def_text=""); bool HasText(const std::string& textid); std::vector>* GetTextElements(const std::string& textid); diff --git a/server/gameserver/types.cc b/server/gameserver/types.cc index 8677e626..cfb2d2e4 100644 --- a/server/gameserver/types.cc +++ b/server/gameserver/types.cc @@ -1,5 +1,6 @@ #include "precompile.h" #include "metamgr.h" +#include "human.h" float* GetAttrAbsPtr(std::array& attr, int attr_id) { @@ -162,3 +163,96 @@ void BattleDataContext::GetWeaponLvQualit(int& weapon_lv, int& quality) 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_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(); + 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_reward_ceg(finaly_ceg); + } + } +} diff --git a/server/gameserver/types.h b/server/gameserver/types.h index b6e11cdd..eac165ca 100644 --- a/server/gameserver/types.h +++ b/server/gameserver/types.h @@ -44,6 +44,8 @@ struct BattleDataContext void ParseResult(a8::XObject& obj); + void CalcBattleStat(struct PlayerStats* stats); + private: void Clear(); void ApplyAttr(std::array& attr_abs, diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 03b58a6a..58cafdd8 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -711,21 +711,21 @@ message MFEmote //英雄结算信息 message MFHeroStats { - optional string hero_unnid = 1; //英雄唯一id - optional string hero_name = 2; //英雄名称 - optional int32 hero_id = 3; //英雄唯id - optional int32 reward_ceg = 4; //英雄获得的ceg数量 - optional int32 ceg_uplimit = 5; //英雄获得的ceg数量上限 + optional string hero_uniid = 1 [default = ""]; //英雄唯一id + optional string hero_name = 2 [default = ""]; //英雄名称 + optional int32 hero_id = 3 [default = 0]; //英雄唯id + optional int32 reward_ceg = 4 [default = 0]; //英雄获得的ceg数量 + optional int32 ceg_uplimit = 5 [default = 0]; //英雄获得的ceg数量上限 } //武器结算信息 message MFWeaponStats { - optional string weapon_unnid = 60; //武器唯一id - optional string weapon_name = 6; //武器名称 - optional int32 weapon_id = 62; //武器唯id - optional int32 reward_ceg = 63; //武器获得的ceg数量 - optional int32 ceg_uplimit = 64; //武器获得的ceg数量上限 + optional string weapon_uniid = 1 [default = ""]; //武器唯一id + optional string weapon_name = 2 [default = ""]; //武器名称 + optional int32 weapon_id = 3 [default = 0]; //武器唯id + optional int32 reward_ceg = 4 [default = 0]; //武器获得的ceg数量 + optional int32 ceg_uplimit = 5 [default = 0]; //武器获得的ceg数量上限 } //游戏结束时玩家统计信息 @@ -774,7 +774,7 @@ message MFPlayerStats repeated MFSkin skin = 45; //皮肤id optional MFHeroStats hero_stats = 46; //英雄结算信息 - optional MFWeaponStats weapons_stats = 47; //武器结算信息 + repeated MFWeaponStats weapons_stats = 47; //武器结算信息 } //空投 diff --git a/server/tools/protobuild/metatable.proto b/server/tools/protobuild/metatable.proto index c3a1db0d..10fbecfa 100755 --- a/server/tools/protobuild/metatable.proto +++ b/server/tools/protobuild/metatable.proto @@ -127,6 +127,7 @@ message Item optional int32 isdefaultskin = 7; optional int32 playerid = 8; optional int32 relationship = 9; + optional string name = 10; } message Equip @@ -437,6 +438,7 @@ message HeroQuality optional int32 id = 1; optional int32 quality = 2; optional int32 gold_limit = 3; + optional int32 lucky = 4; } message GunQuality @@ -444,6 +446,17 @@ message GunQuality optional int32 id = 1; optional int32 quality = 2; optional int32 gold_limit = 3; + optional int32 lucky = 4; +} + +message FormulaPvp +{ + optional float top = 1; + optional float ranked_topx = 2; + optional float kills_topx = 3; + optional float hero_topx = 4; + optional float weapon_topx = 5; + optional float survival_topx = 6; } //end