diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index 1ffcddcd..0ab68284 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -286,6 +286,11 @@ void Hero::BeKill(int killer_id, const std::string& killer_name, int weapon_id) } }, &xtimer_attacher.timer_list_); + if (room->IsPveRoom()) { + --room->pve_data.mon_num; + --room->pve_data.killed_num; + room->NotifyUiUpdate(); + } GetTrigger()->Die(); } diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index a33e99f7..07a633ad 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1546,6 +1546,9 @@ void Human::FillMFGasData(cs::MFGasData* gas_data) (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); + } } TypeConvert::ToPb(room->GetGasData().pos_old, gas_data->mutable_pos_old()); TypeConvert::ToPb(room->GetGasData().pos_new, gas_data->mutable_pos_new()); @@ -1778,6 +1781,12 @@ void Human::SendUIUpdate() notifymsg.set_alive_count(room->AliveCount()); notifymsg.set_kill_count(stats.kills); room->FillSMUiUpdate(notifymsg); + if (room->IsPveRoom()) { + notifymsg.set_score(stats.pve_score); + notifymsg.set_wave(room->pve_data.wave); + notifymsg.set_max_wave(room->pve_data.max_wave); + notifymsg.set_mon_num(room->pve_data.mon_num); + } SendNotifyMsg(notifymsg); } diff --git a/server/gameserver/incubator.cc b/server/gameserver/incubator.cc index 8c777f54..fafd6c3c 100644 --- a/server/gameserver/incubator.cc +++ b/server/gameserver/incubator.cc @@ -20,6 +20,10 @@ void Incubator::Init() }, &xtimer_attacher_.timer_list_); if (room->IsPveRoom()) { + #if 0 + room->pve_data.wave = 1; + #endif + room->pve_data.max_wave = room->pve_mode_meta->mode_time.size(); int wave = 0; for (int time : room->pve_mode_meta->mode_time) { room->xtimer.AddDeadLineTimerAndAttach @@ -245,29 +249,54 @@ void Incubator::SpawnWaveMon(int wave) if (wave >= room->pve_mode_meta->waves.size()) { abort(); } + if (room->pve_data.refreshed_mon > 0 && + room->pve_data.mon_num <= 0) { + timeout_ = true; + return; + } if (wave > 0 && room->IsDestoryRoom()) { return; } + if (room->IsGameOver()) { + return; + } auto& mons = room->pve_mode_meta->waves[wave]; for (MetaData::PveGeminiContent* content : mons) { - MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(content->pb->enemy_id()); - if (hero_meta) { - a8::Vec2 hero_pos = content->spawn_point; + room->xtimer.AddDeadLineTimerAndAttach + ( + room->IsDestoryRoom() ? 0 : SERVER_FRAME_RATE * 2, + a8::XParams() + .SetSender(this) + .SetParam1(content) + .SetParam2(room), + [] (const a8::XParams& param) + { + MetaData::PveGeminiContent* content = (MetaData::PveGeminiContent*)param.param1.GetUserData(); + Room* room = (Room*)param.param2.GetUserData(); + MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(content->pb->enemy_id()); + if (hero_meta) { + a8::Vec2 hero_pos = content->spawn_point; - int team_id = 666; - Creature* master = nullptr; + int team_id = 666; + Creature* master = nullptr; - a8::Vec2 dir = hero_pos; - dir.Normalize(); + a8::Vec2 dir = hero_pos; + dir.Normalize(); - Hero* hero = room->CreateHero(master, - hero_meta, - hero_pos, - dir, - team_id); - if (!hero) { - A8_ABORT(); - } - } + Hero* hero = room->CreateHero(master, + hero_meta, + hero_pos, + dir, + team_id); + if (!hero) { + A8_ABORT(); + } + ++room->pve_data.mon_num; + room->NotifyUiUpdate(); + } + }, + &xtimer_attacher_.timer_list_); + ++room->pve_data.refreshed_mon; } + ++room->pve_data.wave; } diff --git a/server/gameserver/incubator.h b/server/gameserver/incubator.h index 5fdcb32e..621ab255 100644 --- a/server/gameserver/incubator.h +++ b/server/gameserver/incubator.h @@ -14,6 +14,7 @@ class Incubator void AllocAndroid(Human* target, int num); void RecycleAndroid(Human* hum); void ActiveAndroid(Human* hum, Human* android); + bool IsTimeOut() { return timeout_; }; private: bool CanSee(Human* hum, Human* exclude_hum); @@ -21,6 +22,7 @@ private: void SpawnWaveMon(int wave); private: + bool timeout_ = false; std::vector hold_humans_; a8::XTimerAttacher xtimer_attacher_; }; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 28763946..fc77ea9e 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -1186,9 +1186,17 @@ void Room::UpdateGas() if (gas_data_.gas_mode != GasInactive && gas_data_.gas_mode != GasJump) { if (gas_data_.gas_mode != GasInactive) { if (IsPveRoom()) { - + if (!IsGameOver() && + pve_data.refreshed_mon > 0 && + pve_data.killed_num >= pve_data.refreshed_mon) { + game_over_ = true; + game_over_frameno_ = GetFrameNo(); + OnGameOver(); + } } else { - if (!IsGameOver() && alive_count_ <= MAX_TEAM_NUM && GetAliveTeamNum() <= 1) { + if (!IsGameOver() && + alive_count_ <= MAX_TEAM_NUM && + GetAliveTeamNum() <= 1) { game_over_ = true; game_over_frameno_ = GetFrameNo(); OnGameOver(); @@ -1303,22 +1311,19 @@ void Room::UpdateGasInactivePvp() void Room::UpdateGasInactivePve() { { - MetaData::SafeArea* first_safearea = MetaMgr::Instance()->GetSafeArea(FIRST_AREA_ID); - if (!first_safearea) { - abort(); - } + first_safearea = pve_mode_meta->area[0]; gas_data_.gas_mode = GasWaiting; gas_data_.gas_start_frameno = GetFrameNo(); battle_start_frameno_ = GetFrameNo(); gas_data_.old_area_meta = first_safearea; gas_data_.new_area_meta = pve_mode_meta->area[0]; - gas_data_.gas_progress = 0; gas_data_.gas_start_frameno = GetFrameNo(); - gas_data_.pos_old = a8::Vec2(first_safearea->i->x1(), first_safearea->i->y1()); gas_data_.pos_new = a8::Vec2(gas_data_.new_area_meta->i->x1(), gas_data_.new_area_meta->i->y1()); + gas_data_.pos_old = gas_data_.pos_new; gas_data_.pos_old_bk = gas_data_.pos_old; gas_data_.rad_old = gas_data_.old_area_meta->i->rad(); gas_data_.rad_new = gas_data_.new_area_meta->i->rad(); + gas_data_.gas_progress = 0; } NotifyUiUpdate(); ClearPostBattleAutoFreeList(); diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 45facfe1..7aa3f1ab 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -73,6 +73,16 @@ struct CarObject bool taken = false; }; +struct PveData +{ + int wave = 0; + int max_wave = 0; + int mon_num = 0; + + int refreshed_mon = 0; + int killed_num = 0; +}; + class MatchTeam; class Room { @@ -92,6 +102,7 @@ public: std::map mine_objects; MetaData::PveGeminiMode* pve_mode_meta = nullptr; MetaData::PveGemini* pve_instance = nullptr; + PveData pve_data; ~Room(); void InitData(RoomInitInfo& init_info);