diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index 2f2ce080..7d91a916 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -17,6 +17,7 @@ #include "ability.h" #include "netdata.h" #include "collision.h" +#include "debugcmd.h" #include "mt/MapThing.h" #include "mt/Skill.h" @@ -277,7 +278,16 @@ void RoomObstacle::Active() break; case kObstacleFlameSurface: { - ActiveFlameSurface(); + life_time_timer = room->xtimer.SetTimeoutWpEx + ( + 1, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + ActiveFlameSurface(); + } + }, + &xtimer_attacher); } break; default: @@ -903,15 +913,39 @@ void RoomObstacle::ActiveFlameSurface() ForceGridList(); glm::vec3 dir = GlmHelper::UP; GlmHelper::RotateY(dir, rotate_); - glm::vec3 adjusted_pos = GetPos().ToGlmVec3() + dir * (meta->height() / 2.0f); + glm::vec3 adjusted_pos = GetPos().ToGlmVec3() + dir * (meta->height() / 4.0f); + std::shared_ptr> points = std::make_shared>(); + float r = 10; + int width = meta->width() / r / 2; + int height = meta->height() / 2 / r / 2; + if (width < 1 || height < 1) { + return; + } + for (int i = 0; i < width; ++i) { + for (int j = 0; j < height; ++j) { + glm::vec3 pos = GetPos().ToGlmVec3(); + pos.x = (-meta->width()) / 2 + r + i * r * 2; + pos.y = 0; + pos.z = r + j * r * 2; + GlmHelper::RotateY(pos, glm::radians(rotate_ * 180.0f)); + points->push_back(GetPos().ToGlmVec3() + pos); + #if 0 + DebugCmd::CreateSphere(master.Get(), + GetPos().ToGlmVec3() + pos, + glm::vec3(1.0f, 1.0f, 1.0f), + room->AllocUniid()); + #endif + } + } + int hit_count = 0; auto cb = - [this, adjusted_pos] () + [this, adjusted_pos, points, r, hit_count] () mutable { std::vector human_list; room->grid_service->TraverseAllLayerHumanList (room->GetRoomIdx(), *grid_list_, - [this, &human_list, &adjusted_pos] (Human* hum, bool& stop) + [this, &human_list, &adjusted_pos, &points, r, hit_count] (Human* hum, bool& stop) mutable { if (hum->dead) { return; @@ -919,9 +953,24 @@ void RoomObstacle::ActiveFlameSurface() if (!master.Get()) { return; } + #if 0 if (master.Get()->team_id == hum->team_id) { return; } + #endif +#if 1 + for (size_t i = 0; i < points->size(); ++i) { + auto point = points->at(i); + if(a8::IntersectCylinderCylinder + ( + point, r, 10, + hum->GetPos().ToGlmVec3(), hum->GetHitRadius(), 10 + )) { + human_list.push_back(hum); + return; + } + } +#else if (Collision::Check2dRotationRectangle ( hum->GetPos().GetX(), @@ -931,20 +980,31 @@ void RoomObstacle::ActiveFlameSurface() adjusted_pos.z, meta->width(), meta->height() / 2.0f, - GetRotate() * 180.f + glm::radians(GetRotate() * 180.f / A8_PI) )) { human_list.push_back(hum); } +#endif } ); + if (!human_list.empty() && master.Get() && master.Get()->IsPlayer()) { + ++hit_count; +#ifdef MYDEBUG + a8::XPrintf("火焰枪地面命中 hit_count:%d point_size:%d height:%d width:%d rotate:%f\n", + { + hit_count, + points->size(), + meta->height(), + meta->width(), + rotate_ + }); +#endif + } for (auto& hum : human_list) { for (int buff_id : meta->_buff_list) { if (!hum->GetBuffById(buff_id)) { hum->TryAddBuff(master.Get(), buff_id); -#ifdef MYDEBUG - a8::XPrintf("火焰枪地面命中\n", {}); -#endif } } } @@ -952,7 +1012,7 @@ void RoomObstacle::ActiveFlameSurface() room->xtimer.SetIntervalEx ( 1000 / FRAME_RATE_MS, - [this, cb] (int event, const a8::Args* args) + [this, cb] (int event, const a8::Args* args) mutable { if (a8::TIMER_EXEC_EVENT == event) { cb();