From e0fb3a679acfd9a63da2c58a067c0bb9745246c0 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 4 Jun 2020 14:51:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0last=20android=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/android.ai.cc | 44 ++++++++++++++++ server/gameserver/android.ai.h | 1 + server/gameserver/human.h | 2 + server/gameserver/room.cc | 89 ++++++++++++++++++++++++++++++++- server/gameserver/room.h | 3 ++ 5 files changed, 137 insertions(+), 2 deletions(-) diff --git a/server/gameserver/android.ai.cc b/server/gameserver/android.ai.cc index bd1c234..0837f3c 100644 --- a/server/gameserver/android.ai.cc +++ b/server/gameserver/android.ai.cc @@ -37,6 +37,10 @@ void AndroidAI::Update(int delta_time) UpdateNewBieNpc(); return; } + if (a8::HasBitFlag(hum->status, HS_LastAndroid)) { + UpdateLastNpc(); + return; + } switch (state) { case AS_thinking: { @@ -195,3 +199,43 @@ void AndroidAI::UpdateNewBieNpc() a8::UnSetBitFlag(hum->status, HS_NewBieGuideAndroid); } } + +void AndroidAI::UpdateLastNpc() +{ + Human* hum = (Human*)owner; + if (hum->room->GetFrameNo() - hum->enable_frameno < 2) { + hum->move_dir = hum->last_human_target->GetPos() - hum->GetPos(); + hum->move_dir.Normalize(); + hum->attack_dir = hum->move_dir; + if (hum->curr_weapon->weapon_idx != 0) { + hum->curr_weapon->ammo = MetaMgr::Instance()->newbie_first_robot_ammo; + } + } else if (hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 1.5) { + int speed = std::max(1, (int)hum->GetSpeed()); + for (int i = 0; i < speed; ++i) { + a8::Vec2 old_pos = hum->GetPos(); + hum->SetPos(hum->GetPos() + hum->move_dir); + if (hum->IsCollisionInMapService()) { + hum->SetPos(old_pos); + if (i == 0) { + hum->FindPathInMapService(); + } + break; + } + hum->room->grid_service->MoveHuman(hum); + } + } else if (hum->room->GetFrameNo() - hum->enable_frameno < SERVER_FRAME_RATE * 3) { + Human* enemy = hum->last_human_target; + Human* sender = hum; + a8::Vec2 shot_dir = enemy->GetPos() - sender->GetPos(); + if (std::abs(shot_dir.x) > FLT_EPSILON || + std::abs(shot_dir.y) > FLT_EPSILON) { + shot_dir.Normalize(); + shot_dir.Rotate((rand() % 10) / 180.0f); + sender->attack_dir = shot_dir; + sender->Shot(shot_dir); + } + } else { + a8::UnSetBitFlag(hum->status, HS_LastAndroid); + } +} diff --git a/server/gameserver/android.ai.h b/server/gameserver/android.ai.h index 50263e6..829a511 100644 --- a/server/gameserver/android.ai.h +++ b/server/gameserver/android.ai.h @@ -22,6 +22,7 @@ class AndroidAI : public AIComponent private: void UpdateNewBieNpc(); + void UpdateLastNpc(); void ChangeToState(AndroidState_e to_state); diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 1334494..b7b07fe 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -21,6 +21,7 @@ enum HumanStatus HS_NewBieGuideAndroid = 3, HS_AlreadyEquip = 5, HS_AlreadyProcNewBieLogic = 6, + HS_LastAndroid = 7, HS_End }; @@ -138,6 +139,7 @@ class Human : public MoveableEntity float skill_param1 = 0; bool playing_skill = false; xtimer_list* ad_timer_ = nullptr; + Human* last_human_target = nullptr; std::function on_grid_chg; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 339097d..744cd3d 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -508,6 +508,7 @@ void Room::OnHumanDie(Human* hum) --PerfMonitor::Instance()->alive_count; RemoveFromAliveHumanHash(hum); NotifyUiUpdate(); + CheckShowHand(); } bool Room::OverBorder(const a8::Vec2 pos, float radius) @@ -1892,7 +1893,7 @@ void Room::ProcDieAndroid(int die_time, int die_num) #endif std::vector alive_humans; alive_humans.reserve(human_hash_.size()); - GetAliveHumans(alive_humans, 16, nullptr); + GetAliveHumansExcludeLastHuman(alive_humans, 16); { Human* first_alive_player = nullptr; for (auto& pair : accountid_hash_) { @@ -2058,6 +2059,7 @@ void Room::ShuaGridRound(Human* target) Human* hum = pair.second; if (hum->IsAndroid() && a8::HasBitFlag(hum->status, HS_Disable) && + !a8::HasBitFlag(hum->status, HS_LastAndroid) && !hum->real_dead && hum->team_uuid.empty() && grid_service->InView(target->GetGridId(), hum->GetPos().x, hum->GetPos().y) @@ -2164,6 +2166,34 @@ void Room::GetAliveHumans(std::vector& alive_humans, size_t num, Human* } } +void Room::GetAliveHumansExcludeLastHuman(std::vector& alive_humans, size_t num) +{ + alive_humans.reserve(num); + { + if (GetFrameNo() % 8 < 5) { + for (auto itr = human_hash_.begin(); itr != human_hash_.end(); ++itr) { + if (a8::HasBitFlag(itr->second->status, HS_LastAndroid)) { + continue; + } + CheckAliveHuman(itr->second, alive_humans); + if (alive_humans.size() > num) { + break; + } + } + } else { + for (auto itr = human_hash_.rbegin(); itr != human_hash_.rend(); ++itr) { + if (a8::HasBitFlag(itr->second->status, HS_LastAndroid)) { + continue; + } + CheckAliveHuman(itr->second, alive_humans); + if (alive_humans.size() > num) { + break; + } + } + } + } +} + void Room::CheckAliveHuman(Human* hum, std::vector& alive_humans) { if (hum->IsAndroid() && @@ -2419,6 +2449,18 @@ void Room::NewBieRoomStart() }, &xtimer_attacher_.timer_list_); } + std::vector tmp_humans; + tmp_humans.reserve(ROOM_MAX_PLAYER_NUM); + for (auto& pair : human_hash_) { + if (pair.second->IsAndroid()) { + tmp_humans.push_back(pair.second); + } + } + std::random_shuffle(tmp_humans.begin(), tmp_humans.end()); + for (size_t i = 0; i < accountid_hash_.size(); ++i) { + last_human_hash_[tmp_humans[i]->GetEntityUniId()] = tmp_humans[i]; + a8::SetBitFlag(tmp_humans[i]->status, HS_LastAndroid); + } } Human* Room::GetOneCanEnableAndroid() @@ -2433,7 +2475,8 @@ void Room::GetCanEnableAndroids(std::vector& humans, size_t num) for (auto& pair : human_hash_) { if (pair.second->IsAndroid() && !pair.second->real_dead && - a8::HasBitFlag(pair.second->status, HS_Disable) + a8::HasBitFlag(pair.second->status, HS_Disable) && + !a8::HasBitFlag(pair.second->status, HS_LastAndroid) ) { if (humans.size() >= num) { break; @@ -2550,3 +2593,45 @@ void Room::SyncFrameData() } frame_event.Clear(); } + +void Room::CheckShowHand() +{ + if (room_type_ == RT_NewBrid || room_type_ == RT_MidBrid) { + if (alive_count_ <= (int)(accountid_hash_.size() + last_human_hash_.size())) { + std::vector players; + std::vector androids; + for (auto& pair : accountid_hash_) { + players.push_back(pair.second); + } + for (auto& pair : last_human_hash_) { + androids.push_back(pair.second); + } + for (size_t i = 0; i < players.size(); ++i) { + if (i >= androids.size()) { + break; + } + Player* target = players[i]; + Human* hum = androids[i]; + { + a8::Vec2 pos = target->GetPos(); + a8::Vec2 dir = target->move_dir; + if (rand() % 100 < 80) { + dir.Rotate(a8::RandAngle() / 2.0f); + } else { + dir.Rotate(a8::RandAngle()); + } + pos = pos + dir * SHUA_RANGE; + if (OverBorder(pos, hum->GetRadius())) { + pos.x = target->GetPos().x; + if (OverBorder(pos, hum->GetRadius())) { + pos = target->GetPos(); //!!! + } + } + hum->last_human_target = target; + hum->SetPos(pos); + EnableHuman(hum); + } + } + } + } +} diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 2477693..02d75e7 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -168,6 +168,7 @@ private: void ShuaGridRound(Human* target); void GetAliveHumans(std::vector& alive_humans, size_t num, Human* exclude_hum); void CheckAliveHuman(Human* hum, std::vector& alive_humans); + void GetAliveHumansExcludeLastHuman(std::vector& alive_humans, size_t num); a8::Vec2 GetDefaultBornPoint(); void AddToEntityHash(Entity* entity); @@ -190,6 +191,7 @@ private: void CreateLevel0RoomSpecThings(); bool CanAddToScene(Human* hum); void SyncFrameData(); + void CheckShowHand(); #ifdef DEBUG void InitDebugInfo(); @@ -233,6 +235,7 @@ private: std::map later_add_hash_; std::map human_hash_; std::map alive_human_hash_; + std::map last_human_hash_; std::map born_point_hash_; std::map car_hash_;