229 lines
6.0 KiB
C++
229 lines
6.0 KiB
C++
#include "precompile.h"
|
|
|
|
#include <math.h>
|
|
#include <glm/glm.hpp>
|
|
|
|
#include "movehelper.h"
|
|
#include "moveableentity.h"
|
|
#include "room.h"
|
|
#include "mapinstance.h"
|
|
#include "creature.h"
|
|
#include "metamgr.h"
|
|
|
|
MoveHelper::MoveHelper(Creature* owner)
|
|
{
|
|
owner_ = owner;
|
|
}
|
|
|
|
bool MoveHelper::GetMovePosition(glm::vec3& out_pos)
|
|
{
|
|
if (path_index_ >= paths_.size()) {
|
|
ClearPath();
|
|
return false;
|
|
}
|
|
MovePathPoint& curr_point = paths_[path_index_];
|
|
{
|
|
a8::Vec2 dir = a8::Vec2(curr_point.dir.x, curr_point.dir.z);
|
|
curr_point.curr_pos.AddVec2(dir * owner_->GetSpeed());
|
|
owner_->SetPos(curr_point.curr_pos);
|
|
}
|
|
if (owner_->GetPos().Distance2D2(curr_point.src_pos) - curr_point.distance >= 0.0001f) {
|
|
owner_->SetPos(curr_point.tar_pos);
|
|
++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 MoveHelper::CalcTargetPos(float distance)
|
|
{
|
|
ClearPath();
|
|
#ifdef DEBUG1
|
|
if (!c->IsPlayer()) {
|
|
a8::XPrintf("CalcTaretPos old_size:%d\n", {paths_.size()});
|
|
}
|
|
#endif
|
|
glm::vec3 start = owner_->GetPos().ToGlmVec3();
|
|
glm::vec3 end = owner_->GetPos().AddVec2(owner_->GetMoveDir() * distance).ToGlmVec3();
|
|
|
|
bool is_hit = 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()->pb->map_width() + 10) {
|
|
point.tar_pos.x = owner_->room->GetMapMeta()->pb->map_width() - 10;
|
|
}
|
|
if (point.tar_pos.z > owner_->room->GetMapMeta()->pb->map_height() + 10) {
|
|
point.tar_pos.z = owner_->room->GetMapMeta()->pb->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;
|
|
start *= owner_->room->GetMapMeta()->pb->scale();
|
|
end *= owner_->room->GetMapMeta()->pb->scale();
|
|
int ret = owner_->room->map_instance->Raycast(0, start, end, hit_point);
|
|
if (ret > 0) {
|
|
is_hit = true;
|
|
point.tar_pos.FromGlmVec3(hit_point / owner_->room->GetMapMeta()->pb->scale());
|
|
} else {
|
|
point.tar_pos.FromGlmVec3(end / owner_->room->GetMapMeta()->pb->scale());
|
|
}
|
|
}
|
|
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,
|
|
is_hit ? 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()->pb->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 MoveHelper::ClearPath()
|
|
{
|
|
path_index_ = 0;
|
|
paths_.clear();
|
|
}
|
|
|
|
void MoveHelper::AddPaths(const a8::Vec3& start, std::vector<a8::Vec3>& 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
|
|
}
|
|
|
|
size_t MoveHelper::GetPathSize()
|
|
{
|
|
return paths_.size();
|
|
}
|