mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 09:44:45 +01:00
remove useless pathfinding code.
This commit is contained in:
@@ -26,8 +26,6 @@
|
||||
#include "MoveSpline.h"
|
||||
#include "Player.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
template<class T, typename D>
|
||||
void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
|
||||
{
|
||||
@@ -65,30 +63,27 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
|
||||
i_target->GetClosePoint(x, y, z, owner.GetObjectSize(), i_offset, i_angle);
|
||||
}
|
||||
|
||||
/*
|
||||
We MUST not check the distance difference and avoid setting the new location for smaller distances.
|
||||
By that we risk having far too many GetContactPoint() calls freezing the whole system.
|
||||
In TargetedMovementGenerator<T>::Update() we check the distance to the target and at
|
||||
some range we calculate a new position. The calculation takes some processor cycles due to vmaps.
|
||||
If the distance to the target it too large to ignore,
|
||||
but the distance to the new contact point is short enough to be ignored,
|
||||
we will calculate a new contact point each update loop, but will never move to it.
|
||||
The system will freeze.
|
||||
ralf
|
||||
|
||||
//We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
|
||||
float bothObjectSize = i_target->GetObjectBoundingRadius() + owner.GetObjectBoundingRadius() + CONTACT_DISTANCE;
|
||||
if ( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
|
||||
return;
|
||||
*/
|
||||
if (!i_path)
|
||||
i_path = new PathFinderMovementGenerator(&owner);
|
||||
|
||||
// allow pets following their master to cheat while generating paths
|
||||
bool forceDest = (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->isPet()
|
||||
&& owner.HasUnitState(UNIT_STAT_FOLLOW));
|
||||
i_path->calculate(x, y, z, forceDest);
|
||||
if (i_path->getPathType() & PATHFIND_NOPATH)
|
||||
return;
|
||||
|
||||
D::_addUnitStateMove(owner);
|
||||
i_targetReached = false;
|
||||
i_recalculateTravel = false;
|
||||
owner.AddUnitState(UNIT_STATE_CHASE);
|
||||
|
||||
Movement::MoveSplineInit init(owner);
|
||||
init.MoveTo(x,y,z);
|
||||
if (!i_target->IsInWater())
|
||||
init.MovebyPath(i_path->getPath());
|
||||
else
|
||||
init.MoveTo(i_target->GetPositionX(), i_target->GetPositionY(), i_target->GetPositionZ(), false, false);
|
||||
|
||||
init.SetWalk(((D*)this)->EnableWalking());
|
||||
init.Launch();
|
||||
}
|
||||
@@ -125,7 +120,7 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_
|
||||
if (!i_target.isValid() || !i_target->IsInWorld())
|
||||
return false;
|
||||
|
||||
if (!owner.isAlive())
|
||||
if (!&owner || !owner.isAlive())
|
||||
return true;
|
||||
|
||||
if (owner.HasUnitState(UNIT_STATE_NOT_MOVE))
|
||||
@@ -152,11 +147,18 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_
|
||||
i_recheckDistance.Update(time_diff);
|
||||
if (i_recheckDistance.Passed())
|
||||
{
|
||||
i_recheckDistance.Reset(50);
|
||||
i_recheckDistance.Reset(100);
|
||||
//More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
float allowed_dist = i_target->GetObjectSize() + owner.GetObjectSize() + MELEE_RANGE - 0.5f;
|
||||
float dist = (owner.movespline->FinalDestination() - G3D::Vector3(i_target->GetPositionX(),i_target->GetPositionY(),i_target->GetPositionZ())).squaredLength();
|
||||
if (dist >= allowed_dist * allowed_dist)
|
||||
float allowed_dist = owner.GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
|
||||
G3D::Vector3 dest = owner.movespline->FinalDestination();
|
||||
|
||||
bool targetMoved = false;
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist);
|
||||
else
|
||||
targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist);
|
||||
|
||||
if (targetMoved)
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "FollowerReference.h"
|
||||
#include "Timer.h"
|
||||
#include "Unit.h"
|
||||
#include "PathFinderMovementGenerator.h"
|
||||
|
||||
class TargetedMovementGeneratorBase
|
||||
{
|
||||
@@ -38,12 +39,12 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >,
|
||||
{
|
||||
protected:
|
||||
TargetedMovementGeneratorMedium(Unit &target, float offset, float angle) :
|
||||
TargetedMovementGeneratorBase(target), i_recheckDistance(0),
|
||||
TargetedMovementGeneratorBase(target), i_recheckDistance(0),, i_path(NULL),
|
||||
i_offset(offset), i_angle(angle),
|
||||
i_recalculateTravel(false), i_targetReached(false)
|
||||
{
|
||||
}
|
||||
~TargetedMovementGeneratorMedium() {}
|
||||
~TargetedMovementGeneratorMedium() { delete i_path; }
|
||||
|
||||
public:
|
||||
bool Update(T &, const uint32 &);
|
||||
@@ -51,7 +52,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >,
|
||||
|
||||
void unitSpeedChanged() { i_recalculateTravel=true; }
|
||||
void UpdateFinalDistance(float fDistance);
|
||||
|
||||
bool IsReachable() const { return (i_path) ? (i_path->getPathType() & PATHFIND_NORMAL) : true; }
|
||||
protected:
|
||||
void _setTargetLocation(T &);
|
||||
|
||||
@@ -60,6 +61,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >,
|
||||
float i_angle;
|
||||
bool i_recalculateTravel : 1;
|
||||
bool i_targetReached : 1;
|
||||
PathFinderMovementGenerator* i_path;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -319,331 +319,3 @@ void FlightPathMovementGenerator::PreloadEndGrid()
|
||||
else
|
||||
sLog->outDetail("Unable to determine map to preload flightmaster grid");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Unique1's ASTAR Pathfinding Code... For future use & reference...
|
||||
//
|
||||
|
||||
#ifdef __PATHFINDING__
|
||||
|
||||
int GetFCost(int to, int num, int parentNum, float *gcost); // Below...
|
||||
|
||||
int ShortenASTARRoute(short int *pathlist, int number)
|
||||
{ // Wrote this to make the routes a little smarter (shorter)... No point looping back to the same places... Unique1
|
||||
short int temppathlist[MAX_PATHLIST_NODES];
|
||||
int count = 0;
|
||||
// int count2 = 0;
|
||||
int temp, temp2;
|
||||
int link;
|
||||
int upto = 0;
|
||||
|
||||
for (temp = number; temp >= 0; temp--)
|
||||
{
|
||||
qboolean shortened = qfalse;
|
||||
|
||||
for (temp2 = 0; temp2 < temp; temp2++)
|
||||
{
|
||||
for (link = 0; link < nodes[pathlist[temp]].enodenum; link++)
|
||||
{
|
||||
if (nodes[pathlist[temp]].links[link].flags & PATH_BLOCKED)
|
||||
continue;
|
||||
|
||||
//if ((bot->client->ps.eFlags & EF_TANK) && nodes[bot->current_node].links[link].flags & PATH_NOTANKS) //if this path is blocked, skip it
|
||||
// continue;
|
||||
|
||||
//if (nodes[nodes[pathlist[temp]].links[link].targetNode].origin[2] > nodes[pathlist[temp]].origin[2] + 32)
|
||||
// continue;
|
||||
|
||||
if (nodes[pathlist[temp]].links[link].targetNode == pathlist[temp2])
|
||||
{ // Found a shorter route...
|
||||
//if (OrgVisible(nodes[pathlist[temp2]].origin, nodes[pathlist[temp]].origin, -1))
|
||||
{
|
||||
temppathlist[count] = pathlist[temp2];
|
||||
temp = temp2;
|
||||
++count;
|
||||
shortened = qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!shortened)
|
||||
{
|
||||
temppathlist[count] = pathlist[temp];
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
upto = count;
|
||||
|
||||
for (temp = 0; temp < count; temp++)
|
||||
{
|
||||
pathlist[temp] = temppathlist[upto];
|
||||
--upto;
|
||||
}
|
||||
|
||||
G_Printf("ShortenASTARRoute: Path size reduced from %i to %i nodes...n", number, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
CreatePathAStar
|
||||
This function uses the A* pathfinding algorithm to determine the
|
||||
shortest path between any two nodes.
|
||||
It's fairly complex, so I'm not really going to explain it much.
|
||||
Look up A* and binary heaps for more info.
|
||||
pathlist stores the ideal path between the nodes, in reverse order,
|
||||
and the return value is the number of nodes in that path
|
||||
===========================================================================
|
||||
*/
|
||||
int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist)
|
||||
{
|
||||
//all the data we have to hold...since we can't do dynamic allocation, has to be MAX_NODES
|
||||
//we can probably lower this later - eg, the open list should never have more than at most a few dozen items on it
|
||||
short int openlist[MAX_NODES+1]; //add 1 because it's a binary heap, and they don't use 0 - 1 is the first used index
|
||||
float gcost[MAX_NODES];
|
||||
int fcost[MAX_NODES];
|
||||
char list[MAX_NODES]; //0 is neither, 1 is open, 2 is closed - char because it's the smallest data type
|
||||
short int parent[MAX_NODES];
|
||||
|
||||
short int numOpen = 0;
|
||||
short int atNode, temp, newnode=-1;
|
||||
qboolean found = qfalse;
|
||||
int count = -1;
|
||||
float gc;
|
||||
int i, u, v, m;
|
||||
vec3_t vec;
|
||||
|
||||
//clear out all the arrays
|
||||
memset(openlist, 0, sizeof(short int)*(MAX_NODES+1));
|
||||
memset(fcost, 0, sizeof(int)*MAX_NODES);
|
||||
memset(list, 0, sizeof(char)*MAX_NODES);
|
||||
memset(parent, 0, sizeof(short int)*MAX_NODES);
|
||||
memset(gcost, -1, sizeof(float)*MAX_NODES);
|
||||
|
||||
//make sure we have valid data before calculating everything
|
||||
if ((from == NODE_INVALID) || (to == NODE_INVALID) || (from >= MAX_NODES) || (to >= MAX_NODES) || (from == to))
|
||||
return -1;
|
||||
|
||||
openlist[1] = from; //add the starting node to the open list
|
||||
++numOpen;
|
||||
gcost[from] = 0; //its f and g costs are obviously 0
|
||||
fcost[from] = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (numOpen != 0) //if there are still items in the open list
|
||||
{
|
||||
//pop the top item off of the list
|
||||
atNode = openlist[1];
|
||||
list[atNode] = 2; //put the node on the closed list so we don't check it again
|
||||
--numOpen;
|
||||
|
||||
openlist[1] = openlist[numOpen+1]; //move the last item in the list to the top position
|
||||
v = 1;
|
||||
|
||||
//this while loop reorders the list so that the new lowest fcost is at the top again
|
||||
while (1)
|
||||
{
|
||||
u = v;
|
||||
if ((2*u+1) < numOpen) //if both children exist
|
||||
{
|
||||
if (fcost[openlist[u]] >= fcost[openlist[2*u]])
|
||||
v = 2*u;
|
||||
if (fcost[openlist[v]] >= fcost[openlist[2*u+1]])
|
||||
v = 2*u+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((2*u) < numOpen) //if only one child exists
|
||||
{
|
||||
if (fcost[openlist[u]] >= fcost[openlist[2*u]])
|
||||
v = 2*u;
|
||||
}
|
||||
}
|
||||
|
||||
if (u != v) //if they're out of order, swap this item with its parent
|
||||
{
|
||||
temp = openlist[u];
|
||||
openlist[u] = openlist[v];
|
||||
openlist[v] = temp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < nodes[atNode].enodenum; ++i) //loop through all the links for this node
|
||||
{
|
||||
newnode = nodes[atNode].links[i].targetNode;
|
||||
|
||||
//if this path is blocked, skip it
|
||||
if (nodes[atNode].links[i].flags & PATH_BLOCKED)
|
||||
continue;
|
||||
//if this path is blocked, skip it
|
||||
if (bot->client && (bot->client->ps.eFlags & EF_TANK) && nodes[atNode].links[i].flags & PATH_NOTANKS)
|
||||
continue;
|
||||
//skip any unreachable nodes
|
||||
if (bot->client && (nodes[newnode].type & NODE_ALLY_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_ALLIES))
|
||||
continue;
|
||||
if (bot->client && (nodes[newnode].type & NODE_AXIS_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_AXIS))
|
||||
continue;
|
||||
|
||||
if (list[newnode] == 2) //if this node is on the closed list, skip it
|
||||
continue;
|
||||
|
||||
if (list[newnode] != 1) //if this node is not already on the open list
|
||||
{
|
||||
openlist[++numOpen] = newnode; //add the new node to the open list
|
||||
list[newnode] = 1;
|
||||
parent[newnode] = atNode; //record the node's parent
|
||||
|
||||
if (newnode == to) //if we've found the goal, don't keep computing paths!
|
||||
break; //this will break the 'for' and go all the way to 'if (list[to] == 1)'
|
||||
|
||||
//store it's f cost value
|
||||
fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost);
|
||||
|
||||
//this loop re-orders the heap so that the lowest fcost is at the top
|
||||
m = numOpen;
|
||||
while (m != 1) //while this item isn't at the top of the heap already
|
||||
{
|
||||
//if it has a lower fcost than its parent
|
||||
if (fcost[openlist[m]] <= fcost[openlist[m/2]])
|
||||
{
|
||||
temp = openlist[m/2];
|
||||
openlist[m/2] = openlist[m];
|
||||
openlist[m] = temp; //swap them
|
||||
m /= 2;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //if this node is already on the open list
|
||||
{
|
||||
gc = gcost[atNode];
|
||||
VectorSubtract(nodes[newnode].origin, nodes[atNode].origin, vec);
|
||||
gc += VectorLength(vec); //calculate what the gcost would be if we reached this node along the current path
|
||||
|
||||
if (gc < gcost[newnode]) //if the new gcost is less (ie, this path is shorter than what we had before)
|
||||
{
|
||||
parent[newnode] = atNode; //set the new parent for this node
|
||||
gcost[newnode] = gc; //and the new g cost
|
||||
|
||||
for (i = 1; i < numOpen; ++i) //loop through all the items on the open list
|
||||
{
|
||||
if (openlist[i] == newnode) //find this node in the list
|
||||
{
|
||||
//calculate the new fcost and store it
|
||||
fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost);
|
||||
|
||||
//reorder the list again, with the lowest fcost item on top
|
||||
m = i;
|
||||
while (m != 1)
|
||||
{
|
||||
//if the item has a lower fcost than it's parent
|
||||
if (fcost[openlist[m]] < fcost[openlist[m/2]])
|
||||
{
|
||||
temp = openlist[m/2];
|
||||
openlist[m/2] = openlist[m];
|
||||
openlist[m] = temp; //swap them
|
||||
m /= 2;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
break; //exit the 'for' loop because we already changed this node
|
||||
} //if
|
||||
} //for
|
||||
} //if (gc < gcost[newnode])
|
||||
} //if (list[newnode] != 1) --> else
|
||||
} //for (loop through links)
|
||||
} //if (numOpen != 0)
|
||||
else
|
||||
{
|
||||
found = qfalse; //there is no path between these nodes
|
||||
break;
|
||||
}
|
||||
|
||||
if (list[to] == 1) //if the destination node is on the open list, we're done
|
||||
{
|
||||
found = qtrue;
|
||||
break;
|
||||
}
|
||||
} //while (1)
|
||||
|
||||
if (found == qtrue) //if we found a path
|
||||
{
|
||||
//G_Printf("%s - path found!n", bot->client->pers.netname);
|
||||
count = 0;
|
||||
|
||||
temp = to; //start at the end point
|
||||
while (temp != from) //travel along the path (backwards) until we reach the starting point
|
||||
{
|
||||
pathlist[count++] = temp; //add the node to the pathlist and increment the count
|
||||
temp = parent[temp]; //move to the parent of this node to continue the path
|
||||
}
|
||||
|
||||
pathlist[count++] = from; //add the beginning node to the end of the pathlist
|
||||
|
||||
#ifdef __BOT_SHORTEN_ROUTING__
|
||||
count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1
|
||||
#endif //__BOT_SHORTEN_ROUTING__
|
||||
}
|
||||
else
|
||||
{
|
||||
//G_Printf("^1*** ^4BOT DEBUG^5: (CreatePathAStar) There is no route between node ^7%i^5 and node ^7%i^5.n", from, to);
|
||||
count = CreateDumbRoute(from, to, pathlist);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
#ifdef __BOT_SHORTEN_ROUTING__
|
||||
count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1
|
||||
#endif //__BOT_SHORTEN_ROUTING__
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
return count; //return the number of nodes in the path, -1 if not found
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
GetFCost
|
||||
Utility function used by A* pathfinding to calculate the
|
||||
cost to move between nodes towards a goal. Using the A*
|
||||
algorithm F = G + H, G here is the distance along the node
|
||||
paths the bot must travel, and H is the straight-line distance
|
||||
to the goal node.
|
||||
Returned as an int because more precision is unnecessary and it
|
||||
will slightly speed up heap access
|
||||
===========================================================================
|
||||
*/
|
||||
int GetFCost(int to, int num, int parentNum, float *gcost)
|
||||
{
|
||||
float gc = 0;
|
||||
float hc = 0;
|
||||
vec3_t v;
|
||||
|
||||
if (gcost[num] == -1)
|
||||
{
|
||||
if (parentNum != -1)
|
||||
{
|
||||
gc = gcost[parentNum];
|
||||
VectorSubtract(nodes[num].origin, nodes[parentNum].origin, v);
|
||||
gc += VectorLength(v);
|
||||
}
|
||||
gcost[num] = gc;
|
||||
}
|
||||
else
|
||||
gc = gcost[num];
|
||||
|
||||
VectorSubtract(nodes[to].origin, nodes[num].origin, v);
|
||||
hc = VectorLength(v);
|
||||
|
||||
return (int)(gc + hc);
|
||||
}
|
||||
#endif //__PATHFINDING__
|
||||
|
||||
|
||||
Reference in New Issue
Block a user