diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index 01695dd..655a057 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -4,7 +4,7 @@ #include "human.h" #include "room.h" -cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum) +cs::SMUpdate* FrameMaker::MakeUpdateMsg(const Human* hum) { cs::SMUpdate* msg = new cs::SMUpdate; { @@ -21,9 +21,6 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum) room->plane.start_point.ToPB(p->mutable_start_point()); room->plane.end_point.ToPB(p->mutable_end_point()); } - if (hum->send_msg_times == 0) { - room->FetchBuilding(hum); - } for (auto& itr : hum->new_objects) { itr->FillMFObjectFull(msg->add_full_objects()); } @@ -32,10 +29,6 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum) } for (auto& itr : hum->del_objects) { msg->add_del_objids(itr); - Entity* entity = hum->room->GetEntityByUniId(itr); - if (entity) { - hum->part_objects.erase(entity); - } } for (int idx : hum->shots_) { if (idx < room->frame_event.shots_.size()) { @@ -80,21 +73,11 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum) if (room->frame_event.airdrops_.size() > 0) { *msg->mutable_airdrop() = room->frame_event.airdrops_.Get(0); } - if (hum->send_msg_times == 0 || hum->need_sync_active_player) { - msg->set_active_player_id(hum->entity_uniid); - hum->FillMFActivePlayerData(msg->mutable_active_player_data()); - hum->need_sync_active_player = false; - } - if (hum->send_msg_times == 0 || hum->last_sync_gas_frameno < room->gas_data.gas_start_frameno) { - hum->last_sync_gas_frameno = room->gas_data.gas_start_frameno; - hum->FillMFGasData(msg->mutable_gas_data()); - } if (room->gas_data.gas_mode == GasMoving) { msg->set_gas_progress(room->gas_data.gas_progress); room->gas_data.pos_old.ToPB(msg->mutable_gas_pos_old()); } msg->set_alive_count(room->AliveCount()); } - ++hum->send_msg_times; return msg; } diff --git a/server/gameserver/framemaker.h b/server/gameserver/framemaker.h index 9ee74f6..a8515a2 100644 --- a/server/gameserver/framemaker.h +++ b/server/gameserver/framemaker.h @@ -8,5 +8,5 @@ class FrameMaker { public: - cs::SMUpdate* MakeUpdateMsg(Human* hum); + cs::SMUpdate* MakeUpdateMsg(const Human* hum); }; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 8602a1b..5761c79 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -47,6 +47,7 @@ void Human::Initialize() Entity::Initialize(); RecalcSelfCollider(); volume_ = meta->volume; + observers_.insert(this); } float Human::GetSpeed() @@ -993,7 +994,7 @@ void Human::FillMFGasData(cs::MFGasData* gas_data) gas_data->set_rad_new(room->gas_data.rad_new); } -bool Human::CanSee(Human* hum) +bool Human::CanSee(const Human* hum) const { return room->grid_service.InView(grid_id, hum->grid_id); } @@ -1182,12 +1183,43 @@ void Human::RemoveObserver(Human* observer) void Human::SendUpdateMsg() { if (!follow_target_) { - cs::SMUpdate* msg = room->frame_maker.MakeUpdateMsg(this); - if (msg) { - SendNotifyMsg(*msg); - delete msg; - msg = nullptr; + if (send_msg_times == 0) { + room->FetchBuilding(this); } + 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; + } + + cs::SMUpdate* msg = room->frame_maker.MakeUpdateMsg(this); + if (send_msg_times == 0 || last_sync_gas_frameno < room->gas_data.gas_start_frameno) { + last_sync_gas_frameno = room->gas_data.gas_start_frameno; + FillMFGasData(msg->mutable_gas_data()); + } + for (Human* observer : observers_) { + if (observer != this && !observer->follow_synced_active_player) { + msg->set_active_player_id(entity_uniid); + FillMFActivePlayerData(msg->mutable_active_player_data()); + observer->follow_synced_active_player = true; + } else { + if (active_player_data_pb) { + msg->set_active_player_id(entity_uniid); + *msg->mutable_active_player_data() = *active_player_data_pb; + } else { + msg->clear_active_player_id(); + msg->clear_active_player_data(); + } + } + observer->SendNotifyMsg(*msg); + } + delete msg; + + if (active_player_data_pb) { + delete active_player_data_pb; + } + ++send_msg_times; } ClearFrameData(); if (send_gameover) { @@ -1270,6 +1302,12 @@ void Human::ClearFrameData() new_objects.clear(); } if (!del_objects.empty()) { + for (auto& itr : del_objects) { + Entity* entity = room->GetEntityByUniId(itr); + if (entity) { + part_objects.erase(entity); + } + } del_objects.clear(); } if (!shots_.empty()) { diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 0273142..16bc470 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -147,7 +147,7 @@ class Human : public Entity ); void FillMFActivePlayerData(cs::MFActivePlayerData* player_data); void FillMFGasData(cs::MFGasData* gas_data); - bool CanSee(Human* hum); + bool CanSee(const Human* hum) const; void RecalcAttr(); void RecalcVolume(); int GetInventory(int slot_id); @@ -195,6 +195,7 @@ protected: std::vector explosions_; std::set observers_; Human* follow_target_ = nullptr; + bool follow_synced_active_player = false; private: CircleCollider* self_collider_ = nullptr;