diff --git a/server/gameserver/airraid.cc b/server/gameserver/airraid.cc index bd24e7cd..dbc25be1 100644 --- a/server/gameserver/airraid.cc +++ b/server/gameserver/airraid.cc @@ -25,7 +25,7 @@ void AirRaid::Init() ( [this] (const mt::AirRaid* air_raid, bool& stop) { - room_->xtimer.SetTimeoutEx + auto timer_wp = room_->xtimer.SetTimeoutWpEx (SERVER_FRAME_RATE * air_raid->time(), [this, air_raid] (int event, const a8::Args* args) { @@ -36,6 +36,9 @@ void AirRaid::Init() } }, &room_->xtimer_attacher_); + #ifdef DEBUG + timers_.push_back(timer_wp); + #endif }); } @@ -104,12 +107,63 @@ bool AirRaid::GenAirRaidPos(const mt::AirRaid* raid_meta, glm::vec3& center) } center = point; } - room_->frame_event.AddAirRaid(raid_meta->appear_time(), center, raid_meta->rad()); + room_->frame_event.AddAirRaid(raid_meta->appear_time(), + center, + raid_meta->rad(), + std::get<0>(raid_meta->_bombing_time) + ); return true; } void AirRaid::ExecOneRoundAirRaid(const mt::AirRaid* raid_meta, const glm::vec3& pos) { + #if 1 + int continue_time = std::get<0>(raid_meta->_bombing_time); + int interval_time = std::get<1>(raid_meta->_bombing_time); + int bomb_times = continue_time / std::max(1, interval_time); + for (int i = 0; i < bomb_times; ++i) { + glm::vec3 born_pos = pos; + int num = 1; + int delay = i * interval_time * 1000; + + auto bomb_cb = + [this, raid_meta, num, delay, born_pos] + (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (room_->IsGameOver()) { + return; + } + glm::vec3 center = born_pos; + room_->map_instance->Scale(center); + glm::vec3 point; + if (room_->map_instance->FindRandomPointAroundCircle + ( + center, + 100 * room_->GetMapMeta()->scale(), + point + )) { + room_->map_instance->UnScale(point); + for (auto bomb_id : raid_meta->_bomb_ids) { + RoomObstacle* obstacle = room_->CreateObstacle + ( + bomb_id, + point.x, + point.y, + point.z + ); + obstacle->Active(); + } + } + } + }; + + room_->xtimer.SetTimeoutEx + (delay / FRAME_RATE_MS, + bomb_cb, + &room_->xtimer_attacher_); + } + #else for (auto& tuple : raid_meta->_raid_waves) { int num = std::get<0>(tuple); int delay = std::get<1>(tuple); @@ -154,4 +208,20 @@ void AirRaid::ExecOneRoundAirRaid(const mt::AirRaid* raid_meta, const glm::vec3& &room_->xtimer_attacher_); } } + #endif } + +#ifdef DEBUG + +void AirRaid::NextRaid() +{ + for (size_t i = 0; i < timers_.size(); ++i) { + auto& timer_wp = timers_.at(i); + if (!timer_wp.expired()) { + room_->xtimer.ModifyTime(timer_wp, 0); + break; + } + } +} + +#endif diff --git a/server/gameserver/airraid.h b/server/gameserver/airraid.h index df9211e3..5bfe5ae0 100644 --- a/server/gameserver/airraid.h +++ b/server/gameserver/airraid.h @@ -8,6 +8,9 @@ class AirRaid AirRaid(Room* room); void Init(); +#ifdef DEBUG + void NextRaid(); +#endif private: @@ -17,4 +20,7 @@ class AirRaid private: Room* room_ = nullptr; +#ifdef DEBUG + std::vector timers_; +#endif }; diff --git a/server/gameserver/commands.cc b/server/gameserver/commands.cc index d531c260..75ef0507 100644 --- a/server/gameserver/commands.cc +++ b/server/gameserver/commands.cc @@ -8,6 +8,7 @@ #include "ability.h" #include "movement.h" #include "android.h" +#include "airraid.h" #include "cs_proto.pb.h" @@ -170,6 +171,11 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) #if DEBUG room->debug_params[121] = 1; #endif + } else if (cmd == "next_raid") { + #if DEBUG + room->debug_params[121] = 1; + room->GetAirRaid()->NextRaid(); + #endif } else if (cmd == "autodie") { #if DEBUG if (cmds.size() >= 2) { @@ -287,4 +293,7 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) skill->Accelerate(-10000000); } } +#ifdef DEBUG + a8::XPrintf("exec_cmd:%s\n", {cmd}); +#endif } diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index f04967e2..ac95a836 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -21,11 +21,12 @@ void FrameEvent::AddAirDrop(int appear_time, int box_id, const glm::vec3& box_po TypeConvert::ToPb(box_pos, airdrop->mutable_pos()); } -void FrameEvent::AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad) +void FrameEvent::AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad, int continue_time) { cs::MFAirRaid* airraid = room->frame_event_data->airraids_.Add(); airraid->set_appear_time(appear_time); airraid->set_rad(raid_rad); + airraid->set_continue_time(continue_time); TypeConvert::ToPb(raid_pos, airraid->mutable_pos()); } diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index 747e1fe1..282b001f 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -14,7 +14,7 @@ public: Room* room = nullptr; void AddAirDrop(int appear_time, int box_id, const glm::vec3& box_pos); - void AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad); + void AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad, int continue_time); void AddEmote(CreatureWeakPtr& sender, int emote_id); void AddShot(CreatureWeakPtr& sender); void AddBullet(int bullet_uniid, diff --git a/server/gameserver/mt/AirRaid.cc b/server/gameserver/mt/AirRaid.cc index 9c382b94..990a1571 100644 --- a/server/gameserver/mt/AirRaid.cc +++ b/server/gameserver/mt/AirRaid.cc @@ -28,6 +28,18 @@ namespace mt ); } } + { + std::vector strings; + a8::Split(bombing_time(), strings, ':'); + if (strings.size() == 0) { + _bombing_time = std::make_tuple(0, 0); + } else if (strings.size() == 2) { + _bombing_time = std::make_tuple(a8::XValue(strings[0]).GetInt(), + a8::XValue(strings[1]).GetInt()); + } else { + abort(); + } + } } } diff --git a/server/gameserver/mt/AirRaid.h b/server/gameserver/mt/AirRaid.h index 5242ab4b..f539613c 100644 --- a/server/gameserver/mt/AirRaid.h +++ b/server/gameserver/mt/AirRaid.h @@ -15,6 +15,7 @@ namespace mt std::vector> _raid_waves; std::vector _bomb_ids; + std::tuple _bombing_time; }; diff --git a/server/gameserver/mtb/AirRaid.h b/server/gameserver/mtb/AirRaid.h index e9956e5c..7aaa40ef 100644 --- a/server/gameserver/mtb/AirRaid.h +++ b/server/gameserver/mtb/AirRaid.h @@ -16,6 +16,8 @@ namespace mtb const std::string bomb_id() const { return bomb_id_; }; const std::string raid_wave() const { return raid_wave_; }; float rad() const { return rad_; }; + const std::string bombing_time() const { return bombing_time_; }; + float damage() const { return damage_; }; bool has_id() const { return __flags__.test(0);}; bool has_time() const { return __flags__.test(1);}; @@ -23,6 +25,8 @@ namespace mtb bool has_bomb_id() const { return __flags__.test(3);}; bool has_raid_wave() const { return __flags__.test(4);}; bool has_rad() const { return __flags__.test(5);}; + bool has_bombing_time() const { return __flags__.test(6);}; + bool has_damage() const { return __flags__.test(7);}; protected: @@ -32,9 +36,11 @@ namespace mtb std::string bomb_id_; std::string raid_wave_; float rad_ = 0.0f; + std::string bombing_time_; + float damage_ = 0.0f; public: - std::bitset<6> __flags__; + std::bitset<8> __flags__; }; }; diff --git a/server/gameserver/mtb/mtb.all.cc b/server/gameserver/mtb/mtb.all.cc index aae39616..039cf8d1 100644 --- a/server/gameserver/mtb/mtb.all.cc +++ b/server/gameserver/mtb/mtb.all.cc @@ -524,13 +524,15 @@ namespace mtb { a8::reflect::Class* meta_class = nullptr; if (!meta_class) { - meta_class = new a8::reflect::Class("AirRaid", 6, 0); + meta_class = new a8::reflect::Class("AirRaid", 8, 0); meta_class->SetSimpleField(0, "id", a8::reflect::ET_INT32, my_offsetof2(AirRaid, id_)); meta_class->SetSimpleField(1, "time", a8::reflect::ET_INT32, my_offsetof2(AirRaid, time_)); meta_class->SetSimpleField(2, "appear_time", a8::reflect::ET_INT32, my_offsetof2(AirRaid, appear_time_)); meta_class->SetSimpleField(3, "bomb_id", a8::reflect::ET_STRING, my_offsetof2(AirRaid, bomb_id_)); meta_class->SetSimpleField(4, "raid_wave", a8::reflect::ET_STRING, my_offsetof2(AirRaid, raid_wave_)); meta_class->SetSimpleField(5, "rad", a8::reflect::ET_FLOAT, my_offsetof2(AirRaid, rad_)); + meta_class->SetSimpleField(6, "bombing_time", a8::reflect::ET_STRING, my_offsetof2(AirRaid, bombing_time_)); + meta_class->SetSimpleField(7, "damage", a8::reflect::ET_FLOAT, my_offsetof2(AirRaid, damage_)); } return meta_class; } diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 5afcd875..e8aaeff2 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -252,6 +252,7 @@ public: void OpenRoomSwitch(int tag); void CloseRoomSwitch(int tag); void NotifyNewsTicker(int msg_type, std::vector msg_content); + std::shared_ptr GetAirRaid() { return air_raid_; } private: void ShuaAndroid(); diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index 43665f53..313ebbd4 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -392,16 +392,16 @@ void RoomObstacle::DetachFromMaster() { if (!detached_) { detached_ = true; + xtimer_attacher.ClearTimerList(); if (master.Get()) { - xtimer_attacher.ClearTimerList(); master.Get()->SlaveOnRemove(this); - room->grid_service->DelRoomEntity(room, this); - if (!IsDead(room)) { - Die(room); - BroadcastFullState(room); - } - room->RemoveObjectLater(this); } + room->grid_service->DelRoomEntity(room, this); + if (!IsDead(room)) { + Die(room); + BroadcastFullState(room); + } + room->RemoveObjectLater(this); } if (!list_empty(&entry)) { list_del_init(&entry); diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 310069da..6e78e60d 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -851,6 +851,7 @@ message MFAirRaid optional int32 appear_time = 1; //空袭出现时间(毫秒) optional MFVec3 pos = 3; //空袭位置 optional float rad = 4; //空袭半径 + optional int32 continue_time = 5; //轰炸持续时间,(在空袭出现后!!!) } //buff diff --git a/server/tools/protobuild/mt.proto b/server/tools/protobuild/mt.proto index 592c3d5e..0058f69b 100755 --- a/server/tools/protobuild/mt.proto +++ b/server/tools/protobuild/mt.proto @@ -419,6 +419,8 @@ message AirRaid optional string bomb_id = 4; optional string raid_wave = 5; optional float rad = 6; + optional string bombling_time = 7; + optional float damage = 8; } message AirLine