Files
firestorm/Gameleap/code/mw4/Code/MW4/railpath.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

986 lines
21 KiB
C++

#include "MW4Headers.hpp"
#include "server\comline.hpp"
#include "adept\application.hpp"
#include "rail_move.hpp"
#include "move_rect.hpp"
#include "ai.hpp"
#pragma warning (push)
#include <vector>
#include <map>
#pragma warning (pop)
namespace MechWarrior4
{
extern DWORD Path_Calcs_Count;
extern DWORD GridPath_Calcs_Count;
extern DWORD QuickPath_Calcs_Count;
extern DWORD QuickRail_Calcs_Count;
}
namespace MW4AI
{
extern __int64 tCalcPathTime;
extern __int64 tQuickCheckTime;
extern __int64 tCreatePathRequestsTime;
extern __int64 tPathCalc1Time;
extern __int64 tPathCalc2Time;
extern __int64 tNodeToPathTime;
};
using namespace MW4AI;
using namespace MechWarrior4;
CRailPath::CRailPath (CRailGraph *graph,MoverAI *ai)
: m_Start(-1,-1,-1)
, m_End(-1,-1,-1)
{
m_SubPathRequest = NULL;
m_NearLastFrame = false;
m_TenMeterAllowed = false;
m_AI = ai;
m_SubPath = NULL;
m_Graph = graph;
m_Strict = false;
m_StartNode = NULL;
m_EndNode = NULL;
m_Calced = false;
m_InNodePath = 0;
m_Path.clear ();
m_NodePath.clear ();
m_InPath = m_Path.begin ();;
}
CRailPath::CRailPath (CRailGraph *graph,const Stuff::Point3D& start,const Stuff::Point3D& end,bool strict,MoverAI *ai,bool tenmeter)
: m_Start(start)
, m_End(end)
{
m_NearLastFrame = false;
m_TenMeterAllowed = tenmeter;
m_AI = ai;
m_SubPathRequest = NULL;
m_SubPath = NULL;
m_Graph = graph;
m_Strict = strict;
m_Graph->FindBestNode (m_Start,m_End,false,m_StartNode,m_EndNode);
m_Calced = false;
m_InNodePath = 0;
m_Path.clear ();
m_NodePath.clear ();
m_InPath = m_Path.begin ();;
}
CRailPath::CRailPath (CRailGraph *graph,CRailNode *start,CRailNode *end,MoverAI *ai,bool tenmeter)
{
m_NearLastFrame = false;
m_TenMeterAllowed = tenmeter;
m_AI = ai;
m_SubPathRequest = NULL;
m_SubPath = NULL;
m_Graph = graph;
m_StartNode = start;
m_EndNode = end;
m_Strict = true;
m_Start = m_StartNode->Location ();
m_End = m_EndNode->Location ();
m_Calced = false;
m_InNodePath = 0;
m_Path.clear ();
m_NodePath.clear ();
m_InPath = m_Path.begin ();
// m_GridRequests.clear ();
}
CRailPath::~CRailPath (void)
{
m_NodePath.clear ();
m_Path.clear ();
delete m_SubPath;
m_SubPath = NULL;
delete m_SubPathRequest;
m_SubPathRequest = NULL;
}
void CRailPath::UpdateSrcDest (CRailNode *src,CRailNode *dest)
{
Verify (dest);
m_StartNode = src;
m_EndNode = dest;
m_End = m_EndNode->Location ();
m_Start = m_StartNode->Location ();
}
void CRailPath::UpdateSrcDest (const Stuff::Point3D& src,const Stuff::Point3D& dest)
{
m_Start = src;
m_End = dest;
m_Graph->FindBestNode (m_Start,m_End,false,m_StartNode,m_EndNode);
}
void CRailPath::Save (MemoryStream *stream)
{
stlport::vector<NodePathElement>::iterator iter1;
stlport::vector<PathElement>::iterator iter2;
*stream << m_TenMeterAllowed;
*stream << m_Start;
*stream << m_End;
*stream << m_HeadPoint;
*stream << m_UsageAllowed;
*stream << m_Calced;
*stream << m_Strict;
if (m_StartNode)
{
*stream << true;
*stream << m_StartNode->ID ();
}
else
*stream << false;
if (m_EndNode)
{
*stream << true;
*stream << m_EndNode->ID ();
}
else
*stream << false;
*stream << m_InNodePath;
*stream << ((int) m_State);
*stream << m_NodePath.size ();
*stream << m_Path.size ();
int count;
for (iter2 = m_Path.begin (),count = 0;(iter2 != m_Path.end ()) && (m_InPath != iter2);iter2++,count++);
*stream << count;
for (iter1 = m_NodePath.begin ();iter1 != m_NodePath.end ();iter1++)
{
iter1->Save (stream);
}
for (iter2 = m_Path.begin ();iter2 != m_Path.end ();iter2++)
{
iter2->Save (stream);
}
}
void CRailPath::Load (MemoryStream *stream)
{
bool flag;
int temp;
int size1,size2;
*stream >> m_TenMeterAllowed;
*stream >> m_Start;
*stream >> m_End;
*stream >> m_HeadPoint;
*stream >> m_UsageAllowed;
*stream >> m_Calced;
*stream >> m_Strict;
*stream >> flag;
m_StartNode = NULL;
if (flag)
{
int id;
*stream >> id;
m_StartNode = m_Graph->Node (id);
}
*stream >> flag;
m_EndNode = NULL;
if (flag)
{
int id;
*stream >> id;
m_EndNode = m_Graph->Node (id);
}
*stream >> m_InNodePath;
*stream >> temp;
m_State = (PATHSTATES) temp;
*stream >> size1;
*stream >> size2;
int count,i;
*stream >> count;
m_NodePath.assign (size1,NodePathElement ());
for (i=0;i<size1;i++)
{
m_NodePath[i].Load (stream);
}
m_Path.assign (size2,PathElement());
for (i=0;i<size2;i++)
{
m_Path[i].Load (stream);
}
m_InPath = m_Path.begin ();
m_InPath += count;
}
void CRailPath::PathElement::Save (MemoryStream *stream)
{
*stream << loc;
*stream << usage;
*stream << onrail;
*stream << linkid;
}
void CRailPath::PathElement::Load (MemoryStream *stream)
{
*stream >> loc;
*stream >> usage;
*stream >> onrail;
*stream >> linkid;
}
void CRailPath::NodePathElement::Save (MemoryStream *stream)
{
*stream << usage;
if (link)
{
*stream << true;
*stream << link->ID ();
}
else
*stream << false;
if (destnode)
{
*stream << true;
*stream << destnode->ID ();
}
else
*stream << false;
}
void CRailPath::NodePathElement::Load (MemoryStream *stream)
{
bool flag;
int id;
*stream >> usage;
destnode = NULL;
link = NULL;
*stream >> flag;
if (flag)
{
*stream >> id;
link = g_MissionGraph->Link (id);
}
*stream >> flag;
if (flag)
{
*stream >> id;
destnode = g_MissionGraph->Node (id);
}
}
float CRailPath::CostGuess (CRailNode *src)
{
Stuff::Point3D start;
Stuff::Point3D end;
start = src->Location ();
end = m_End;
float t1,t2;
t1 = end.x - start.x;
t2 = end.z - start.z;
t1 = t1<0 ? t1*-1.0f : t1;
t2 = t2<0 ? t2*-1.0f : t2;
return 0;
// return t2 < t1 ? (t1+(t2/2.0f)) : (t2+(t1/2.0f));
}
void CRailPath::CalcOutVec (Stuff::Point3D& outvec)
{
outvec = NextPoint ();
// outvec = Stuff::Point3D (-1,-1,-1);
}
bool CRailPath::NewSubPath (const Stuff::Point3D& loc)
{
if (m_InPath == m_Path.end ())
return false;
int mask=0;
if (m_InPath->usage & JUMPFLAG)
{
Verify (!m_SubPathRequest);
return true;
}
if (m_InPath->onrail)
{
Verify (!m_SubPathRequest);
return true;
}
delete m_SubPath;
m_SubPath = NULL;
if (m_SubPathRequest)
{
m_SubPath = m_SubPathRequest->GridPath ();
if (!m_SubPathRequest->Done ())
{
return true;
}
m_SubPathRequest->DetachGridPath ();
delete m_SubPathRequest;
m_SubPathRequest = NULL;
if (!m_SubPath->Calced ())
{
if (m_InPath->linkid != -1)
m_Graph->DeleteLink (m_InPath->linkid);
delete m_SubPath;
m_SubPath = NULL;
m_Calced = false;
return false;
}
if (m_SubPath->QuickValid ())
{
delete m_SubPath;
m_SubPath = NULL;
}
}
else
{
mask = ConvertUsagetoMovePass (m_InPath->usage);
m_SubPathRequest = g_PathManager->AddRequest (gos_GetElapsedTime (),m_Graph,(unsigned short) mask,loc.x,loc.z,m_InPath->loc.x,m_InPath->loc.z,m_AI,m_TenMeterAllowed);
return true;
#if 0
gos_PushCurrentHeap (g_RailHeap);
m_SubPath = new CGridPath (m_Graph,(unsigned short) mask,loc.x,loc.z,m_InPath->loc.x,m_InPath->loc.z,m_TenMeterAllowed);
gos_PopCurrentHeap ();
Verify (m_SubPath);
m_SubPath->CalcPath();
#endif
}
#if 0
if (!m_SubPath->Calced ())
{
if (m_InPath->linkid != -1)
m_Graph->DeleteLink (m_InPath->linkid);
delete m_SubPath;
m_SubPath = NULL;
m_Calced = false;
return false;
}
if (m_SubPath->QuickValid ())
{
delete m_SubPath;
m_SubPath = NULL;
}
#endif
return true;
}
bool CRailPath::Next (const Stuff::Point3D& loc)
{
if (m_SubPath)
{
if (m_SubPath->Next ())
{
return true;
}
delete m_SubPath;
m_SubPath = NULL;
if (m_InPath != m_Path.end ())
{
m_InPath++;
return NewSubPath (loc);
}
}
if (m_InPath != m_Path.end ())
{
m_InPath++;
return NewSubPath (loc);
}
return false;
}
Stuff::Point3D CRailPath::CurrentPoint (void) const
{
if (!m_Calced)
return Stuff::Point3D (-1,-1,-1);
if (m_State == RAIL_FINISH)
return Stuff::Point3D (-1,-1,-1);
if (m_InPath == m_Path.end () && (m_SubPath == NULL))
return Stuff::Point3D (-1,-1,-1);
if (m_SubPath)
return m_SubPath->CurrentPoint ();
else
return m_InPath->loc;
}
bool CRailPath::PointBehind (const Stuff::Point3D& loc,const Stuff::Point3D& dest)
{
Stuff::Point3D nextdest,destextra,nextdestextra;
Scalar dist1,dist2,dot;
nextdest = NextPoint ();
if (nextdest == Point3D (-1,-1,-1))
return false;
int x,y,mask;
x = (int) (loc.x/10);
y = (int) (loc.z/10);
mask = ConvertUsagetoMovePass (m_UsageAllowed&(~JUMPFLAG));
if ((!m_Graph->MoveTo (x+1,y,0,mask)) || (!m_Graph->MoveTo (x-1,y,0,mask)) || (!m_Graph->MoveTo (x,y-1,0,mask)) || (!m_Graph->MoveTo (x,y+1,0,mask)))
{
return false;
}
destextra.Subtract (dest,loc);
dist1 = destextra.GetLengthSquared ();
nextdestextra.Subtract (nextdest,loc);
dist2 = nextdestextra.GetLengthSquared ();
if (dist2 < dist1)
return true;
dot = (nextdestextra.x*destextra.x) + (nextdestextra.z*destextra.z);
dot /= (nextdestextra.GetLength () * destextra.GetLength ());
if ((m_Graph->Passable (loc.x,loc.z) & BRIDGE_FLAG) && (dot <= 0.0f))
return true;
if ((dot <= 0.0f) && (dist1 < 400))
return true;
return false;
}
void CRailPath::PointList (stlport::vector<Point3D>& dest)
{
dest.clear ();
if (!m_Calced)
return;
if (m_InPath == m_Path.end () && (m_SubPath == NULL))
return;
gos_PushCurrentHeap (g_RailHeap);
if (m_SubPath)
{
m_SubPath->PointList (dest);
}
stlport::vector<PathElement>::iterator iter;
for (iter = m_InPath;iter != m_Path.end ();iter++)
{
dest.push_back (iter->loc);
}
gos_PopCurrentHeap ();
}
void CRailPath::Tick (const Stuff::Point3D& loc,Stuff::Time till,Stuff::Scalar speed,Stuff::Point3D& outvec,bool& jump,bool& prejump)
{
m_HeadPoint = Stuff::Point3D (-1,-1,-1);
Verify (m_Calced);
jump = false;
prejump = false;
if (m_State == RAIL_FINISH)
return;
if (m_SubPathRequest)
{
if (m_SubPathRequest->Done ())
{
m_SubPath = m_SubPathRequest->DetachGridPath ();
delete m_SubPathRequest;
m_SubPathRequest = NULL;
if (!m_SubPath->Calced ())
{
if (m_InPath->linkid != -1)
m_Graph->DeleteLink (m_InPath->linkid);
delete m_SubPath;
m_SubPath = NULL;
m_Calced = false;
m_State = RAIL_FINISH;
return;
}
if (m_SubPath->QuickValid ())
{
delete m_SubPath;
m_SubPath = NULL;
}
}
else
{
m_State = RAIL_MOVE_WAITING;
return;
}
}
m_State = RAIL_MOVE_ENDPOINT;
CalcOutVec (outvec);
Stuff::Point3D destloc,extra,fakeloc;
Stuff::Scalar dist,move;
destloc = CurrentPoint ();
destloc.y = 0;
fakeloc = loc;
fakeloc.y = 0;
extra.Subtract (destloc,fakeloc);
dist = extra.GetLengthSquared ();
if (speed < 0)
move = (float) (speed * till * 6); // use 6 frame buffer
else
move = (float) (speed * till * 6); // use 6 frame buffer
move *= move;
// if ((dist<49.0) || (dist < move) || PointBehind (loc,destloc))
if (m_NearLastFrame)
{
m_NearLastFrame = false;
if (!Next (loc))
{
m_State = RAIL_FINISH;
return;
}
if (!m_Calced)
return;
Tick (loc,till,speed,outvec,jump,prejump);
return;
}
#if 1
if ((dist<16.0) || (dist < move) || PointBehind (loc,destloc))
{
m_NearLastFrame = true;
}
#endif
m_HeadPoint = CurrentPoint ();
destloc = CurrentPoint ();
destloc.y = 0;
fakeloc = loc;
fakeloc.y = 0;
extra.Subtract (destloc,fakeloc);
dist = extra.GetLengthSquared ();
CalcOutVec (outvec);
stlport::vector<PathElement>::iterator iter;
iter = m_InPath;
if (m_InPath != m_Path.end ())
iter++;
if (m_InPath->usage & JUMPFLAG)
jump = true;
else
jump = false;
if ((iter != m_Path.end ()) && (iter->usage & JUMPFLAG))
prejump = true;
bool flag = false;
if ((!m_SubPath) && (iter == m_Path.end () && (m_State != RAIL_FINISH)))
flag = true;
if ((m_SubPath) && (iter == m_Path.end () && (m_State != RAIL_FINISH)))
{
if (m_SubPath->OneFromEnd ())
flag = true;
}
}
bool CRailGraph::PointOpen (Scalar x,Scalar y,int movepass)
{
const int SIZEDELTA = 8;
int delta[SIZEDELTA][2] = {
{-1*BLOCK_GRID_RES,0*BLOCK_GRID_RES},
{0*BLOCK_GRID_RES,-1*BLOCK_GRID_RES},
{1*BLOCK_GRID_RES,0*BLOCK_GRID_RES},
{0*BLOCK_GRID_RES,1*BLOCK_GRID_RES},
#if 1
{-1*BLOCK_GRID_RES,-1*BLOCK_GRID_RES},
{-1*BLOCK_GRID_RES,1*BLOCK_GRID_RES},
{1*BLOCK_GRID_RES,-1*BLOCK_GRID_RES},
{1*BLOCK_GRID_RES,1*BLOCK_GRID_RES}
#endif
};
int i;
if (CheckCanPass (Passable (x,y),movepass))
return false;
for (i=0;i<SIZEDELTA;i++)
{
if (CheckCanPass (Passable (x+delta[i][0],y+delta[i][1]),movepass))
return false;
}
return true;
}
Stuff::Point3D CRailGraph::PullPointElementMask (Stuff::Point3D& start,Stuff::Point3D& end,int movepass)
{
end.y = 0;
start.y = 0;
if (!PointOpen (end.x,end.z , movepass))
{
Stuff::Point3D vec,tempvec,third;
Stuff::Scalar len,curlen;
third.Subtract (start,end);
len = third.GetLengthSquared ();
if (len < 5.0f)
return Point3D (-1,-1,-1);
vec.Normalize (third);
curlen = 0;
while ((curlen*curlen) < len)
{
curlen+=BLOCK_GRID_RES;
third.Multiply (vec,curlen);
tempvec.Add (third,end);
if (PointOpen (tempvec.x,tempvec.z , movepass))
return tempvec;
}
return Stuff::Point3D (-1,-1,-1);
}
else
return end;
}
Stuff::Point3D CRailGraph::PullPointElement (Stuff::Point3D& start,Stuff::Point3D& end,int usage)
{
int movepass;
movepass = ConvertUsagetoMovePass (usage);
return PullPointElementMask (start,end,movepass);
}
void CRailPath::DumpPath (void)
{
stlport::vector<PathElement>::iterator iter;
char text[100];
iter = m_Path.begin ();
while (iter != m_Path.end ())
{
sprintf (text,"Move Point %f,%f",iter->loc.x,iter->loc.z);
COMSPEW (text);
iter++;
}
COMSPEW ("");
}
void CRailPath::ReverseList (void)
{
stlport::vector<NodePathElement>::iterator start,end;
// COMSPEW ("reversing path list");
start = m_NodePath.begin ();
end = m_NodePath.end ();
stlport::reverse (start,end);
}
void CRailPath::Reverify (int usage)
{
return;
#if 0
if (!m_QuickPath)
return;
unsigned short usa = (unsigned short) (m_UsageAllowed&(~JUMPFLAG));
if (m_Graph->QuickCheck ((int) m_Start.x,(int) m_Start.z,(int) m_End.x,(int) m_End.z,(unsigned short) ConvertUsagetoMovePass (usa)))
return;
m_Calced = false;
m_NodePath.clear ();
m_Path.clear ();
CalcPath (usage);
#endif
}
void CRailPath::CalcPath (int usage)
{
PATH_LOGIC("Calc");
TIME_FUNCTION(tCalcPathTime);
Verify (m_Graph);
int i;
int type;
my_heap<CRailNode *,true,railnodecmp> calc;
CRailNode *temp;
bool done;
Scalar dist;
Point3D extra;
m_NearLastFrame = false;
m_SubPathRequest = NULL;
Set_Statistic(Path_Calcs_Count, Path_Calcs_Count+1);
// usage &= ~JUMPFLAG;
Verify (m_Graph->CountNodes ());
Verify (m_Graph->CountLinks ());
Verify (usage >0);
m_UsageAllowed = usage & (~JUMPFLAG);
AutoHeap local_heap (g_RailHeap);
unsigned short usa = (unsigned short) (m_UsageAllowed&(~JUMPFLAG));
extra = m_Graph->PullPointElement (m_Start,m_End,usa);
if (extra == Point3D (-1,-1,-1))
{
m_Calced = false;
return;
}
m_End = extra;
m_QuickPath = false;
if (m_Graph->QuickCheck ((int) m_Start.x,(int) m_Start.z,(int) m_End.x,(int) m_End.z,(unsigned short) ConvertUsagetoMovePass (usa)))
{
Set_Statistic(QuickRail_Calcs_Count, QuickRail_Calcs_Count+1);
m_Calced = true;
m_Path.push_back (PathElement (m_Start,usa,false,-1));
m_Path.push_back (PathElement (m_End,usa,true,-1));
m_InPath = m_Path.begin ();
m_QuickPath = true;
return;
}
if ((m_StartNode == NULL) || (m_EndNode == NULL))
{
m_Calced = false;
m_State = RAIL_START_PATH;
return;
}
m_Start.y = m_End.y = 0;
extra.Subtract (m_Start,m_End);
dist = extra.GetLengthSquared ();
if ((m_StartNode == m_EndNode) || ((dist < (250.0f*250.0f)) && (!m_Graph->BridgeNear (m_Start,m_End))))
{
m_Calced = true;
m_Path.push_back (PathElement (m_Start,usa,false,-1));
Point3D temp;
temp = m_Graph->PullPointElement (m_Start,m_End,usa);
if (temp != Point3D (-1,-1,-1))
{
m_Path.push_back (PathElement (temp,usa,false,-1));
m_InPath = m_Path.begin ();
m_InPath++;
gos_PushCurrentHeap (g_RailHeap);
unsigned short mask = (unsigned short) ConvertUsagetoMovePass (m_InPath->usage);
m_SubPath = new CGridPath (m_Graph,mask,m_Start.x,m_Start.z,m_End.x,m_End.z,m_TenMeterAllowed);
gos_PopCurrentHeap ();
Verify (m_SubPath);
m_SubPath->DoCalcPath();
if (m_SubPath->Calced ())
{
if (m_SubPath->QuickValid ())
{
delete m_SubPath;
m_SubPath = NULL;
m_Calced = true;
m_Path.clear ();
m_Path.push_back (PathElement (m_Start,usa,false,-1));
m_Path.push_back (PathElement (m_End,usa,false,-1));
m_InPath = m_Path.begin ();
m_QuickPath = true;
return;
}
return;
}
else if (m_StartNode == m_EndNode)
{
delete m_SubPath;
m_SubPath = NULL;
CreatePathRequests ();
return;
}
else
{
m_Calced = false;
delete m_SubPath;
m_SubPath = NULL;
}
#if 0
if ((m_Calced) || (m_StartNode == m_EndNode))
{
Set_Statistic(QuickRail_Calcs_Count, QuickRail_Calcs_Count+1);
m_QuickPath = true;
return;
}
#endif
}
else
m_Calced = false;
if (m_StartNode == m_EndNode)
{
m_QuickPath = true;
m_State = RAIL_FINISH;
m_Calced = true;
m_Path.push_back (PathElement (m_End,usa,false,-1));
m_InPath = m_Path.end ();
return;
}
}
m_Graph->ClearPathFlags ();
m_StartNode->PathWeight (1,CostGuess (m_EndNode),usa);
calc.Insert (m_StartNode);
done = false;
m_Calced = false;
int count = 0;
{
PATH_LOGIC("RailPath phase 1");
TIME_FUNCTION(tPathCalc1Time);
{
while (!done)
{
count++;
if (count > (m_Graph->NumNodes ()*2))
{
break;
}
if (!calc.size ())
break;
temp = calc.ExtractMin ();
if (temp == NULL)
break;
if (temp == m_EndNode)
{
done = true;
break;
}
int size;
float cost;
cost = temp->PathWeight ();
size = temp->NumLinks ();
for (i=0;i<size;i++)
{
CRailNode *dest;
CRailLink *curlink;
float newcost;
curlink = temp->Link (i);
dest = curlink->OtherLocation (temp);
newcost = curlink->LowestWeight (usage,type,temp);
if (newcost == -1)
continue;
if (type == 0)
continue;
newcost += cost;
if (dest->PathWeight (newcost,CostGuess (dest),type))
{
if (calc.Member (dest))
calc.DecreaseKey (dest);
else
calc.Insert (dest);
}
}
}
}
if (!done)
return;
done = false;
CRailNode *cur;
int min;
float mincost;
cur = m_EndNode;
min = NULL;
count =0;
{
PATH_LOGIC("RailPath phase 2");
TIME_FUNCTION(tPathCalc2Time);
{
while (!done)
{
count++;
if (count > (m_Graph->NumNodes ()*2))
{
m_Calced = false;
return;
}
min = 0;
mincost = cur->Link (min)->OtherLocation (cur)->PathWeight ();
if (cur->Link (min)->LowestWeight (usage,type,cur->Link (min)->OtherLocation (cur)) == -1.0f)
mincost = 0;
for (i=1;i<cur->NumLinks ();i++)
{
float t;
t= cur->Link (i)->OtherLocation (cur)->PathWeight ();
if (cur->Link (i)->LowestWeight (usage,type,cur->Link (i)->OtherLocation (cur)) == -1.0f)
t = 0;
if (((t < mincost) && (t != 0)) || (mincost == 0))
{
mincost = t;
min = i;
}
}
m_NodePath.push_back (NodePathElement (cur->Link (min),cur,cur->PathType ()));
cur = cur->Link (min)->OtherLocation (cur);
if (cur == m_StartNode)
{
int fred = 0;
if (usage & LEGFLAG)
fred = LEGFLAG;
else if (usage & JUMPFLAG)
fred = JUMPFLAG;
else if (usage & TRACKFLAG)
fred = TRACKFLAG;
else if (usage & WHEELFLAG)
fred = WHEELFLAG;
else if (usage & FLYFLAG)
fred = FLYFLAG;
else if (usage & HOVERFLAG)
fred = HOVERFLAG;
else if (usage & HELIFLAG)
fred = HELIFLAG;
else if (usage & WATERFLAG)
fred = WATERFLAG;
#if defined(LAB_ONLY)
else
PAUSE (("unknown movetype in calcpath"));
#endif
m_NodePath.push_back (NodePathElement (NULL,cur,fred));
ReverseList ();
done = true;
continue;
}
}
}
}
m_Calced = true;
m_State = RAIL_START_PATH;
m_HeadPoint = Stuff::Point3D (-1,-1,-1);
m_InNodePath = 0;
ConvertNodeToPath ();
if (m_Calced)
CreatePathRequests ();
}
}
void CRailPath::CreatePathRequests (void)
{
TIME_FUNCTION(tCreatePathRequestsTime);
if (m_Calced)
NewSubPath (m_Start);
}