diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index 2c9dce2..4954d46 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -641,7 +641,19 @@ namespace MetaData void AirRaid::Init() { - + { + std::vector strings; + a8::Split(i->raid_wave(), strings, '|'); + for (auto& str : strings) { + std::vector strings2; + a8::Split(str, strings2, ':'); + raid_waves.push_back(std::make_tuple( + a8::XValue(strings2[0]).GetInt(), + a8::XValue(strings2[1]).GetInt() + ) + ); + } + } } void AirLine::Init() diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index 8ca15c6..0153583 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -171,6 +171,7 @@ namespace MetaData struct AirRaid { const metatable::AirRaid* i = nullptr; + std::vector> raid_waves; void Init(); }; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 59a4f54..afa14f0 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -3945,32 +3945,49 @@ void Room::AirRaid(int airraid_id) auto raid_cb = [] (const a8::XParams& param) { + auto bomb_cb = + [] (const a8::XParams& param) + { + Room* room = (Room*)param.sender.GetUserData(); + if (room->IsGameOver()) { + return; + } + MetaData::AirRaid* raid_meta = (MetaData::AirRaid*)param.param1.GetUserData(); + a8::Vec2 center = a8::Vec2 + ( + param.param2.GetDouble(), + param.param3.GetDouble() + ); + a8::Vec2 dir = a8::Vec2::UP; + dir.Rotate(a8::RandAngle()); + a8::Vec2 pos = center + dir * (50 + rand() % 100);; + RoomObstacle* obstacle = room->CreateObstacle + ( + raid_meta->i->bomb_id(), + pos.x, + pos.y + ); + obstacle->Active(); + }; Room* room = (Room*)param.sender.GetUserData(); if (room->IsGameOver()) { return; } MetaData::AirRaid* raid_meta = (MetaData::AirRaid*)param.param1.GetUserData(); - a8::Vec2 center = a8::Vec2 - ( - param.param2.GetDouble(), - param.param3.GetDouble() - ); - for (int i = 0; i < raid_meta->i->bomb_num(); ++i) { - a8::Vec2 dir = a8::Vec2::UP; - dir.Rotate(a8::RandAngle()); - a8::Vec2 pos = center + dir * (50 + rand() % 100);; - RoomObstacle* obstacle = room->CreateObstacle - ( - raid_meta->i->bomb_id(), - pos.x, - pos.y - ); - obstacle->Active(); - if (obstacle) { + for (auto& tuple : raid_meta->raid_waves) { + int num = std::get<0>(tuple); + int delay = std::get<1>(tuple); + for (int i = 0; i < num; ++i) { + room->xtimer.AddDeadLineTimerAndAttach + (delay / FRAME_RATE_MS, + a8::XParams() + .SetSender(room) + .SetParam1(raid_meta) + .SetParam2(param.param2.GetDouble()) + .SetParam3(param.param3.GetDouble()), + bomb_cb, + &room->xtimer_attacher_.timer_list_); } - #if 1 - room->BroadcastDebugMsg(a8::Format("airraid pos=%d:%d", {pos.x, pos.y})); - #endif } }; diff --git a/server/tools/protobuild/metatable.proto b/server/tools/protobuild/metatable.proto index baf3db8..17b1b92 100755 --- a/server/tools/protobuild/metatable.proto +++ b/server/tools/protobuild/metatable.proto @@ -269,7 +269,7 @@ message AirRaid optional int32 time = 2; optional int32 appear_time = 3; optional int32 bomb_id = 4; - optional int32 bomb_num = 5; + optional string raid_wave = 5; optional float rad = 6; }