#include "precompile.h" #include #include #include "movement.h" #include "moveableentity.h" #include "room.h" #include "mapinstance.h" #include "creature.h" #include "mt/Map.h" Movement::Movement(Creature* owner) { owner_ = owner; } bool Movement::UpdatePosition() { if (path_index_ >= paths_.size()) { ClearPath(); is_find_path_ = false; return false; } MovePathPoint& curr_point = paths_[path_index_]; { a8::Vec2 dir = a8::Vec2(curr_point.dir.x, curr_point.dir.z); float h = 0.0f; if (owner_->room->map_instance->GetPosHeight(curr_point.curr_pos, h)) { #ifdef DEBUG1 a8::XPrintf("pos:%f,%f,%f h1:%f\n", { owner_->GetPos().x, owner_->GetPos().y, owner_->GetPos().z, h }); #endif curr_point.curr_pos.y = h; } else { //abort(); } curr_point.curr_pos.AddVec2(dir * owner_->GetSpeed()); owner_->SetPos(curr_point.curr_pos); if (owner_->room->map_instance->GetPosHeight(owner_->GetPos(), h)) { #ifdef DEBUG1 a8::XPrintf("pos:%f,%f,%f h2:%f\n", { owner_->GetPos().x, owner_->GetPos().y, owner_->GetPos().z, h }); #endif auto new_pos = owner_->GetPos(); new_pos.y = h; owner_->SetPos(new_pos); } else { //abort(); } } if (owner_->GetPos().Distance2D2(curr_point.src_pos) - curr_point.distance >= 0.0001f) { curr_point.tar_pos.y = curr_point.curr_pos.y; owner_->SetPos(curr_point.tar_pos); float h = 0.0f; if (owner_->room->map_instance->GetPosHeight(owner_->GetPos(), h)) { a8::XPrintf("pos:%f,%f,%f h3:%f\n", { owner_->GetPos().x, owner_->GetPos().y, owner_->GetPos().z, h }); auto new_pos = owner_->GetPos(); new_pos.y = h; owner_->SetPos(new_pos); } else { //abort(); } ++path_index_; if (path_index_ < paths_.size()) { MovePathPoint& next_point = paths_[path_index_]; a8::Vec2 dir = owner_->GetPos().CalcDir2D(next_point.tar_pos); dir.Normalize(); next_point.dir.x = dir.x; next_point.dir.z = dir.y; } } if (owner_->GetPos().x < 0 || owner_->GetPos().y < 0) { abort(); } return true; } void Movement::CalcTargetPos(float distance) { ClearPath(); #ifdef DEBUG1 if (!c->IsPlayer()) { a8::XPrintf("CalcTaretPos old_size:%d\n", {paths_.size()}); } #endif Position pos = owner_->GetPos(); glm::vec3 start = owner_->GetPos().ToGlmVec3(); glm::vec3 end = pos.AddGlmVec3(owner_->GetMoveDir() * distance).ToGlmVec3(); bool hit_result = false; MovePathPoint point; if (owner_->HasBuffEffect(kBET_ThroughWall) || owner_->HasBuffEffect(kBET_Fly) || owner_->HasBuffEffect(kBET_Jump)) { point.tar_pos.FromGlmVec3(end); if (point.tar_pos.x > owner_->room->GetMapMeta()->map_width() + 10) { point.tar_pos.x = owner_->room->GetMapMeta()->map_width() - 10; } if (point.tar_pos.z > owner_->room->GetMapMeta()->map_height() + 10) { point.tar_pos.z = owner_->room->GetMapMeta()->map_height() - 10; } if (point.tar_pos.x < 10) { point.tar_pos.x = 10; } if (point.tar_pos.z < 10) { point.tar_pos.z = 10; } } else { glm::vec3 hit_point; owner_->room->map_instance->Scale(start); owner_->room->map_instance->Scale(end); bool ret = owner_->room->map_instance->Raycast(0, start, end, hit_point, hit_result); if (ret) { owner_->room->map_instance->UnScale(hit_point); point.tar_pos.FromGlmVec3(hit_point); } else { return; } } point.distance = owner_->GetPos().Distance2D2(point.tar_pos); point.src_pos = owner_->GetPos(); point.curr_pos = owner_->GetPos(); if (point.tar_pos.x < 0 || point.tar_pos.z < 0) { abort(); } #ifdef DEBUG if (owner_->IsPlayer()) { a8::XPrintf("CalcTargetPos src_pos:%f,%f,%f tar_pos:%f,%f,%f is_hit:%d start:%f,%f,%f end:%f,%f,%f distance:%f src_distance:%f\n", { point.src_pos.x, point.src_pos.y, point.src_pos.z, point.tar_pos.x, point.tar_pos.y, point.tar_pos.z, hit_result ? 1 : 0, start.x, start.y, start.z, end.x, end.y, end.z, point.distance, distance }); } #endif if (point.distance < 0.00001f / owner_->room->GetMapMeta()->scale()) { return; } a8::Vec2 dir = owner_->GetPos().CalcDir2D(point.tar_pos); dir.Normalize(); point.dir.x = dir.x; point.dir.z = dir.y; paths_.push_back(point); } void Movement::ClearPath() { is_find_path_ = false; path_index_ = 0; paths_.clear(); } void Movement::AddPaths(const glm::vec3& start, std::vector& paths) { #if 0 if (paths.empty()) { abort(); return; } glm::vec3 last_pos; last_pos.x = start.x; last_pos.y = start.y; last_pos.z = start.z; size_t i = 0; if (std::abs(last_pos.x - paths[0].x) < 0.00001f && std::abs(last_pos.z - paths[0].z) < 0.00001f) { if (paths.size() < 2) { abort(); } ++i; } for (; i < paths.size(); ++i) { MovePathPoint p; p.src_pos = last_pos; p.src_pos.x *= 10.f; p.src_pos.y *= 10.f; p.src_pos.z *= 10.f; p.tar_pos.x = paths[i].x * 10.f; p.tar_pos.y = paths[i].y * 10.f; p.tar_pos.z = paths[i].z * 10.f; p.curr_pos = p.src_pos; glm::vec2 src_pos; glm::vec2 tar_pos; src_pos.x = p.src_pos.x; src_pos.y = p.src_pos.z; tar_pos.x = p.tar_pos.x; tar_pos.y = p.tar_pos.z; { a8::Vec2 v1; a8::Vec2 v2; v1.x = tar_pos.x; v1.y = tar_pos.y; v2.x = src_pos.x; v2.y = src_pos.y; p.distance = v1.Distance(v2); } glm::vec2 dir = tar_pos - src_pos; dir = glm::normalize(dir); if (isnan(dir.x)) { abort(); } if (isnan(dir.y)) { abort(); } p.dir.x = dir.x; p.dir.y = 0; p.dir.z = dir.y; last_pos.x = paths[i].x; last_pos.y = paths[i].y; last_pos.z = paths[i].z; #ifdef DEBUG1 a8::XPrintf("AddPaths size:%d i:%d src_pos:%f,%f tar_pos:%f:%f\n", { paths.size(), i, src_pos.x, src_pos.y, tar_pos.x, tar_pos.y}); #endif paths_.push_back(p); } #endif is_find_path_ = true; } size_t Movement::GetPathSize() { return paths_.size(); }