2005 lines
68 KiB
C++
2005 lines
68 KiB
C++
#include "precompile.h"
|
|
|
|
#include <math.h>
|
|
#include <float.h>
|
|
|
|
#include <a8/mutable_xobject.h>
|
|
|
|
#include <f8/udplog.h>
|
|
#include <f8/utils.h>
|
|
|
|
#include "cs_proto.pb.h"
|
|
#include "cs_msgid.pb.h"
|
|
#include "ss_proto.pb.h"
|
|
#include "ss_msgid.pb.h"
|
|
|
|
#include "pbutils.h"
|
|
#include "ability.h"
|
|
#include "killmgr.h"
|
|
#include "room.h"
|
|
#include "player.h"
|
|
#include "human.h"
|
|
#include "weapon.h"
|
|
#include "buff.h"
|
|
#include "effect.h"
|
|
#include "car.h"
|
|
#include "hero.h"
|
|
#include "loot.h"
|
|
#include "obstacle.h"
|
|
#include "roomobstacle.h"
|
|
#include "skill.h"
|
|
#include "skin.h"
|
|
#include "typeconvert.h"
|
|
#include "team.h"
|
|
#include "roommgr.h"
|
|
#include "httpproxy.h"
|
|
#include "jsondatamgr.h"
|
|
#include "gamelog.h"
|
|
#include "GGListener.h"
|
|
#include "playermgr.h"
|
|
#include "matchmgr.h"
|
|
#include "frag_mitask.h"
|
|
#include "smoke_mitask.h"
|
|
#include "stats.h"
|
|
|
|
#include "mt/Param.h"
|
|
#include "mt/Buff.h"
|
|
#include "mt/Item.h"
|
|
#include "mt/Equip.h"
|
|
#include "mt/Hero.h"
|
|
#include "mt/MapThing.h"
|
|
#include "mt/Skill.h"
|
|
#include "mt/SafeArea.h"
|
|
#include "mt/Map.h"
|
|
#include "mt/PveGemini.h"
|
|
#include "mt/PveGeminiMode.h"
|
|
#include "mt/PveGeminiContent.h"
|
|
|
|
static void Creature_FillBuffList(Creature* self, Human* hum, ::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_buff_list)
|
|
{
|
|
self->TraverseBuff
|
|
(
|
|
[hum, pb_buff_list] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff->NeedSync(hum) && buff->IsValid()) {
|
|
auto p = pb_buff_list->Add();
|
|
buff->FillMFBuff(p);
|
|
}
|
|
});
|
|
}
|
|
|
|
static void Creature_FillEffectList(Creature* self, Human* hum, ::google::protobuf::RepeatedPtrField<::cs::MFEffect>* pb_effect_list)
|
|
{
|
|
self->TraverseEffect
|
|
(
|
|
[hum, pb_effect_list] (Effect* effect, bool& stop)
|
|
{
|
|
auto p = pb_effect_list->Add();
|
|
effect->FillMFEffect(p);
|
|
});
|
|
}
|
|
|
|
static void Creature_FillSkillList(Creature* self, ::google::protobuf::RepeatedPtrField< cs::MFSkill >*
|
|
pb_skill_list)
|
|
{
|
|
self->TraverseSkill
|
|
(
|
|
[self, pb_skill_list] (Skill* skill, bool& stop)
|
|
{
|
|
auto p = pb_skill_list->Add();
|
|
skill->FillMFSkill(p);
|
|
});
|
|
}
|
|
|
|
static void Human_FillItemList(Human* self,
|
|
std::map<int, int>& items,
|
|
::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_item_list)
|
|
{
|
|
for (auto& pair : items) {
|
|
auto p = pb_item_list->Add();
|
|
p->set_key(pair.first);
|
|
p->set_value(pair.second);
|
|
}
|
|
}
|
|
|
|
static void Human_FillBodyState(Human* self, ::google::protobuf::RepeatedPtrField<::cs::MFBodyState>* states)
|
|
{
|
|
if (!self->pain_killer_timer.expired()) {
|
|
int passed_time = (self->room->GetFrameNo() - self->pain_killer_frameno) * FRAME_RATE_MS;
|
|
int left_time = std::max(0, self->pain_killer_lastingtime * 1000 - passed_time);
|
|
int anodyne_max_time = mt::Param::GetIntParam("anodyne_max_time");
|
|
left_time = std::min(left_time, anodyne_max_time * 1000);
|
|
|
|
cs::MFBodyState* state = states->Add();
|
|
state->set_state_type(1);
|
|
state->set_left_time(left_time);
|
|
state->set_lasting_time(anodyne_max_time * 1000);
|
|
}
|
|
}
|
|
|
|
void PBUtils::Ability_FillMFAttrAdditionList(Ability* self, Human* hum, cs::MFActivePlayerData* player_data)
|
|
{
|
|
_Ability_FillMFAttrAdditionList
|
|
(self,
|
|
hum,
|
|
[player_data] ()
|
|
{
|
|
return player_data->add_attr_addition();
|
|
});
|
|
}
|
|
|
|
void PBUtils::Ability_FillMFAttrAdditionList(Ability* self, Human* hum, cs::MFPlayerFull* full_data)
|
|
{
|
|
_Ability_FillMFAttrAdditionList
|
|
(self,
|
|
hum,
|
|
[full_data] ()
|
|
{
|
|
return full_data->add_attr_addition();
|
|
});
|
|
}
|
|
|
|
void PBUtils::_Ability_FillMFAttrAdditionList(Ability* self,
|
|
Human* hum,
|
|
std::function<cs::MFAttrAddition* ()> add_func
|
|
)
|
|
{
|
|
#if 0
|
|
for (int attr_id = 0; attr_id < kHAT_End; ++attr_id) {
|
|
if (!(attr_id == 12 || attr_id == 33)) {
|
|
continue;
|
|
}
|
|
if (self->buff_attr_flag_[attr_id]) {
|
|
auto pb_attr = add_func();
|
|
pb_attr->set_attr_id(attr_id);
|
|
pb_attr->set_abs_val(self->buff_attr_abs_[attr_id]);
|
|
#if 1
|
|
pb_attr->set_rate_val(self->buff_attr_rate_[attr_id]);
|
|
#else
|
|
pb_attr->set_rate_val(self->buff_attr_rate_[attr_id] * 100);
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
master.name
|
|
killer.name
|
|
dead.name
|
|
weapon.name
|
|
weapon.text_icon
|
|
image.id:
|
|
*/
|
|
void KillMgr::OnHumanDead(Human* dead_hum, KillInfo* info)
|
|
{
|
|
RollMsgHintInfo hint_info;
|
|
std::shared_ptr<cs::SMRollMsg> pb_msg = std::make_shared<cs::SMRollMsg>();
|
|
FillHintInfo(dead_hum, info, hint_info);
|
|
PreprocessRollMsg(pb_msg, hint_info);
|
|
BoradcastRollMsg(dead_hum, info, 0, pb_msg);
|
|
}
|
|
|
|
void KillMgr::PreprocessRollMsg(std::shared_ptr<cs::SMRollMsg> pb_msg,
|
|
RollMsgHintInfo& hint_info)
|
|
{
|
|
if (hint_info.hint_template) {
|
|
for (auto& tuple : *hint_info.hint_template) {
|
|
int el_type = std::get<0>(tuple);
|
|
std::string el_val = std::get<1>(tuple);
|
|
switch (el_type) {
|
|
case kTextElement:
|
|
{
|
|
auto e = pb_msg->add_elements();
|
|
e->set_element_type(el_type);
|
|
e->mutable_union_obj_1()->set_text(el_val);
|
|
}
|
|
break;
|
|
case kImageElement:
|
|
{
|
|
auto e = pb_msg->add_elements();
|
|
e->set_element_type(el_type);
|
|
e->mutable_union_obj_2()->set_id(a8::XValue(el_val));
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
std::string text;
|
|
if (hint_info.Replace(el_type, text)) {
|
|
if (el_type == kFieldIdxWeaponTextIcon) {
|
|
auto e = pb_msg->add_elements();
|
|
e->set_element_type(kImageElement);
|
|
e->mutable_union_obj_2()->set_id(a8::XValue(text));
|
|
} else {
|
|
auto e = pb_msg->add_elements();
|
|
e->set_element_type(kTextElement);
|
|
e->mutable_union_obj_1()->set_text(text);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KillMgr::BoradcastRollMsg(Human* dead_hum,
|
|
KillInfo* info,
|
|
int killer_team_id,
|
|
std::shared_ptr<cs::SMRollMsg> pb_msg)
|
|
{
|
|
std::shared_ptr<KillInfo> info_copy = std::make_shared<KillInfo>();
|
|
*info_copy = *info;
|
|
std::shared_ptr<cs::SMRollMsg> pb_msg_copy = std::make_shared<cs::SMRollMsg>();
|
|
pb_msg_copy = pb_msg;
|
|
dead_hum->room->xtimer.SetTimeoutEx
|
|
(
|
|
0,
|
|
[dead_hum, info_copy, pb_msg_copy, killer_team_id]
|
|
(int event, const a8::Args* args) mutable
|
|
{
|
|
if (a8::TIMER_EXEC_EVENT == event) {
|
|
KillMgr::Instance()->BoradcastRollMsgCb
|
|
(dead_hum,
|
|
info_copy.get(),
|
|
killer_team_id,
|
|
pb_msg_copy);
|
|
}
|
|
},
|
|
&dead_hum->xtimer_attacher);
|
|
}
|
|
|
|
void KillMgr::BoradcastRollMsgCb(Human* dead_hum,
|
|
KillInfo* info,
|
|
int killer_team_id,
|
|
std::shared_ptr<cs::SMRollMsg> pb_msg)
|
|
{
|
|
dead_hum->room->TraversePlayerList
|
|
(
|
|
[dead_hum, info, &pb_msg, killer_team_id]
|
|
(Player* hum) -> bool
|
|
{
|
|
for (int i = 0; i < pb_msg->elements_size(); ++i) {
|
|
auto element = pb_msg->mutable_elements(i);
|
|
if (element->element_type() == kTextElement) {
|
|
int color = element->mutable_union_obj_1()->color();
|
|
if (info->killer_id == hum->GetUniId()){
|
|
color = mt::Param::s().self_kill_color;
|
|
} else if (killer_team_id == hum->team_id) {
|
|
color = mt::Param::s().teammate_kill_color;
|
|
} else if (dead_hum == hum) {
|
|
color = mt::Param::s().self_bekill_color;
|
|
} else if (dead_hum->team_id == hum->team_id) {
|
|
color = mt::Param::s().teammate_bekill_color;
|
|
}
|
|
if (element->mutable_union_obj_1()->color() != color) {
|
|
element->mutable_union_obj_1()->set_color(color);
|
|
}
|
|
}
|
|
}
|
|
hum->SendNotifyMsg(*pb_msg);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
void Weapon::ToPB(Creature* c, cs::MFWeapon* pb_obj)
|
|
{
|
|
pb_obj->set_weapon_uniid(a8::XValue(weapon_uniid).GetString());
|
|
pb_obj->set_weapon_id(weapon_id);
|
|
if (weapon_uniid && weapon_lv == 0) {
|
|
int p_weapon_lv = 1;
|
|
int p_quality = 1;
|
|
c->GetBattleContext()->GetWeaponLvQuality(weapon_uniid, p_weapon_lv, p_quality);
|
|
weapon_lv = p_weapon_lv;
|
|
}
|
|
pb_obj->set_weapon_lv(std::max(1, weapon_lv));
|
|
pb_obj->set_ammo(ammo);
|
|
pb_obj->set_volume(GetClipVolume(c));
|
|
}
|
|
|
|
void Buff::FillMFBuff(cs::MFBuff* buff_pb)
|
|
{
|
|
buff_pb->set_buff_id(meta->buff_id());
|
|
buff_pb->set_left_time(GetLeftTime());
|
|
buff_pb->set_lasting_time(GetLastingTime());
|
|
buff_pb->set_buff_uniid(buff_uniid);
|
|
if (res_scale_frameno > 0) {
|
|
buff_pb->set_res_scale(res_scale);
|
|
}
|
|
if (owner->IsHuman() &&
|
|
(meta->buff_effect() == kBET_Driver ||
|
|
meta->buff_effect() == kBET_Passenger)) {
|
|
}
|
|
}
|
|
|
|
void Effect::FillMFEffect(cs::MFEffect* effect_pb)
|
|
{
|
|
effect_pb->set_effect_id(effect_id);
|
|
effect_pb->set_effect_uniid(effect_uniid);
|
|
}
|
|
|
|
void Car::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
|
|
{
|
|
part_data->set_object_type(ET_Car);
|
|
cs::MFCarPart* p = part_data->mutable_union_obj_11();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
}
|
|
|
|
void Car::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
|
|
{
|
|
full_data->set_object_type(ET_Car);
|
|
cs::MFCarFull* p = full_data->mutable_union_obj_11();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
p->set_car_id(meta->id());
|
|
p->set_heroid(meta->heroid());
|
|
p->set_driver(driver_ ? driver_->GetUniId() : 0);
|
|
for (auto hum : passengers_) {
|
|
auto less_data = p->add_passengers();
|
|
hum->FillMFObjectLess(room, hum, less_data);
|
|
}
|
|
p->set_born_frameno(ceil(born_frameno_ / 2.0));
|
|
p->set_dead(dead);
|
|
p->set_health(GetHP());
|
|
p->set_max_health(GetMaxHP());
|
|
p->set_oil(cur_oil_);
|
|
p->set_max_oil(meta->max_oil());
|
|
if (GetCurrWeapon()) {
|
|
p->set_bullet_num(GetCurrWeapon()->ammo);
|
|
} else {
|
|
p->set_bullet_num(0);
|
|
}
|
|
p->set_seat_num(meta->_int_param2);
|
|
Creature_FillBuffList(this, hum, p->mutable_buff_list());
|
|
Creature_FillEffectList(this, hum, p->mutable_effect_list());
|
|
p->set_team_id(team_id);
|
|
}
|
|
|
|
void Hero::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
|
|
{
|
|
part_data->set_object_type(ET_Hero);
|
|
cs::MFHeroPart* p = part_data->mutable_union_obj_10();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
}
|
|
|
|
void Hero::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
|
|
{
|
|
full_data->set_object_type(ET_Hero);
|
|
cs::MFHeroFull* p = full_data->mutable_union_obj_10();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
p->set_heroid(meta->id());
|
|
p->set_master_uniid(master.Get() ? master.Get()->GetUniId() : 0);
|
|
p->set_dead(dead);
|
|
p->set_health(GetHP());
|
|
p->set_max_health(GetMaxHP());
|
|
Creature_FillBuffList(this, hum, p->mutable_buff_list());
|
|
Creature_FillEffectList(this, hum, p->mutable_effect_list());
|
|
p->set_team_id(team_id);
|
|
}
|
|
|
|
void Loot::FillMFObjectPart( Room* room, Human* hum, cs::MFObjectPart* part_data)
|
|
{
|
|
part_data->set_object_type(ET_Loot);
|
|
cs::MFLootPart* p = part_data->mutable_union_obj_5();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
}
|
|
|
|
void Loot::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
|
|
{
|
|
full_data->set_object_type(ET_Loot);
|
|
cs::MFLootFull* p = full_data->mutable_union_obj_5();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(born_pos, p->mutable_born_pos());
|
|
|
|
p->set_item_id(item_id);
|
|
p->set_count(count);
|
|
p->set_item_level(item_level);
|
|
if (show_anim && room->GetFrameNo() <= create_frame_no + 1) {
|
|
p->set_show_anim(true);
|
|
}
|
|
}
|
|
|
|
void Obstacle::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
|
|
{
|
|
part_data->set_object_type(ET_Obstacle);
|
|
cs::MFObstaclePart* p = part_data->mutable_union_obj_2();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
if (std::abs(scale - 1.0f) > 0.00001f) {
|
|
p->set_scale(scale);
|
|
}
|
|
}
|
|
|
|
void Obstacle::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
|
|
{
|
|
full_data->set_object_type(ET_Obstacle);
|
|
if (IsClientCached(hum)) {
|
|
int object_flags = 0;
|
|
a8::SetBitFlag(object_flags, kOfReadCache);
|
|
full_data->set_obj_uniid(GetUniId());
|
|
full_data->set_object_flags(object_flags);
|
|
return;
|
|
}
|
|
|
|
cs::MFObstacleFull* p = full_data->mutable_union_obj_2();
|
|
if (CanClientCache(hum)) {
|
|
int object_flags = 0;
|
|
a8::SetBitFlag(object_flags, kOfWriteCache);
|
|
#if 0
|
|
full_data->set_obj_uniid(GetUniId());
|
|
#endif
|
|
full_data->set_object_flags(object_flags);
|
|
AddClientCache(hum);
|
|
}
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
if (std::abs(scale - 1.0f) > 0.00001f) {
|
|
p->set_scale(scale);
|
|
}
|
|
|
|
p->set_obstacle_id(meta->thing_id());
|
|
p->set_health(GetHealth(room));
|
|
p->set_dead(IsDead(room));
|
|
p->set_dead_at_thisframe(IsDead(room) ? GetDeadFrameNo(room) <= room->GetFrameNo() : false);
|
|
|
|
if (!IsPermanent()) {
|
|
RoomObstacle* ob = (RoomObstacle*)this;
|
|
p->set_born_frameno(ceil(ob->born_frameno / 2.0));
|
|
}
|
|
|
|
if (meta->thing_type() == kObstacleHideHouse) {
|
|
#if 0
|
|
if (GetInteractionData(hum)) {
|
|
#if 1
|
|
p->set_button_name("3");
|
|
#else
|
|
p->set_button_name("脱离");
|
|
#endif
|
|
} else {
|
|
#if 1
|
|
p->set_button_name("2");
|
|
#else
|
|
p->set_button_name("躲藏");
|
|
#endif
|
|
}
|
|
#endif
|
|
} else {
|
|
if (IsOpenInteraction()) {
|
|
if (IsDead(hum->room)) {
|
|
p->set_button_name("");
|
|
} else {
|
|
#if 1
|
|
p->set_button_name("1");
|
|
#else
|
|
p->set_button_name("开启");
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
if (meta->thing_type() == kObstacleStrengthenWall) {
|
|
p->set_rotate(rotate_ * 180);
|
|
}
|
|
p->set_team_id(GetTeamId(room));
|
|
}
|
|
|
|
void Skill::FillMFSkill(cs::MFSkill* skill_pb)
|
|
{
|
|
skill_pb->set_skill_id(meta->skill_id());
|
|
skill_pb->set_left_time(GetLeftTime());
|
|
skill_pb->set_cd_time(GetCd());
|
|
skill_pb->set_curr_times(GetCurrTimes());
|
|
skill_pb->set_max_times(GetMaxTimes());
|
|
if (minor_type_) {
|
|
int minor_left_time = std::max
|
|
(0,
|
|
minor_cd_time_ - (int)((owner->room->GetFrameNo() - minor_frameno_) * FRAME_RATE_MS));
|
|
skill_pb->set_minor_type(minor_type_);
|
|
skill_pb->set_minor_left_time(minor_left_time);
|
|
skill_pb->set_minor_cd_time(minor_cd_time_);
|
|
skill_pb->set_left_time(GetCd());
|
|
#ifdef DEBUG
|
|
a8::XPrintf("type: %d, lefttime:%d cd_time:%d\n", {
|
|
minor_type_,
|
|
minor_left_time,
|
|
minor_cd_time_
|
|
});
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void Skin::ToPB(cs::MFSkin* pb_obj)
|
|
{
|
|
pb_obj->set_skin_id(skin_id);
|
|
pb_obj->set_skin_lv(skin_lv);
|
|
}
|
|
|
|
void PBUtils::Human_SendSMPvePassWave(Human* self, int new_wave, int pve_max_wave, int wait_time)
|
|
{
|
|
cs::SMPvePassWave notify_msg;
|
|
notify_msg.set_new_wave(new_wave);
|
|
notify_msg.set_pve_max_wave(pve_max_wave);
|
|
notify_msg.set_pve_max_wave(wait_time);
|
|
self->SendNotifyMsg(notify_msg);
|
|
}
|
|
|
|
void Human::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
|
|
{
|
|
part_data->set_object_type(ET_Player);
|
|
cs::MFPlayerPart* p = part_data->mutable_union_obj_1();
|
|
p->set_obj_uniid(GetUniId());
|
|
p->set_speed(GetSpeed() * SERVER_FRAME_RATE);
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
}
|
|
|
|
void Human::FillMFObjectLess(Room* room, Human* hum, cs::MFPlayerFull* full_data)
|
|
{
|
|
cs::MFPlayerFull* p = full_data;
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
|
|
p->set_health(GetHP());
|
|
p->set_max_health(GetMaxHP());
|
|
p->set_dead(dead);
|
|
p->set_downed(downed);
|
|
p->set_disconnected(disconnected);
|
|
for (auto itr : skins) {
|
|
auto skin = p->add_skin();
|
|
itr.ToPB(skin);
|
|
}
|
|
p->set_backpack(backpack);
|
|
p->set_helmet(helmet);
|
|
p->set_chest(chest);
|
|
p->set_shoot_offset_x(shoot_offset.x);
|
|
p->set_shoot_offset_y(shoot_offset.y);
|
|
p->set_level(GetBattleContext()->GetLevel());
|
|
p->set_hero_level(GetBattleContext()->GetHeroLevel());
|
|
p->set_hero_level(GetBattleContext()->GetHeroLevel());
|
|
GetCurrWeapon()->ToPB(this, p->mutable_weapon());
|
|
PBUtils::Ability_FillMFAttrAdditionList(GetAbility().get(), this, p);
|
|
if (GetCar()) {
|
|
p->set_car_uniid(GetCar()->car_uniid);
|
|
p->set_car_seat(GetSeat());
|
|
} else {
|
|
p->set_car_uniid(0);
|
|
p->set_car_seat(0);
|
|
}
|
|
}
|
|
|
|
void Human::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
|
|
{
|
|
full_data->set_object_type(ET_Player);
|
|
cs::MFPlayerFull* p = full_data->mutable_union_obj_1();
|
|
p->set_obj_uniid(GetUniId());
|
|
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), p->mutable_dir());
|
|
|
|
p->set_health(GetHP());
|
|
p->set_level(GetBattleContext()->GetLevel());
|
|
p->set_Hero_level(GetBattleContext()->GetHeroLevel());
|
|
p->set_max_health(GetMaxHP());
|
|
p->set_dead(dead);
|
|
p->set_downed(downed);
|
|
p->set_disconnected(disconnected);
|
|
p->set_speed(GetSpeed() * SERVER_FRAME_RATE);
|
|
for (auto itr : skins) {
|
|
auto skin = p->add_skin();
|
|
itr.ToPB(skin);
|
|
}
|
|
p->set_backpack(backpack);
|
|
p->set_helmet(helmet);
|
|
p->set_chest(chest);
|
|
p->set_team_member_num(GetTeam()->GetMemberNum());
|
|
GetCurrWeapon()->ToPB(this, p->mutable_weapon());
|
|
p->set_energy_shield(energy_shield);
|
|
p->set_gemstone(gemstone);
|
|
p->set_shoot_offset_x(shoot_offset.x);
|
|
p->set_shoot_offset_y(shoot_offset.y);
|
|
#if 1
|
|
{
|
|
p->set_max_energy_shield(max_energy_shield);
|
|
}
|
|
#endif
|
|
if (guild_id != 0) {
|
|
p->set_guild_id(guild_id);
|
|
}
|
|
if (vip_lv != 0) {
|
|
p->set_vip_lv(vip_lv);
|
|
}
|
|
if (head_frame != 0) {
|
|
p->set_head_frame(head_frame);
|
|
}
|
|
if (sex != 0) {
|
|
p->set_sex(sex);
|
|
}
|
|
if (!user_data.empty()) {
|
|
p->set_user_data(user_data);
|
|
}
|
|
p->set_vip(vip);
|
|
p->set_kill_count(stats->kills);
|
|
if (emoji1 != 0) {
|
|
p->set_emoji1(emoji1);
|
|
}
|
|
if (emoji2 != 0) {
|
|
p->set_emoji2(emoji2);
|
|
}
|
|
if (parachute != 0) {
|
|
p->set_parachute(parachute);
|
|
}
|
|
if (IsPlayer()) {
|
|
int i = 0;
|
|
}
|
|
if (follow_target.Get()) {
|
|
p->set_follow_target(follow_target.Get()->GetUniId());
|
|
#ifdef DEBUG1
|
|
a8::XPrintf("DoFollow1 %d->%d\n", {GetUniId(), follow_target.Get()->GetUniId()});
|
|
#endif
|
|
}
|
|
Human_FillBodyState(this, p->mutable_states());
|
|
Creature_FillBuffList(this, hum, p->mutable_buff_list());
|
|
Creature_FillEffectList(this, hum, p->mutable_effect_list());
|
|
Creature_FillSkillList(this, p->mutable_skill_list());
|
|
if (dead) {
|
|
p->set_killer_name(stats->killer_name);
|
|
p->set_killer_id(stats->killer_id);
|
|
if (real_dead){
|
|
p->set_can_revive(false);
|
|
} else {
|
|
p->set_can_revive(true);
|
|
int countdown = 0;
|
|
if (!revive_timer.expired()) {
|
|
countdown = std::ceil(room->xtimer.GetRemainTime(revive_timer) / SERVER_FRAME_RATE);
|
|
} else {
|
|
f8::UdpLog::Instance()->Warning
|
|
("Human::FillMFObjectfull revive_timer == nullptr "
|
|
"dead_frameno:%d dead_times:%d alive_count:%d "
|
|
"room.frameno:%d",
|
|
{
|
|
dead_frameno,
|
|
stats->dead_times,
|
|
room->AliveCount(),
|
|
room->GetFrameNo()
|
|
});
|
|
}
|
|
countdown = std::max(0, countdown - kReviveTimeAdd);
|
|
p->set_revive_countdown(countdown);
|
|
}
|
|
}
|
|
p->set_charid(meta->id());
|
|
if (GetCar()) {
|
|
p->set_car_uniid(GetCar()->car_uniid);
|
|
p->set_car_seat(GetSeat());
|
|
} else {
|
|
p->set_car_uniid(0);
|
|
p->set_car_seat(0);
|
|
}
|
|
if (GetBuffByEffectId(kBET_HoldShield)) {
|
|
p->set_shield_hp(shield_hp_);
|
|
p->set_shield_max_hp(shield_max_hp_);
|
|
}
|
|
p->set_team_id(team_id);
|
|
}
|
|
|
|
void Human::FillMFObjectImage(Room* room, Human* hum, cs::MFCharacterImage* image_data)
|
|
{
|
|
image_data->set_obj_uniid(GetUniId());
|
|
image_data->set_cur_weapon_idx(GetCurrWeapon()->weapon_idx);
|
|
GetCurrWeapon()->ToPB(this, image_data->mutable_weapon());
|
|
}
|
|
|
|
void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb)
|
|
{
|
|
stats_pb->set_player_id(GetUniId());
|
|
stats_pb->set_player_avatar_url(avatar_url);
|
|
stats_pb->set_charid(meta->id());
|
|
stats_pb->set_team_id(team_id);
|
|
stats_pb->set_nickname(name);
|
|
|
|
int alive_time = room->GetFrameNo() * FRAME_RATE_MS;
|
|
if (!dead) {
|
|
stats_pb->set_time_alive(alive_time);
|
|
} else {
|
|
alive_time = (dead_frameno - room->GetBattleStartFrameNo()) * FRAME_RATE_MS;
|
|
if (room->GetBattleStartFrameNo() <= 0) {
|
|
alive_time = 0;
|
|
}
|
|
alive_time = std::max(alive_time, 0);
|
|
stats_pb->set_time_alive(alive_time);
|
|
}
|
|
|
|
stats_pb->set_kills(stats->kills);
|
|
stats_pb->set_damage_amount(stats->damage_amount_out);
|
|
stats_pb->set_heal_amount(stats->heal_amount);
|
|
|
|
stats_pb->set_assist(stats->assist);
|
|
stats_pb->set_rescue(stats->rescue_member);
|
|
stats_pb->set_pve_wave(stats->pve_wave);
|
|
stats_pb->set_revive(stats->revive);
|
|
stats_pb->set_rank_chg(stats->rank_chg);
|
|
|
|
stats_pb->set_history_time_alive(stats->history_time_alive);
|
|
stats_pb->set_history_kills(stats->history_kills);
|
|
stats_pb->set_history_damage_amount(stats->history_damage_amount);
|
|
stats_pb->set_history_heal_amount(stats->history_heal_amount);
|
|
|
|
stats_pb->set_gold(stats->gold);
|
|
#if 1
|
|
stats_pb->set_score(stats->pve_rank_score);
|
|
#else
|
|
stats_pb->set_score(stats->score);
|
|
#endif
|
|
stats_pb->set_pass_score(stats->pass_score);
|
|
stats_pb->set_rank_score(stats->rank_score);
|
|
stats_pb->set_has_pass(has_pass);
|
|
|
|
stats_pb->set_dead(dead);
|
|
stats_pb->set_killer_id(stats->killer_id);
|
|
stats_pb->set_killer_name(stats->killer_name);
|
|
{
|
|
Player* killer = room->GetPlayerByUniId(stats->killer_id);
|
|
if (killer) {
|
|
stats_pb->set_killer_avatar_url(killer->avatar_url);
|
|
stats_pb->set_killer_account_id(killer->account_id);
|
|
} else {
|
|
stats_pb->set_killer_avatar_url("");
|
|
stats_pb->set_killer_account_id("");
|
|
}
|
|
}
|
|
|
|
stats_pb->set_account_id(account_id);
|
|
if (guild_id != 0) {
|
|
stats_pb->set_guild_id(guild_id);
|
|
}
|
|
stats_pb->set_rescue_guild_member(stats->rescue_guild_member);
|
|
|
|
for (auto& pair : stats->items) {
|
|
auto p = stats_pb->add_items();
|
|
p->set_key(pair.first);
|
|
p->set_value(pair.second);
|
|
}
|
|
for (auto& pair : stats->extra_drop) {
|
|
auto p = stats_pb->add_extra_drop();
|
|
p->set_key(pair.first);
|
|
p->set_value(pair.second);
|
|
}
|
|
if (vip_lv != 0) {
|
|
stats_pb->set_vip_lv(vip_lv);
|
|
}
|
|
if (head_frame != 0) {
|
|
stats_pb->set_head_frame(head_frame);
|
|
}
|
|
if (sex != 0) {
|
|
stats_pb->set_sex(sex);
|
|
}
|
|
{
|
|
for (auto& skin : skins) {
|
|
auto pb_skin = stats_pb->add_skin();
|
|
skin.ToPB(pb_skin);
|
|
}
|
|
}
|
|
TypeConvert::ToPb(stats->pb_hero_stats, stats_pb->mutable_hero_stats());
|
|
for (auto& itr : stats->pb_weapons_stats) {
|
|
TypeConvert::ToPb(itr, stats_pb->add_weapons_stats());
|
|
}
|
|
}
|
|
|
|
void Human::FillMFTeamData(Human* hum, cs::MFTeamData* team_data, bool is_game_over)
|
|
{
|
|
{
|
|
last_sync_teamdata_frameno_ = room->GetFrameNo();
|
|
|
|
team_data->set_team_id(team_id);
|
|
team_data->set_player_id(GetUniId());
|
|
team_data->set_hero_id(meta->id());
|
|
team_data->set_level(hum->GetBattleContext()->GetLevel());
|
|
team_data->set_hero_level(hum->GetBattleContext()->GetHeroLevel());
|
|
team_data->set_score(stats->pve_rank_score);
|
|
if (is_game_over || !real_dead || room->GetFrameNo() - GetRealDeadFrameNo(room) < 4) {
|
|
TypeConvert::ToPb(GetPos(), team_data->mutable_pos());
|
|
TypeConvert::ToPb(GetAttackDir(), team_data->mutable_dir());
|
|
team_data->set_health(GetHP());
|
|
team_data->set_max_health(GetMaxHP());
|
|
team_data->set_dead(dead);
|
|
team_data->set_downed(downed);
|
|
}
|
|
#if 1
|
|
team_data->set_dead(dead);
|
|
#endif
|
|
|
|
if (is_game_over || room->GetGasData().GetGasMode() == GasInactive) {
|
|
team_data->set_name(name);
|
|
}
|
|
|
|
if (room->GetGasData().GetGasMode() != GasInactive &&
|
|
room->GetFrameNo() - room->GetBattleStartFrameNo() < 4) {
|
|
team_data->set_name(name);
|
|
team_data->set_disconnected(socket_handle == 0);
|
|
}
|
|
|
|
if (is_game_over) {
|
|
team_data->set_account_id(account_id);
|
|
team_data->set_avatar_url(avatar_url);
|
|
team_data->set_user_value1(user_value1);
|
|
team_data->set_user_value2(user_value2);
|
|
team_data->set_user_value3(user_value3);
|
|
if (guild_id != 0) {
|
|
team_data->set_guild_id(guild_id);
|
|
}
|
|
}
|
|
if (vip_lv != 0) {
|
|
team_data->set_vip_lv(vip_lv);
|
|
}
|
|
if (head_frame != 0) {
|
|
team_data->set_head_frame(head_frame);
|
|
}
|
|
if (sex != 0) {
|
|
team_data->set_sex(sex);
|
|
}
|
|
if (room->GetGasData().GetGasMode() == GasInactive ||
|
|
room->GetFrameNo() - room->GetBattleStartFrameNo() < 4) {
|
|
team_data->set_user_data(user_data);
|
|
}
|
|
#if 0
|
|
if (HasBuffEffect(kBET_Jump) && GetTeam()) {
|
|
bool can_follow = hum->CanFollow(this);
|
|
if (can_follow) {
|
|
team_data->set_can_follow(can_follow);
|
|
}
|
|
}
|
|
#endif
|
|
{
|
|
for (auto itr : skins) {
|
|
auto skin = team_data->add_skin();
|
|
itr.ToPB(skin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::FillSMGameOver(cs::SMGameOver& msg)
|
|
{
|
|
if (GetTeam()->already_report_battle) {
|
|
msg.mutable_settlement_new()->set_settlement_status(1);
|
|
auto p = msg.mutable_settlement_new();
|
|
p->set_version(20230321);
|
|
p->set_team_id(GetTeam()->GetTeamId());
|
|
p->set_room_uuid(a8::XValue(room->GetRoomUuid()).GetString());
|
|
p->set_room_mode(room->IsPveRoom() ? 1 : 0);
|
|
p->set_team_mode(1);
|
|
p->set_game_over(room->IsGameOver() ? 1 : 0);
|
|
p->set_victory(stats->victory ? 1 : 0);
|
|
p->set_watchable(false);
|
|
p->set_map_id(room->GetMapMeta()->map_id());
|
|
p->set_battle_uuid(a8::XValue(battle_uuid).GetString());
|
|
|
|
if (room->IsPveRoom()) {
|
|
p->set_pve_settlement_color(stats->settlement_color);
|
|
p->set_pve_wave(room->pve_data.GetPassedWave());
|
|
p->set_pve_max_wave(room->pve_data.max_wave);
|
|
p->set_pve_instance_id(room->pve_instance->gemini_id());
|
|
} else {
|
|
p->set_pvp_settlement_type(stats->pvp_settlement_type);
|
|
p->set_pvp_settlement_color(stats->settlement_color);
|
|
p->set_pvp_team_rank(GetTeam()->team_rank);
|
|
p->set_pvp_total_human_num(room->GetHumanNum());
|
|
p->set_pvp_alive_human_num(room->AliveCount());
|
|
p->set_pvp_total_team_num(room->GetTeamNum());
|
|
p->set_pvp_match_mode(0);
|
|
}
|
|
GetTeam()->FillSMGameOver(msg);
|
|
return;
|
|
} else {
|
|
msg.mutable_settlement_new()->set_settlement_status(0);
|
|
auto p = msg.mutable_settlement_new();
|
|
p->set_version(20230321);
|
|
p->set_team_id(GetTeam()->GetTeamId());
|
|
p->set_room_uuid(a8::XValue(room->GetRoomUuid()).GetString());
|
|
p->set_room_mode(room->IsPveRoom() ? 1 : 0);
|
|
p->set_team_mode(1);
|
|
p->set_game_over(room->IsGameOver() ? 1 : 0);
|
|
p->set_victory(stats->victory ? 1 : 0);
|
|
{
|
|
int alive_team_num = room->GetAliveTeamNum();
|
|
|
|
if (stats->victory) {
|
|
p->set_watchable(false);
|
|
} else {
|
|
if (room->GetAliveTeamNum() > 1) {
|
|
p->set_watchable(true);
|
|
} else {
|
|
if (room->IsPveRoom()) {
|
|
p->set_watchable(!room->IsGameOver());
|
|
} else {
|
|
p->set_watchable(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
p->set_map_id(room->GetMapMeta()->map_id());
|
|
p->set_battle_uuid(a8::XValue(battle_uuid).GetString());
|
|
|
|
if (room->IsPveRoom()) {
|
|
p->set_pve_settlement_color(stats->settlement_color);
|
|
p->set_pve_wave(room->pve_data.GetPassedWave());
|
|
p->set_pve_max_wave(room->pve_data.max_wave);
|
|
p->set_pve_instance_id(room->pve_instance->gemini_id());
|
|
} else {
|
|
p->set_pvp_settlement_type(stats->pvp_settlement_type);
|
|
p->set_pvp_settlement_color(stats->settlement_color);
|
|
p->set_pvp_team_rank(GetTeam()->team_rank);
|
|
p->set_pvp_total_human_num(room->GetHumanNum());
|
|
p->set_pvp_alive_human_num(room->AliveCount());
|
|
p->set_pvp_total_team_num(room->GetTeamNum());
|
|
p->set_pvp_match_mode(0);
|
|
}
|
|
GetTeam()->FillSMGameOver(msg);
|
|
return;
|
|
}
|
|
int alive_team_num = room->GetAliveTeamNum();
|
|
|
|
if (stats->victory) {
|
|
msg.set_watchable(false);
|
|
} else {
|
|
if (room->GetAliveTeamNum() > 1) {
|
|
msg.set_watchable(true);
|
|
} else {
|
|
if (room->IsPveRoom()) {
|
|
msg.set_watchable(!room->IsGameOver());
|
|
} else {
|
|
msg.set_watchable(false);
|
|
}
|
|
}
|
|
}
|
|
msg.set_map_id(room->GetMapMeta()->map_id());
|
|
msg.set_team_id(team_id);
|
|
msg.set_team_rank(GetTeam()->team_rank);
|
|
msg.set_personal_rank(stats->rank);
|
|
if (room->IsPveRoom()) {
|
|
stats->pve_wave = room->pve_data.GetPassedWave();
|
|
msg.set_game_over(room->IsGameOver());
|
|
} else {
|
|
msg.set_game_over(room->IsGameOver() || (alive_team_num == 1));
|
|
}
|
|
msg.set_victory(stats->victory);
|
|
msg.set_room_uuid(a8::XValue(room->GetRoomUuid()));
|
|
msg.set_total_human_num(room->GetHumanNum());
|
|
msg.set_alive_human_num(room->AliveCount());
|
|
if (GetTeam()) {
|
|
GetTeam()->TraverseMembers
|
|
(
|
|
[this, &msg] (Human* member) -> bool
|
|
{
|
|
{
|
|
member->FillMFTeamData(this, msg.add_team_data(), true);
|
|
cs::MFPlayerStats* p = msg.add_player_stats();
|
|
member->FillMFPlayerStats(p);
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
{
|
|
msg.set_total_team_num(room->GetTeamNum());
|
|
if (room->IsPveRoom()) {
|
|
msg.set_pve_wave(room->pve_data.GetPassedWave());
|
|
msg.set_pve_max_wave(room->pve_data.max_wave);
|
|
msg.set_pve_instance_id(room->pve_instance->gemini_id());
|
|
msg.set_pve_boss_killed(room->pve_data.boss_state == 2 ? 1 : 0);
|
|
}
|
|
}
|
|
TypeConvert::ToPb(stats->over_reward, msg.mutable_reward());
|
|
{
|
|
if (!stats->over_reward.total_ceg.empty()) {
|
|
auto p = msg.add_spoils_items();
|
|
p->add_values("10001");
|
|
p->add_values(stats->over_reward.total_ceg);
|
|
}
|
|
for (auto& tuple : stats->over_reward.items) {
|
|
auto p = msg.add_spoils_items();
|
|
p->add_values(a8::XValue(std::get<0>(tuple)).GetString());
|
|
p->add_values(std::get<1>(tuple));
|
|
}
|
|
}
|
|
{
|
|
if (room->IsPveRoom()) {
|
|
msg.set_mode(GetTeam()->GetMemberNum() <= 1 ? 1 : 2);
|
|
msg.set_my_rank(room->pve_data.GetPassedWave());
|
|
msg.set_max_rank(room->pve_data.max_wave);
|
|
} else {
|
|
if (GetTeam()->GetMemberNum() <= 1) {
|
|
msg.set_mode(1);
|
|
msg.set_my_rank(stats->rank);
|
|
msg.set_max_rank(room->GetHumanNum());
|
|
} else {
|
|
if (GetTeam()->team_rank <= 0) {
|
|
msg.set_mode(1);
|
|
msg.set_my_rank(stats->rank);
|
|
msg.set_max_rank(room->GetHumanNum());
|
|
} else {
|
|
msg.set_mode(2);
|
|
msg.set_my_rank(GetTeam()->team_rank);
|
|
msg.set_max_rank(room->GetTeamNum());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#if 1
|
|
if (room->GetBattleStartFrameNo() <= 0 &&
|
|
dead_frameno) {
|
|
msg.set_team_rank(0);
|
|
msg.set_personal_rank(0);
|
|
msg.set_my_rank(0);
|
|
}
|
|
#endif
|
|
if (IsPlayer()) {
|
|
Player* p = (Player*)this;
|
|
if (!p->settlement) {
|
|
p->settlement = std::make_shared<cs::MFSettlement>();
|
|
FillMFSettlement(&msg, p->settlement.get());
|
|
}
|
|
*msg.mutable_settlement() = *p->settlement;
|
|
}
|
|
}
|
|
|
|
void Human::FillMFActivePlayerData(cs::MFActivePlayerData* player_data)
|
|
{
|
|
#ifdef DEBUG1
|
|
a8::XPrintf("FillMFActivePlayerData isPlayer:%d id:%d name:%s need_sync_active_player:%d send_msg_times:%d\n",
|
|
{
|
|
IsPlayer() ? 1 : 0,
|
|
GetUniId(),
|
|
name,
|
|
need_sync_active_player ? 1 : 0,
|
|
send_msg_times
|
|
});
|
|
#endif
|
|
{
|
|
player_data->set_action_type(action_type);
|
|
if (action_type != AT_None) {
|
|
int duration = std::max(0,
|
|
action_duration -
|
|
(int)((room->GetFrameNo() - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000
|
|
);
|
|
player_data->set_action_item_id(action_item_id);
|
|
player_data->set_action_duration(duration);
|
|
player_data->set_action_target_id(action_target_id);
|
|
player_data->set_action_frameno(action_frameno);
|
|
#if 1
|
|
if (action_type == AT_UseItem) {
|
|
const mt::Equip* item_meta = mt::Equip::GetByIdBySlotId(action_item_id);
|
|
if (item_meta) {
|
|
player_data->set_action_item_id(item_meta->id());
|
|
int action_param = 0;
|
|
switch (action_item_id) {
|
|
case IS_HEALTHKIT:
|
|
case IS_SHEN_BAO:
|
|
{
|
|
switch (std::get<0>(item_meta->_heal)) {
|
|
case 1:
|
|
{
|
|
action_param = std::get<1>(item_meta->_heal);
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
action_param = std::get<1>(item_meta->_heal) * GetMaxHP();
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case IS_PAIN_KILLER:
|
|
{
|
|
switch (std::get<0>(item_meta->_heal)) {
|
|
case 1:
|
|
{
|
|
action_param = std::get<1>(item_meta->_heal) * item_meta->time();
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
action_param = std::get<1>(item_meta->_heal) * GetMaxHP()
|
|
* item_meta->time();
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
player_data->set_action_param(action_param);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#if 1
|
|
for (auto itr : skins) {
|
|
auto skin = player_data->add_skin();
|
|
itr.ToPB(skin);
|
|
}
|
|
#else
|
|
skin.ToPB(player_data->mutable_skin());
|
|
#endif
|
|
player_data->set_backpack(backpack);
|
|
player_data->set_helmet(helmet);
|
|
player_data->set_chest(chest);
|
|
player_data->set_health(GetHP());
|
|
player_data->set_max_health(GetMaxHP());
|
|
player_data->set_cur_weapon_idx(GetCurrWeapon()->weapon_idx);
|
|
player_data->set_cur_scope(curr_scope_idx);
|
|
if (HasBuffEffect(kBET_InWater)) {
|
|
player_data->set_dive_oxygen_max(mt::Param::s().dive_oxygen_total);
|
|
player_data->set_dive_oxygen_curr(oxygen_);
|
|
}
|
|
for (auto& weapon : weapons) {
|
|
auto p = player_data->add_weapons();
|
|
weapon.ToPB(this, p);
|
|
}
|
|
for (auto& inv : GetInventoryData()) {
|
|
player_data->add_inventory(inv.num);
|
|
}
|
|
player_data->set_energy_shield(energy_shield);
|
|
#if 1
|
|
{
|
|
player_data->set_max_energy_shield(max_energy_shield);
|
|
}
|
|
#endif
|
|
Human_FillBodyState(this, player_data->mutable_states());
|
|
Human_FillItemList(this, this->items_, player_data->mutable_items());
|
|
Creature_FillSkillList(this, player_data->mutable_skill_list());
|
|
player_data->set_shoot_offset_x(shoot_offset.x);
|
|
player_data->set_shoot_offset_y(shoot_offset.y);
|
|
PBUtils::Ability_FillMFAttrAdditionList(GetAbility().get(), this, player_data);
|
|
if (GetBuffByEffectId(kBET_HoldShield)) {
|
|
player_data->set_shield_hp(shield_hp_);
|
|
player_data->set_shield_max_hp(shield_max_hp_);
|
|
}
|
|
player_data->set_gemstone(gemstone);
|
|
}
|
|
|
|
void Human::ProcThrowDmg(int throw_uniid)
|
|
{
|
|
auto itr = pending_throw_bomb.find(throw_uniid);
|
|
if (itr == pending_throw_bomb.end()) {
|
|
return;
|
|
}
|
|
auto context = itr->second;
|
|
|
|
glm::vec3 bomb_pos;
|
|
glm::vec3 bomb_dir;
|
|
TypeConvert::FromPb(bomb_pos, &context->pos());
|
|
TypeConvert::FromPb(bomb_dir, &context->dir());
|
|
if (!(std::abs(bomb_dir.x) > FLT_EPSILON ||
|
|
std::abs(bomb_dir.y) > FLT_EPSILON ||
|
|
std::abs(bomb_dir.z) > FLT_EPSILON
|
|
)) {
|
|
pending_throw_bomb.erase(throw_uniid);
|
|
return;
|
|
}
|
|
|
|
GlmHelper::Normalize(bomb_dir);
|
|
glm::vec3 target_pos = bomb_pos + bomb_dir * context->fly_distance();
|
|
const mt::Equip* equip_meta = mt::Equip::GetById(context->weapon_id());
|
|
if (equip_meta && equip_meta->_inventory_slot() > 0) {
|
|
|
|
auto proc_frag_func =
|
|
[this, equip_meta, context, bomb_pos, bomb_dir, target_pos] ()
|
|
{
|
|
std::shared_ptr<FragMiTask> task = std::make_shared<FragMiTask>();
|
|
task->room = room;
|
|
task->sender.Attach(this);
|
|
task->bomb_pos.FromGlmVec3(target_pos);
|
|
task->gun_meta = equip_meta;
|
|
task->meta = equip_meta;
|
|
task->atk = equip_meta->_atk;
|
|
task->explosion_range = equip_meta->explosion_range();
|
|
task->Initialize();
|
|
int delay_time = equip_meta->missiles_time();;
|
|
room->xtimer.SetTimeoutEx
|
|
(std::max(1, (int)(delay_time / FRAME_RATE_MS)),
|
|
[task] (int event, const a8::Args* args)
|
|
{
|
|
if (a8::TIMER_EXEC_EVENT == event) {
|
|
task->Done();
|
|
}
|
|
},
|
|
&task->xtimer_attacher);
|
|
};
|
|
auto proc_smoke_func =
|
|
[this, equip_meta, context, bomb_pos, bomb_dir, target_pos] ()
|
|
{
|
|
const mt::Buff* buff_meta = mt::Buff::GetById(HUNLUAN_BUFFID);
|
|
if (!buff_meta) {
|
|
return;
|
|
}
|
|
std::shared_ptr<SmokeMiTask> task = std::make_shared<SmokeMiTask>();
|
|
task->room = room;
|
|
task->bomb_pos.FromGlmVec3(target_pos);
|
|
task->buff_meta = buff_meta;
|
|
task->gun_meta = equip_meta;
|
|
task->Initialize();
|
|
auto task_wp = std::weak_ptr<SmokeMiTask>(task);
|
|
room->xtimer.SetIntervalEx
|
|
(SERVER_FRAME_RATE / 2,
|
|
[task_wp] (int event, const a8::Args* args)
|
|
{
|
|
if (a8::TIMER_EXEC_EVENT == event) {
|
|
if (!task_wp.expired()) {
|
|
task_wp.lock()->Check();
|
|
}
|
|
}
|
|
},
|
|
&task->xtimer_attacher);
|
|
|
|
room->xtimer.SetTimeoutEx
|
|
(SERVER_FRAME_RATE * mt::Param::GetIntParam("smoke_duration", 10),
|
|
[task] (int event, const a8::Args* args)
|
|
{
|
|
if (a8::TIMER_DELETE_EVENT == event) {
|
|
task->Done();
|
|
}
|
|
},
|
|
&room->xtimer_attacher_);
|
|
{
|
|
std::shared_ptr<Ability> old_context_ability = context_ability;
|
|
glm::vec3 old_context_dir = context_dir;
|
|
Position old_context_pos = context_pos;
|
|
context_dir = bomb_dir;
|
|
context_pos.FromGlmVec3(target_pos);
|
|
context_ability = nullptr;
|
|
const mt::Buff * buff_meta = mt::Buff::GetById(equip_meta->buffid());
|
|
if (buff_meta) {
|
|
AddBuff(this,
|
|
buff_meta
|
|
);
|
|
}
|
|
context_dir = old_context_dir;
|
|
context_pos = old_context_pos;
|
|
context_ability = old_context_ability;
|
|
}
|
|
};
|
|
auto proc_molotor_cocktail_func =
|
|
[this, equip_meta, context, bomb_pos, bomb_dir, target_pos] ()
|
|
{
|
|
std::shared_ptr<Ability> old_context_ability = context_ability;
|
|
glm::vec3 old_context_dir = context_dir;
|
|
Position old_context_pos = context_pos;
|
|
context_dir = bomb_dir;
|
|
context_pos.FromGlmVec3(target_pos);
|
|
context_ability = nullptr;
|
|
const mt::Buff * buff_meta = mt::Buff::GetById(equip_meta->buffid());
|
|
if (buff_meta) {
|
|
AddBuff(this,
|
|
buff_meta
|
|
);
|
|
}
|
|
context_dir = old_context_dir;
|
|
context_pos = old_context_pos;
|
|
context_ability = old_context_ability;
|
|
};
|
|
switch (equip_meta->_inventory_slot()) {
|
|
case IS_FRAG:
|
|
{
|
|
proc_frag_func();
|
|
}
|
|
break;
|
|
case IS_SMOKE:
|
|
{
|
|
proc_smoke_func();
|
|
}
|
|
break;
|
|
case IS_MOLOTOR_COCKTAIL:
|
|
{
|
|
proc_molotor_cocktail_func();
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
|
|
}
|
|
break;
|
|
}//end switch
|
|
}
|
|
pending_throw_bomb.erase(throw_uniid);
|
|
}
|
|
|
|
void Human::FillMFGasData(cs::MFGasData* gas_data)
|
|
{
|
|
gas_data->set_mode(room->GetGasData().GetGasMode());
|
|
if (room->GetGasData().GetGasMode() == GasInactive) {
|
|
long long duration = room->GetGasInactiveTime() * SERVER_FRAME_RATE -
|
|
(room->GetFrameNo() - room->GetGasData().gas_start_frameno);
|
|
gas_data->set_duration(std::max(duration * 50, (long long)1000) / 1000);
|
|
} else if (room->GetGasData().GetGasMode() == GasJump) {
|
|
gas_data->set_duration(0);
|
|
} else if (room->GetGasData().GetGasMode() == GasMoving) {
|
|
if (room->GetGasData().new_area_meta->shrink_speed() > 0.01f) {
|
|
long long duration = (room->GetGasData().old_area_meta->rad() - room->GetGasData().new_area_meta->rad()) /
|
|
room->GetGasData().new_area_meta->shrink_speed();
|
|
++duration;
|
|
gas_data->set_duration(++duration);
|
|
} else {
|
|
gas_data->set_duration(0);
|
|
}
|
|
} else {
|
|
if (room->GetGasData().old_area_meta->wait_time() <= 0) {
|
|
gas_data->set_duration(0);
|
|
} else {
|
|
long long duration = room->GetGasData().old_area_meta->wait_time() * 20 -
|
|
(room->GetFrameNo() - room->GetGasData().gas_start_frameno);
|
|
gas_data->set_duration(std::max(duration * 50, (long long)1000) / 1000);
|
|
}
|
|
if (room->IsPveRoom()) {
|
|
gas_data->set_duration(0);
|
|
}
|
|
}
|
|
// 333
|
|
{
|
|
glm::vec3 v3(room->GetGasData().pos_old.x, 0.0f, room->GetGasData().pos_old.y);
|
|
TypeConvert::ToPb(v3, gas_data->mutable_pos_old());
|
|
}
|
|
{
|
|
glm::vec3 v3(room->GetGasData().pos_new.x, 0.0f, room->GetGasData().pos_new.y);
|
|
TypeConvert::ToPb(v3, gas_data->mutable_pos_new());
|
|
}
|
|
gas_data->set_rad_old(room->GetGasData().rad_old);
|
|
gas_data->set_rad_new(room->GetGasData().rad_new);
|
|
}
|
|
|
|
void Human::SendUpdateMsg()
|
|
{
|
|
#ifdef DEBUG
|
|
long long begin_tick1 = a8::XGetTickCount();
|
|
long long end_tick1 = a8::XGetTickCount();
|
|
#endif
|
|
if (!follow_target_ && !a8::HasBitFlag(status, CS_Disable)) {
|
|
#ifdef DEBUG
|
|
long long begin_tick = a8::XGetTickCount();
|
|
long long end_tick = a8::XGetTickCount();
|
|
#endif
|
|
cs::MFActivePlayerData* active_player_data_pb = nullptr;
|
|
if (send_msg_times == 0 || need_sync_active_player_) {
|
|
active_player_data_pb = new cs::MFActivePlayerData();
|
|
FillMFActivePlayerData(active_player_data_pb);
|
|
need_sync_active_player_ = false;
|
|
}
|
|
#ifdef DEBUG
|
|
end_tick = a8::XGetTickCount();
|
|
if (a8::XGetTickCount() - begin_tick > 1000) {
|
|
A8_ABORT();
|
|
}
|
|
begin_tick = a8::XGetTickCount();
|
|
#endif
|
|
|
|
cs::SMUpdate* msg = room->frame_maker.MakeUpdateMsg(this);
|
|
if (send_msg_times == 0 || last_sync_gas_frameno < room->GetGasData().gas_start_frameno) {
|
|
last_sync_gas_frameno = room->GetGasData().gas_start_frameno;
|
|
FillMFGasData(msg->mutable_gas_data());
|
|
}
|
|
#ifdef DEBUG
|
|
end_tick = a8::XGetTickCount();
|
|
if (a8::XGetTickCount() - begin_tick > 200) {
|
|
A8_ABORT();
|
|
}
|
|
begin_tick = a8::XGetTickCount();
|
|
#endif
|
|
NotifyObservers(msg, active_player_data_pb);
|
|
delete msg;
|
|
|
|
if (active_player_data_pb) {
|
|
delete active_player_data_pb;
|
|
}
|
|
++send_msg_times;
|
|
} else {
|
|
need_sync_active_player_ = false;
|
|
}
|
|
#ifdef DEBUG
|
|
end_tick1 = a8::XGetTickCount();
|
|
if (end_tick1 - begin_tick1 > 100) {
|
|
A8_ABORT();
|
|
}
|
|
#endif
|
|
framedata_.ClearFrameData(this);
|
|
}
|
|
|
|
void Human::SendGameOver()
|
|
{
|
|
#if 1
|
|
if (GetTeam()->HasPlayer()) {
|
|
if (GetTeam()->already_report_battle) {
|
|
cs::SMGameOver msg;
|
|
FillSMGameOver(msg);
|
|
SendNotifyMsg(msg);
|
|
} else {
|
|
CalcStats();
|
|
if (GetTeam()->team_rank) {
|
|
if (!GetTeam()->sending_battlereport) {
|
|
GetTeam()->sending_battlereport = true;
|
|
GetTeam()->SendTeamBattleReport(this);
|
|
}
|
|
} else {
|
|
cs::SMGameOver msg;
|
|
FillSMGameOver(msg);
|
|
SendNotifyMsg(msg);
|
|
}
|
|
}
|
|
}
|
|
if (IsEntitySubType(EST_Player)) {
|
|
if (!is_game_end_) {
|
|
GameLog::Instance()->GameEnd((Player*)this);
|
|
is_game_end_ = true;
|
|
}
|
|
}
|
|
#else
|
|
if (IsEntitySubType(EST_Player)) {
|
|
if (already_report_battle_) {
|
|
cs::SMGameOver msg;
|
|
FillSMGameOver(msg);
|
|
SendNotifyMsg(msg);
|
|
#ifdef DEBUG
|
|
if (!f8::IsTestEnv()) {
|
|
a8::XPrintf("gameOver %s\n", {f8::PbToJson(&msg)});
|
|
}
|
|
#endif
|
|
} else {
|
|
if (!sending_battlereport_) {
|
|
sending_battlereport_ = true;
|
|
SendBattleReport();
|
|
}
|
|
if (!is_game_end_) {
|
|
GameLog::Instance()->GameEnd((Player*)this);
|
|
is_game_end_ = true;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void Human::SendDebugMsg(const std::string& debug_msg)
|
|
{
|
|
#ifdef DEBUG
|
|
cs::SMDebugMsg notify_msg;
|
|
#if 1
|
|
notify_msg.set_debug_msg(debug_msg);
|
|
#else
|
|
notify_msg.set_debug_msg(a8::TimestampToDateTime(time(nullptr)) + " " + debug_msg);
|
|
#endif
|
|
SendNotifyMsg(notify_msg);
|
|
#endif
|
|
}
|
|
|
|
void Human::SendUIUpdate()
|
|
{
|
|
cs::SMUiUpdate notifymsg;
|
|
notifymsg.set_alive_count(room->AliveCount());
|
|
notifymsg.set_kill_count(stats->kills);
|
|
room->FillSMUiUpdate(notifymsg);
|
|
if (room->IsPveRoom()) {
|
|
notifymsg.set_score(stats->pve_rank_score);
|
|
notifymsg.set_wave(room->pve_data.GetWave() + 1);
|
|
notifymsg.set_max_wave(room->pve_data.max_wave);
|
|
notifymsg.set_mon_num(room->pve_data.mon_num);
|
|
notifymsg.set_boss_state(room->pve_data.boss_state);
|
|
}
|
|
SendNotifyMsg(notifymsg);
|
|
}
|
|
|
|
|
|
void Human::SendSysPiaoMsg(const std::string& msg, int color, int duration)
|
|
{
|
|
cs::SMSysPiaoMsg notifymsg;
|
|
notifymsg.set_msg(msg);
|
|
notifymsg.set_color(color);
|
|
notifymsg.set_duration(duration);
|
|
SendNotifyMsg(notifymsg);
|
|
}
|
|
|
|
void Human::SendShowCountdown(const std::string& msg, int countdown)
|
|
{
|
|
cs::SMShowCountdown notifymsg;
|
|
notifymsg.set_msg(msg);
|
|
notifymsg.set_countdown(countdown);
|
|
SendNotifyMsg(notifymsg);
|
|
}
|
|
|
|
void Human::SendBattleSettlement()
|
|
{
|
|
if (!IsPlayer()) {
|
|
return;
|
|
}
|
|
Player* p = (Player*)this;
|
|
std::shared_ptr<a8::MutableXObject> params = a8::MutableXObject::CreateObject();
|
|
{
|
|
params->SetVal("account_id", account_id);
|
|
params->SetVal("session_id", session_id);
|
|
params->SetVal("battle_uuid", battle_uuid);
|
|
params->SetVal("__POST", f8::PbToJson(p->settlement.get()));
|
|
}
|
|
|
|
std::string url;
|
|
JsonDataMgr::Instance()->GetApiUrl(url);
|
|
if (url.find('?') != std::string::npos) {
|
|
url += "c=Battle&a=reportSettlement";
|
|
} else {
|
|
url += "?c=Battle&a=reportSettlement";
|
|
}
|
|
std::string data;
|
|
params->ToUrlEncodeStr(data);
|
|
#ifdef DEBUG
|
|
{
|
|
if (!f8::IsTestEnv()) {
|
|
a8::XPrintf("reportSettlement %s\n", {data});
|
|
}
|
|
}
|
|
#endif
|
|
long long room_uuid = room->GetRoomUuid();
|
|
std::string tmp_account_id = account_id;
|
|
|
|
HttpProxy::Instance()->HttpGet
|
|
(
|
|
[room_uuid, tmp_account_id, data]
|
|
(bool ok, a8::XObject* rsp_obj, f8::HttpContext* ctx)
|
|
{
|
|
Room* room = RoomMgr::Instance()->GetRoomByUuid(room_uuid);
|
|
if (!room) {
|
|
return;
|
|
}
|
|
Player* hum = room->GetPlayerByAccountId(tmp_account_id);
|
|
if (!hum) {
|
|
return;
|
|
}
|
|
if (!ok) {
|
|
f8::UdpLog::Instance()->Error("reportSettlement error params: %s response: %s",
|
|
{
|
|
data,
|
|
""
|
|
});
|
|
}
|
|
},
|
|
url.c_str(),
|
|
*params.get()
|
|
);
|
|
}
|
|
|
|
void Human::AddItem(int item_id, int item_num)
|
|
{
|
|
auto itr = items_.find(item_id);
|
|
if (itr != items_.end()) {
|
|
itr->second += item_num;
|
|
} else {
|
|
items_[item_id] = item_num;
|
|
}
|
|
|
|
if (room && room->GetFrameNo() > join_frameno) {
|
|
#if 0
|
|
room->frame_event.AddItemChg(GetWeakPtrRef(), item_id, items_[item_id]);
|
|
#endif
|
|
if (IsPlayer()) {
|
|
cs::SMGetItemNotify notify_msg;
|
|
auto pair = notify_msg.add_items();
|
|
pair->set_key(item_id);
|
|
pair->set_value(item_num);
|
|
SendNotifyMsg(notify_msg);
|
|
}
|
|
} else {
|
|
if (item_num <= 0) {
|
|
battling_items_.insert(item_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::NotifyObservers(cs::SMUpdate* msg, cs::MFActivePlayerData* active_player_data_pb)
|
|
{
|
|
bool refreshed_view = false;
|
|
std::set<int> synced_objects;
|
|
for (Human* observer : observers_) {
|
|
msg->clear_team_data();
|
|
if (observer->GetTeam()) {
|
|
observer->GetTeam()->TraverseMembers
|
|
(
|
|
[observer, msg] (Human* member) -> bool
|
|
{
|
|
#if 1
|
|
{
|
|
#else
|
|
if (member != observer || observer->room->IsPveRoom()) {
|
|
#endif
|
|
member->FillMFTeamData(observer, msg->add_team_data(), false);
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
if (observer != this && !observer->follow_synced_active_player) {
|
|
msg->set_active_player_id(GetUniId());
|
|
FillMFActivePlayerData(msg->mutable_active_player_data());
|
|
if (!refreshed_view) {
|
|
{
|
|
for (auto& pair : framedata_.new_objects) {
|
|
synced_objects.insert(pair.first);
|
|
}
|
|
}
|
|
std::set<Entity*> view_objects;
|
|
GetViewObjects(view_objects);
|
|
for (Entity* entity : view_objects) {
|
|
if (synced_objects.find(entity->GetUniId()) == synced_objects.end()) {
|
|
entity->FillMFObjectFull(room, this, msg->add_full_objects());
|
|
synced_objects.insert(entity->GetUniId());
|
|
}
|
|
}
|
|
refreshed_view = true;
|
|
for (auto& pair : framedata_.part_objects) {
|
|
if (synced_objects.find(pair.second.entity_uniid) == synced_objects.end()) {
|
|
Entity* entity = room->GetEntityByUniId(pair.second.entity_uniid);
|
|
if (entity) {
|
|
entity->FillMFObjectFull(room, this, msg->add_full_objects());
|
|
synced_objects.insert(entity->GetUniId());
|
|
} else {
|
|
#ifdef DEBUG
|
|
A8_ABORT();
|
|
#endif
|
|
}
|
|
}
|
|
#ifdef DEBUG
|
|
observer->SendDebugMsg(a8::Format("观战 notify %d->%d frameno:%d part_obj:%d",
|
|
{
|
|
GetUniId(),
|
|
observer->GetUniId(),
|
|
room->GetFrameNo(),
|
|
pair.second.entity_uniid
|
|
}));
|
|
#endif
|
|
}
|
|
#ifdef DEBUG
|
|
observer->SendDebugMsg(a8::Format("观战 notify %d->%d frameno:%d",
|
|
{
|
|
GetUniId(),
|
|
observer->GetUniId(),
|
|
room->GetFrameNo()
|
|
}));
|
|
#endif
|
|
}
|
|
observer->follow_synced_active_player = true;
|
|
} else {
|
|
if (active_player_data_pb) {
|
|
msg->set_active_player_id(GetUniId());
|
|
*msg->mutable_active_player_data() = *active_player_data_pb;
|
|
} else {
|
|
msg->clear_active_player_id();
|
|
msg->clear_active_player_data();
|
|
}
|
|
}
|
|
if (observer != this) {
|
|
for (int i = 0; i < msg->full_objects_size(); ++i) {
|
|
cs::MFObjectFull* full_obj = msg->mutable_full_objects(i);
|
|
if (a8::HasBitFlag(full_obj->object_flags(), kOfReadCache)) {
|
|
Entity* e = room->GetEntityByUniId(full_obj->obj_uniid());
|
|
if (e) {
|
|
if (!e->IsClientCached(observer)) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
observer->SendNotifyMsg(*msg);
|
|
}
|
|
}
|
|
|
|
void Human::FillMFSettlement(cs::SMGameOver* msg, cs::MFSettlement* s)
|
|
{
|
|
s->set_version(2022111801);
|
|
s->set_room_uuid(a8::XValue(room->GetRoomUuid()).GetString());
|
|
s->set_room_mode(room->GetRoomMode());
|
|
s->set_match_mode(GetBattleContext()->GetMatchMode());
|
|
s->set_team_mode(GetTeamMode());
|
|
s->set_game_over(msg->game_over() ? 1 : 0);
|
|
s->set_victory(stats->victory);
|
|
if (stats->victory) {
|
|
s->set_watchable(false);
|
|
} else {
|
|
if (room->GetAliveTeamNum() > 1) {
|
|
s->set_watchable(true);
|
|
} else {
|
|
if (room->IsPveRoom()) {
|
|
s->set_watchable(!room->IsGameOver());
|
|
} else {
|
|
s->set_watchable(false);
|
|
}
|
|
}
|
|
}
|
|
s->set_team_id(team_id);
|
|
s->set_account_id(account_id);
|
|
s->set_temmate_all_dead(1);
|
|
|
|
s->set_old_rank(stats->old_rank);
|
|
s->set_new_rank(stats->new_rank);
|
|
s->set_old_score(stats->old_score);
|
|
s->set_new_score(stats->new_score);
|
|
|
|
s->set_map_id(room->GetMapMeta()->map_id());
|
|
s->set_map_name(room->GetMapMeta()->map_name());
|
|
s->set_rank_score_chg(stats->new_score - stats->old_score);
|
|
for (auto item : msg->spoils_items()) {
|
|
if (!(a8::XValue(item.values(1)).GetString().empty())) {
|
|
auto p = s->add_spoils_items();
|
|
p->set_item_id(a8::XValue(item.values(0)));
|
|
p->set_item_num(item.values(1));
|
|
}
|
|
}
|
|
|
|
if (room->IsPveRoom()) {
|
|
s->set_pve_settlement_color(stats->settlement_color);
|
|
s->set_pve_wave(room->pve_data.GetPassedWave());
|
|
s->set_pve_max_wave(room->pve_data.max_wave);
|
|
s->set_pve_instance_id(room->pve_instance->gemini_id());
|
|
s->set_pve_boss_killed(room->pve_data.boss_state == 2 ? 1 : 0);
|
|
} else {
|
|
s->set_pvp_settlement_type(stats->pvp_settlement_type);
|
|
s->set_pvp_settlement_color(stats->settlement_color);
|
|
s->set_pvp_team_rank(GetTeam()->team_rank);
|
|
s->set_pvp_personal_rank(stats->rank);
|
|
s->set_pvp_my_rank(msg->my_rank());
|
|
s->set_pvp_max_rank(msg->max_rank());
|
|
s->set_pvp_total_human_num(msg->total_human_num());
|
|
s->set_pvp_alive_human_num(msg->alive_human_num());
|
|
s->set_pvp_total_team_num(msg->total_team_num());
|
|
}
|
|
|
|
*s->mutable_reward() = msg->reward();
|
|
std::vector<const cs::MFPlayerStats*> stats;
|
|
{
|
|
for (auto& item : msg->player_stats()) {
|
|
stats.push_back(&item);
|
|
}
|
|
if (room->IsPveRoom()) {
|
|
std::sort(stats.begin(), stats.end(),
|
|
[] (const cs::MFPlayerStats* a, const cs::MFPlayerStats *b) -> bool
|
|
{
|
|
if (a->score() > b->score()) {
|
|
return true;
|
|
}
|
|
if (a->score() < b->score()) {
|
|
return false;
|
|
}
|
|
return a->player_id() < b->player_id();
|
|
});
|
|
}
|
|
}
|
|
|
|
int i = 0;
|
|
for (auto item : stats) {
|
|
++i;
|
|
auto p = s->add_members_stats();
|
|
p->set_id(item->player_id());
|
|
p->set_account_id(item->account_id());
|
|
p->set_name(item->nickname());
|
|
p->set_head(a8::XValue(avatar_url));
|
|
p->set_head_frame(item->head_frame());
|
|
p->set_sex(item->sex());
|
|
p->set_hero_id(item->charid());
|
|
p->set_dead(item->dead() ? 1 : 0);
|
|
p->set_is_myself(item->account_id() == account_id ? 1 : 0);
|
|
//
|
|
p->set_is_mvp(0);
|
|
|
|
if (room->IsPveRoom()) {
|
|
p->set_pve_order(i);
|
|
p->set_pve_score(item->score());
|
|
p->set_pve_star(room->pve_mode_meta->CalcStar(item->score()));
|
|
p->set_pve_damage(item->damage_amount());
|
|
p->set_pve_survia_time(item->time_alive());
|
|
p->set_pve_wave(item->pve_wave());
|
|
p->set_pve_max_wave(room->pve_data.max_wave);
|
|
p->set_pve_revive(item->revive());
|
|
} else {
|
|
p->set_pvp_kill(item->kills());
|
|
p->set_pvp_damage(item->damage_amount());
|
|
p->set_pvp_assist(item->assist());
|
|
p->set_pvp_survia_time(item->time_alive());
|
|
p->set_pvp_recover(item->heal_amount());
|
|
p->set_pvp_rescue(item->rescue());
|
|
}
|
|
if (!item->dead() && p->account_id() != account_id) {
|
|
s->set_temmate_all_dead(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::NotifyTeamMarkTargetPos()
|
|
{
|
|
if (GetTeam()) {
|
|
cs::SMTeamMarkTargetPosList notify_msg;
|
|
for (auto& pair : GetTeam()->target_pos) {
|
|
auto p = notify_msg.add_pos_list();
|
|
p->set_obj_uniid(pair.first);
|
|
TypeConvert::ToPb(pair.second, p->mutable_pos());
|
|
}
|
|
GetTeam()->TraverseMembers
|
|
(
|
|
[¬ify_msg] (Human* hum)
|
|
{
|
|
hum->SendNotifyMsg(notify_msg);
|
|
return true;
|
|
});
|
|
}
|
|
}
|
|
|
|
void GGListener::SendError(int sockhandle, unsigned int seqid,
|
|
int error_code, const std::string& error_msg,
|
|
const char* file, int lineno, int error_param)
|
|
{
|
|
cs::SMRpcError msg;
|
|
msg.set_error_code(error_code);
|
|
msg.set_error_msg(error_msg);
|
|
msg.set_debug_msg("");
|
|
if (file) {
|
|
msg.set_file(file);
|
|
} else {
|
|
msg.set_file("");
|
|
}
|
|
msg.set_lineno(lineno);
|
|
msg.set_error_param(error_param);
|
|
f8::Net_SendProxyMsg(tcp_listener_.get(), sockhandle, seqid, error_code, cs::_SMRpcError, msg);
|
|
}
|
|
|
|
void GGListener::ForceCloseChildSocket(int sockhandle)
|
|
{
|
|
ss::SS_ForceCloseSocket msg;
|
|
SendProxyMsg(sockhandle, msg);
|
|
}
|
|
|
|
Player* PlayerMgr::CreatePlayerByCMJoin(Player* hum,
|
|
long ip_saddr,
|
|
int socket,
|
|
const cs::CMJoin& msg)
|
|
{
|
|
hum->socket_handle = socket;
|
|
hum->ip_saddr = ip_saddr;
|
|
hum->account_id = msg.account_id();
|
|
hum->session_id = msg.session_id();
|
|
hum->name = msg.name();
|
|
hum->team_uuid = msg.team_uuid();
|
|
hum->team_mode = msg.team_mode();
|
|
hum->auto_fill = msg.auto_fill();
|
|
hum->avatar_url = msg.avatar_url();
|
|
hum->create_tick = a8::XGetTickCount();
|
|
hum->account_registertime = f8::ExtractRegisterTimeFromSessionId(msg.session_id());
|
|
hum->channel = f8::ExtractChannelIdFromAccountId(msg.account_id());
|
|
hum->head_frame = msg.head_frame();
|
|
hum->sex = msg.sex();
|
|
hum->user_data = msg.user_data();
|
|
#if 0
|
|
for (auto& weapon : msg.weapons()) {
|
|
if (weapon.weapon_id() != 0) {
|
|
const mt::Item* item_meta = mt::Item::GetById(weapon.weapon_id());
|
|
if (item_meta && item_meta->type() == 7) {
|
|
const mt::Equip* equip_meta = mt::Equip::GetById(item_meta->relationship());
|
|
if (equip_meta && equip_meta->equip_type() == EQUIP_TYPE_WEAPON) {
|
|
Weapon& spec_weapon = a8::FastAppend(hum->spec_weapons);
|
|
spec_weapon.weapon_uniid = a8::XValue(weapon.weapon_uniid());
|
|
spec_weapon.weapon_id = item_meta->relationship();
|
|
spec_weapon.ammo = weapon.ammo();
|
|
spec_weapon.meta = equip_meta;
|
|
spec_weapon.Recalc();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#if 0
|
|
for (auto& pair : msg.talent_list()) {
|
|
hum->talent_list.push_back(
|
|
std::make_tuple(pair.key(), pair.value())
|
|
);
|
|
}
|
|
#endif
|
|
socket_hash_[socket] = hum;
|
|
return hum;
|
|
}
|
|
|
|
void PlayerMgr::_SS_WSP_SocketDisconnect(f8::MsgHdr& hdr, const ss::SS_WSP_SocketDisconnect& msg)
|
|
{
|
|
Player* hum = GetPlayerBySocket(hdr.socket_handle);
|
|
if (hum) {
|
|
RemovePlayerBySocket(hdr.socket_handle);
|
|
hum->room->OnPlayerOffline(hum);
|
|
}
|
|
#if DEBUG
|
|
a8::XPrintf("remove socket1 %d\n", {hdr.socket_handle});
|
|
#endif
|
|
if (MatchMgr::Instance()->GetMatchInfo(hdr.socket_handle)) {
|
|
#if DEBUG
|
|
a8::XPrintf("remove socket2 %d\n", {hdr.socket_handle});
|
|
#endif
|
|
MatchMgr::Instance()->RemoveSocket(hdr.socket_handle);
|
|
}
|
|
}
|
|
|
|
void PlayerMgr::_SS_Ping(f8::MsgHdr& hdr, const ss::SS_Ping& msg)
|
|
{
|
|
ss::SS_Pong respmsg;
|
|
GGListener::Instance()->SendToClient(hdr.socket_handle, 0, respmsg);
|
|
}
|
|
|
|
void Team::FillSMGameOver(cs::SMGameOver& msg)
|
|
{
|
|
auto p = msg.mutable_settlement_new();
|
|
std::vector<Human*> sorted_members;
|
|
for (Human* hum : members_) {
|
|
sorted_members.push_back(hum);
|
|
}
|
|
if (room->IsPveRoom()) {
|
|
std::sort(sorted_members.begin(), sorted_members.end(),
|
|
[] (Human* a, Human* b) -> bool
|
|
{
|
|
if (a->stats->pve_rank_score > b->stats->pve_rank_score) {
|
|
return true;
|
|
}
|
|
if (a->stats->pve_rank_score < b->stats->pve_rank_score) {
|
|
return false;
|
|
}
|
|
return a->GetUniId() < b->GetUniId();
|
|
});
|
|
}
|
|
int i = 0;
|
|
for (Human* hum : sorted_members) {
|
|
++i;
|
|
auto member = p->add_members();
|
|
member->set_obj_uniid(hum->GetUniId());
|
|
member->set_account_id(hum->account_id);
|
|
member->set_name(hum->name);
|
|
member->set_head(a8::XValue(hum->avatar_url));
|
|
member->set_head_frame(hum->head_frame);
|
|
member->set_sex(hum->sex);
|
|
member->set_hero_id(hum->meta->id());
|
|
member->set_dead(hum->dead);
|
|
member->set_is_mvp(0);
|
|
|
|
member->set_old_rank(0);
|
|
member->set_new_rank(0);
|
|
member->set_old_score(0);
|
|
member->set_new_score(0);
|
|
|
|
if (room->IsPveRoom()) {
|
|
member->set_pve_order(i);
|
|
member->set_pve_score(hum->stats->pve_rank_score);
|
|
member->set_pve_star(room->pve_mode_meta->CalcStar(hum->stats->pve_rank_score));
|
|
member->set_pve_damage(hum->stats->damage_amount_out);
|
|
member->set_pve_revive(hum->stats->revive);
|
|
member->set_pve_survia_time(room->GetFrameNo() * FRAME_RATE_MS);
|
|
member->set_pve_wave(hum->stats->pve_wave);
|
|
member->set_pve_max_wave(room->pve_data.max_wave);
|
|
member->set_pve_boss_killed(hum->stats->pve_kill_boss);
|
|
} else {
|
|
member->set_pvp_kill(hum->stats->kills);
|
|
member->set_pvp_damage(hum->stats->damage_amount_out);
|
|
member->set_pvp_assist(hum->stats->assist);
|
|
member->set_pvp_survia_time(room->GetFrameNo() * FRAME_RATE_MS);
|
|
member->set_pvp_recover(hum->stats->heal_amount);
|
|
member->set_pvp_rescue(hum->stats->rescue_member);
|
|
member->set_pvp_personal_rank(hum->stats->rank);
|
|
}
|
|
}
|
|
}
|