diff --git a/server/gameserver/collision.cc b/server/gameserver/collision.cc index a478b849..c9ebf178 100644 --- a/server/gameserver/collision.cc +++ b/server/gameserver/collision.cc @@ -1,5 +1,7 @@ #include "precompile.h" +#include + #include #include "collision.h" @@ -28,3 +30,50 @@ bool Collision::CheckCB(Creature* c, Obstacle* b) { return false; } + +static float TwoDistance(float x1, float y1, float x2, float y2) +{ + return pow(pow((x1 - x2), 2.0f) + pow((y1 - y2), 2.0f), 0.5); +} + +static float rot(float x1, float y1, float x2, float y2) +{ + float value = (y1 - y2) / (x1 - x2); + return atan(value) * 180 / A8_PI; +} + +static void GetNewRxRy(float x1, float y1, float x2, float y2, float dro, float& new_rx, float& new_ry) +{ + float distance = TwoDistance(x1, y1, x2, y2); + float new_rot = rot(x1, y1, x2, y2) - dro; + new_rx = cos(new_rot / 180 * A8_PI) * distance; + new_ry = sin(new_rot / 180 * A8_PI) * distance; +} + +bool Collision::Check2dRotationRectangle(float rx, float ry, float r, float dx, float dy, float dw, float dh, float dro) +{ + float new_rx = 0.0f; + float new_ry = 0.0f; + GetNewRxRy(rx, ry, dx, dy, dro, new_rx, new_ry); + + float tmp_dx = std::min(new_rx, dw * 0.5f); + float tmp_dx1 = std::max(tmp_dx, -dw * 0.5f); + float tmp_dy = std::min(new_ry, dh * 0.5f); + float tmp_dy1 = std::max(tmp_dy, -dh * 0.5f); + +#ifdef DEBUG1 + a8::XPrintf("new_rx:%f new_ry:%f dx1:%f dy1:%f dro:%f v1:%f v2:%f r:%f,%f d:%f,%f\n", + { + new_rx, + new_ry, + tmp_dx1, + tmp_dy1, + dro, + (tmp_dx1 - new_rx) * (tmp_dx1 - new_rx) + (tmp_dy1 - new_ry) * (tmp_dy1 - new_ry) , + r*r, + rx,ry, + dx,dy + }); +#endif + return (tmp_dx1 - new_rx) * (tmp_dx1 - new_rx) + (tmp_dy1 - new_ry) * (tmp_dy1 - new_ry) <= r * r; +} diff --git a/server/gameserver/collision.h b/server/gameserver/collision.h index 3e36823a..dd0b0e18 100644 --- a/server/gameserver/collision.h +++ b/server/gameserver/collision.h @@ -12,4 +12,14 @@ class Collision static bool CheckCC(Creature* a, Creature* b); static bool CheckCB(Creature* c, Obstacle* b); + /* + --圆与旋转矩形碰撞 + --rx ry 圆坐标 + --r 圆半径 + --dx dy 矩形坐标 + --dw dh 矩形长宽 + --dro 矩形旋转角度 + */ + static bool Check2dRotationRectangle(float rx, float ry, float r, float dx, float dy, float dw, float dh, float dro); + }; diff --git a/server/gameserver/skill.cc b/server/gameserver/skill.cc index b5cde48d..e7de11dc 100644 --- a/server/gameserver/skill.cc +++ b/server/gameserver/skill.cc @@ -14,6 +14,7 @@ #include "pbutils.h" #include "ability.h" #include "battledatacontext.h" +#include "collision.h" #include "mt/Buff.h" #include "mt/Skill.h" @@ -588,26 +589,22 @@ void Skill::ProcCMXD() bool* is_hit = args.Get(0); Entity* e = args.Get(1); if (sender.Get() && e->IsCreature(sender.Get()->room)) { - // 999 - #if 1 - #else Creature* c = (Creature*)e; - a8::Vec2 target_pos = sender.Get()->GetPos() + - sender.Get()->GetAttackDir() * SkillHelper::GetCmxdRange(this_skill_meta) / 2; - bool ret = Check2dRotationRectangle + glm::vec3 target_pos = sender.Get()->GetPos().ToGlmVec3(); + target_pos = target_pos + (sender.Get()->GetAttackDir() * (float)SkillHelper::GetCmxdRange(this_skill_meta) / 2.0f); + bool ret = Collision::Check2dRotationRectangle (c->GetPos().x, c->GetPos().y, 20, target_pos.x, target_pos.y, - shield_buff_meta->param4, + shield_buff_meta->_param4, SkillHelper::GetCmxdRange(this_skill_meta), sender.Get()->GetAttackDirRotate() * 180.0f ); if (ret) { *is_hit = true; } - #endif } } );