diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 880581b..feca7d5 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1,5 +1,7 @@ #include "precompile.h" +#include + #include #include @@ -1647,6 +1649,20 @@ void Human::_UpdateMove(int speed) CheckGrass(); } +void Human::PullHuman(const a8::Vec2& pull_dir, float distance) +{ + for (int i = 0; i < distance; ++i) { + a8::Vec2 old_pos = pos; + pos = pos + pull_dir; + if (IsCollisionInMapService()) { + pos = old_pos; + break; + } + room->grid_service.MoveHuman(this); + } + CheckGrass(); +} + void Human::ClearFrameData() { if (!new_objects.empty()) { @@ -1876,8 +1892,27 @@ void Human::ProcSkillPhase(MetaData::SkillPhase* phase) switch (phase->func_id) { case Skill_Jump: { + a8::Vec2 old_pos = pos; pos = skill_target_pos; - CheckGrass(); + if (IsCollisionInMapService()) { + pos = old_pos; + } else { + for (auto& cell : grid_list) { + for (Human* hum : cell->human_list) { + if (hum->team_id != team_id && hum->pos.Distance(skill_target_pos) < hum->GetRadius()) { + hum->DecHP(phase->param1.GetDouble(), entity_uniid, name, 0); + a8::Vec2 pull_dir = pos - old_pos; + if (std::abs(pull_dir.x) > FLT_EPSILON || + std::abs(pull_dir.y) > FLT_EPSILON) { + pull_dir.Normalize(); + hum->PullHuman(pull_dir, phase->param2.GetDouble()); + } + } + } + } + room->grid_service.MoveHuman(this); + CheckGrass(); + } } break; case Skill_Shot: diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 91fce3d..57cbf44 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -213,6 +213,7 @@ class Human : public Entity protected: void _UpdateMove(int speed); + void PullHuman(const a8::Vec2& pull_dir, float distance); private: void ClearFrameData();