2016-03-27 11:49:47 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
// actor.cpp:
|
|
|
|
|
|
|
|
#include "actor.h"
|
|
|
|
|
|
|
|
ActorPath::ActorPath()
|
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
m_FallHeight = 96;
|
|
|
|
m_path = NULL;
|
|
|
|
m_pathlen = 0;
|
|
|
|
m_fLookAhead = 4096.0f;
|
|
|
|
m_bChangeLookAhead = true;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
Clear();
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ActorPath::~ActorPath()
|
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
if (m_path) {
|
|
|
|
delete[] m_path;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::Clear(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
m_startpathpos = 0;
|
|
|
|
m_pathpos = 0;
|
|
|
|
m_Side = false;
|
|
|
|
m_Time = -10000000;
|
|
|
|
m_delta[0] = 0;
|
|
|
|
m_delta[1] = 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
bool ActorPath::DoesTheoreticPathExist(
|
|
|
|
float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared
|
|
|
|
)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return PathSearch::FindPath(start, end, ent, maxPath, NULL, 0, m_FallHeight) != 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::FindPath(
|
|
|
|
float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared
|
|
|
|
)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
int depth = PathManager.FindPath(start, end, ent, maxPath, vLeashHome, fLeashDistSquared, m_FallHeight);
|
|
|
|
|
|
|
|
if (depth) {
|
|
|
|
if (depth > m_pathlen) {
|
|
|
|
if (m_path) {
|
|
|
|
delete[] m_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pathlen = 10 * ((depth - 1) / 10) + 10;
|
|
|
|
m_path = new PathInfo[m_pathlen];
|
|
|
|
}
|
|
|
|
|
|
|
|
m_startpathpos = PathManager.GeneratePath(m_path);
|
|
|
|
m_pathpos = m_startpathpos;
|
|
|
|
m_TotalDist = PathManager.total_dist;
|
|
|
|
m_Side = false;
|
|
|
|
m_Time = level.inttime;
|
|
|
|
UpdatePos(start);
|
|
|
|
} else {
|
|
|
|
Clear();
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::FindPathAway(
|
|
|
|
float *start,
|
|
|
|
float *avoid,
|
|
|
|
float *vPreferredDir,
|
|
|
|
Entity *ent,
|
|
|
|
float fMinSafeDist,
|
|
|
|
float *vLeashHome,
|
|
|
|
float fLeashDistSquared
|
|
|
|
)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
int depth = PathManager.FindPathAway(
|
|
|
|
start, avoid, vPreferredDir, ent, fMinSafeDist, vLeashHome, fLeashDistSquared, m_FallHeight
|
|
|
|
);
|
|
|
|
|
|
|
|
if (depth) {
|
|
|
|
if (depth > m_pathlen) {
|
|
|
|
if (m_path) {
|
|
|
|
delete[] m_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pathlen = 10 * (depth - 1) / 10 + 10;
|
|
|
|
m_path = new PathInfo[m_pathlen];
|
|
|
|
}
|
|
|
|
|
|
|
|
m_startpathpos = PathManager.GeneratePathAway(m_path);
|
|
|
|
m_pathpos = m_startpathpos;
|
|
|
|
m_TotalDist = PathManager.total_dist;
|
|
|
|
m_Side = false;
|
|
|
|
m_Time = level.inttime;
|
|
|
|
UpdatePos(start);
|
|
|
|
} else {
|
|
|
|
Clear();
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::FindPathNear(
|
|
|
|
float *start,
|
|
|
|
float *nearby,
|
|
|
|
Entity *ent,
|
|
|
|
float maxPath,
|
|
|
|
float fRadiusSquared,
|
|
|
|
float *vLeashHome,
|
|
|
|
float fLeashDistSquared
|
|
|
|
)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
int depth = PathManager.FindPathNear(
|
|
|
|
start, nearby, ent, maxPath, fRadiusSquared, vLeashHome, fLeashDistSquared, m_FallHeight
|
|
|
|
);
|
|
|
|
|
|
|
|
if (depth) {
|
|
|
|
if (depth > m_pathlen) {
|
|
|
|
if (m_path) {
|
|
|
|
delete[] m_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pathlen = 10 * (depth - 1) / 10 + 10;
|
|
|
|
m_path = new PathInfo[m_pathlen];
|
|
|
|
}
|
|
|
|
|
|
|
|
m_startpathpos = PathManager.GeneratePathNear(m_path);
|
|
|
|
m_pathpos = m_startpathpos;
|
|
|
|
m_TotalDist = PathManager.total_dist;
|
|
|
|
m_Side = false;
|
|
|
|
m_Time = level.inttime;
|
|
|
|
UpdatePos(start);
|
|
|
|
} else {
|
|
|
|
Clear();
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::ReFindPath(float *start, Entity *ent)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
vec3_t point;
|
|
|
|
// this is a critical bug in all versions of mohaa, it passes directly m_path->point
|
|
|
|
// but m_path can be deleted afterwards, leaving a dangling pointer to the path_end
|
|
|
|
// global variable
|
|
|
|
VectorCopy(m_path->point, point);
|
|
|
|
int depth = PathManager.FindPath(start, point, ent, 0, NULL, 0, m_FallHeight);
|
|
|
|
|
|
|
|
if (depth) {
|
|
|
|
if (depth > m_pathlen) {
|
|
|
|
if (m_path) {
|
|
|
|
delete[] m_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pathlen = 10 * (depth - 1) / 10 + 10;
|
|
|
|
m_path = new PathInfo[m_pathlen];
|
|
|
|
}
|
|
|
|
|
|
|
|
m_startpathpos = PathManager.GeneratePath(m_path);
|
|
|
|
m_pathpos = m_startpathpos;
|
|
|
|
m_TotalDist = PathManager.total_dist;
|
|
|
|
m_Side = false;
|
|
|
|
m_Time = level.inttime;
|
|
|
|
UpdatePos(start);
|
|
|
|
} else {
|
|
|
|
Clear();
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
float ActorPath::PathLookAhead(float total_area, Vector& end, float *origin)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
float area = total_area;
|
|
|
|
float s;
|
|
|
|
float t;
|
|
|
|
float normal[2];
|
|
|
|
float delta[2];
|
|
|
|
Vector pos;
|
|
|
|
float fallheight;
|
|
|
|
PathInfo *current_path = m_pathpos;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
while (1) {
|
|
|
|
pos = current_path->point;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (current_path == m_path) {
|
|
|
|
break;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
fallheight = current_path->point[2] - origin[2];
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (fallheight > 94.0f || fallheight < -94.0f) {
|
|
|
|
VectorCopy(current_path->point, end);
|
|
|
|
m_HasCompleteLookahead = false;
|
|
|
|
return area;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
current_path--;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
normal[0] = current_path->point[1] - pos[1];
|
|
|
|
normal[1] = pos[0] - current_path->point[0];
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
VectorNormalize2D(normal);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
delta[0] = current_path->point[0] - origin[0];
|
|
|
|
delta[1] = current_path->point[1] - origin[1];
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
t = fabs(DotProduct2D(delta, normal)) * current_path->dist;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (t >= area) {
|
|
|
|
t = area / t;
|
|
|
|
s = 1.0f - t;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
end[0] = current_path->point[0] * t + pos[0] * s;
|
|
|
|
end[1] = current_path->point[1] * t + pos[1] * s;
|
|
|
|
end[2] = current_path->point[2] * t + pos[2] * s;
|
|
|
|
m_HasCompleteLookahead = false;
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
area -= t;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
VectorCopy(current_path->point, end);
|
|
|
|
m_HasCompleteLookahead = true;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
return area;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::UpdatePos(float *origin, float fNodeRadius)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
Vector end;
|
|
|
|
float s = 0;
|
|
|
|
float t = 0;
|
|
|
|
vec2_t delta;
|
|
|
|
float current_dot = 0;
|
|
|
|
float previous_dot = 0;
|
|
|
|
Vector pos;
|
|
|
|
PathInfo *current_path = NULL;
|
|
|
|
vec2_t dir;
|
|
|
|
Vector end2;
|
|
|
|
vec2_t delta2;
|
|
|
|
vec2_t dir2;
|
|
|
|
|
|
|
|
if (m_pathpos == m_path) {
|
|
|
|
end = m_pathpos->point;
|
|
|
|
m_bChangeLookAhead = true;
|
|
|
|
m_HasCompleteLookahead = true;
|
|
|
|
m_delta[0] = end[0] - origin[0];
|
|
|
|
m_delta[1] = end[1] - origin[1];
|
|
|
|
VectorNormalize2D2(m_delta, dir);
|
|
|
|
} else if (m_fLookAhead >= 4096.0f) {
|
|
|
|
if (m_fLookAhead - 4096.0f >= PathLookAhead(m_fLookAhead, end, origin)) {
|
|
|
|
Vector mins = Vector(-15, -15, 0);
|
|
|
|
Vector maxs = Vector(15, 15, 60);
|
|
|
|
Vector e = end + Vector(0, 0, 32);
|
|
|
|
|
|
|
|
pos = origin + Vector(0, 0, 32);
|
|
|
|
|
|
|
|
if (G_SightTrace(
|
|
|
|
pos,
|
|
|
|
mins,
|
|
|
|
maxs,
|
|
|
|
e,
|
|
|
|
(gentity_t *)NULL, // g_entities[ 0 ].entity
|
|
|
|
0,
|
|
|
|
MASK_PLAYERSOLID,
|
|
|
|
false,
|
|
|
|
"Actor::UpdatePos 2"
|
|
|
|
)
|
|
|
|
!= true) {
|
|
|
|
if (m_bChangeLookAhead) {
|
|
|
|
m_fLookAhead -= 2048.0f;
|
|
|
|
m_bChangeLookAhead = false;
|
|
|
|
} else {
|
|
|
|
m_fLookAhead *= 0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_fLookAhead < 4096.0f) {
|
|
|
|
m_fLookAhead = 4096.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
PathLookAhead(4096.0f, end, origin);
|
|
|
|
goto __setdelta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_fLookAhead += 1024.0f;
|
|
|
|
|
|
|
|
if (m_fLookAhead > 65536.0f) {
|
|
|
|
m_fLookAhead = 65536.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bChangeLookAhead = true;
|
|
|
|
|
|
|
|
__setdelta:
|
|
|
|
|
|
|
|
m_delta[0] = end[0] - origin[0];
|
|
|
|
m_delta[1] = end[1] - origin[1];
|
|
|
|
|
|
|
|
VectorNormalize2D2(m_delta, dir);
|
|
|
|
} else if (PathLookAhead(4096.0f, end, origin) < 4096.0f - m_fLookAhead) {
|
|
|
|
PathLookAhead(m_fLookAhead, end2, origin);
|
|
|
|
|
|
|
|
Vector mins = Vector(-15, -15, 0);
|
|
|
|
Vector maxs = Vector(15, 15, 60);
|
|
|
|
Vector e = end2 + Vector(0, 0, 32);
|
|
|
|
|
|
|
|
pos = origin + Vector(0, 0, 32);
|
|
|
|
|
|
|
|
if (G_SightTrace(pos, mins, maxs, e, (gentity_t *)NULL, 0, MASK_MONSTERSOLID, false, "Actor::UpdatePos 1")
|
|
|
|
!= true) {
|
|
|
|
m_fLookAhead += 1024.0f;
|
|
|
|
|
|
|
|
if (m_fLookAhead > 4096.0f) {
|
|
|
|
m_fLookAhead = 4096.0f;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
m_fLookAhead -= 1024.0f;
|
|
|
|
|
|
|
|
if (m_fLookAhead < 1024.0f) {
|
|
|
|
m_fLookAhead = 1024.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
PathLookAhead(m_fLookAhead, end2, origin);
|
|
|
|
}
|
|
|
|
|
|
|
|
delta[0] = end2[0] - origin[0];
|
|
|
|
delta[1] = end2[1] - origin[1];
|
|
|
|
VectorNormalize2D2(delta, dir2);
|
|
|
|
|
|
|
|
m_delta[0] = end[0] - origin[0];
|
|
|
|
m_delta[1] = end[1] - origin[1];
|
|
|
|
VectorNormalize2D2(m_delta, dir);
|
|
|
|
|
|
|
|
if (DotProduct2D(dir, dir2) > 0.7f) {
|
|
|
|
m_delta[0] = delta[0];
|
|
|
|
m_delta[1] = delta[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bChangeLookAhead = true;
|
|
|
|
} else {
|
|
|
|
m_fLookAhead -= 1024.0f;
|
|
|
|
|
|
|
|
if (m_fLookAhead < 1024.0f) {
|
|
|
|
m_fLookAhead = 1024.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_delta[0] = end[0] - origin[0];
|
|
|
|
m_delta[1] = end[1] - origin[1];
|
|
|
|
VectorNormalize2D2(m_delta, dir);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
m_bChangeLookAhead = true;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
current_path = m_pathpos;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
while (1) {
|
|
|
|
delta2[0] = current_path->point[0] - origin[0];
|
|
|
|
delta2[1] = current_path->point[1] - origin[1];
|
|
|
|
current_dot = DotProduct2D(delta2, dir) - fNodeRadius;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (current_dot >= 0.0f) {
|
|
|
|
break;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
previous_dot = current_dot;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (current_path == LastNode()) {
|
|
|
|
break;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
current_path--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current_path != m_pathpos) {
|
|
|
|
m_pathpos = current_path + 1;
|
|
|
|
|
|
|
|
t = previous_dot / (previous_dot - current_dot);
|
|
|
|
s = 1.0f - t;
|
|
|
|
|
|
|
|
/*m_pathpos->point[ 0 ] = m_pathpos->point[ 0 ] * s + current_path->point[ 0 ] * t;
|
2016-03-27 11:49:47 +02:00
|
|
|
m_pathpos->point[ 1 ] = m_pathpos->point[ 1 ] * s + current_path->point[ 1 ] * t;
|
|
|
|
m_pathpos->point[ 2 ] = m_pathpos->point[ 2 ] * s + current_path->point[ 2 ] * t;*/
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
VectorCopy(current_path->point, m_pathpos->point);
|
|
|
|
|
|
|
|
current_path->dist *= s;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
m_Side = true;
|
|
|
|
} else {
|
|
|
|
m_Side = false;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
bool ActorPath::Complete(const float *origin) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
if (!m_HasCompleteLookahead) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (!m_path) {
|
|
|
|
return true;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
if (fabs(origin[0] - m_path->point[0]) < 16.0f && fabs(origin[1] - m_path->point[1]) < 16.0f) {
|
|
|
|
return true;
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
return false;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
PathInfo *ActorPath::StartNode(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_startpathpos;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
PathInfo *ActorPath::CurrentNode(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_pathpos;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
int ActorPath::CurrentNodeIndex(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_pathpos ? m_pathpos - m_path : -1;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
PathInfo *ActorPath::NextNode(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_pathpos == m_path ? NULL : m_pathpos - 1;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
PathInfo *ActorPath::LastNode(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_path;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
Vector ActorPath::CurrentPathDir(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return Vector(m_pathpos->dir[0], m_pathpos->dir[1], 0);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
float *ActorPath::CurrentPathGoal(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_pathpos->point;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
int ActorPath::Time(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_Time;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
Vector ActorPath::CurrentDelta(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return Vector(m_delta[0], m_delta[1], 0);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
bool ActorPath::IsAccurate(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_pathpos->bAccurate;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
float ActorPath::TotalDist(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_TotalDist;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::SetFallHeight(float fHeight)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
m_FallHeight = fHeight;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
float ActorPath::GetFallHeight(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_FallHeight;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::TrimPathFromEnd(int nNodesPop)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
int iLastPos = m_path - m_pathpos;
|
|
|
|
|
|
|
|
if (iLastPos - nNodesPop > 0) {
|
|
|
|
for (int i = 0; i < iLastPos; i++) {
|
|
|
|
m_path[i] = m_path[i + nNodesPop];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Clear();
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::Shorten(float fDistRemove)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
if (m_path->dist > fDistRemove) {
|
|
|
|
m_path->point[0] += m_path->dir[0] * -fDistRemove;
|
|
|
|
m_path->point[1] += m_path->dir[1] * -fDistRemove;
|
|
|
|
m_path->point[2] += m_path->point[2] * -fDistRemove;
|
|
|
|
m_path->dist -= fDistRemove;
|
|
|
|
} else {
|
|
|
|
while (fDistRemove - m_path->dist > m_path->dist) {
|
|
|
|
TrimPathFromEnd(1);
|
|
|
|
|
|
|
|
if (!m_pathpos) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
bool ActorPath::HasCompleteLookahead(void) const
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_HasCompleteLookahead;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
bool ActorPath::IsSide(void) const
|
2018-08-19 08:26:59 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
return m_Side;
|
2018-08-19 08:26:59 +02:00
|
|
|
}
|
|
|
|
|
2023-10-12 20:18:22 +02:00
|
|
|
void ActorPath::ForceShortLookahead(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-12 20:18:22 +02:00
|
|
|
m_fLookAhead = 4096.0f;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|