// should only be included by rail_move.hpp //-------------------------------------------------------------------- namespace MW4AI { inline gridpoint::gridpoint (int p1,int p2) { Verify (p1>=(MinX/10.0f)); Verify (p2>=(MinZ/10.0f)); if (p1 < MinX/10.0f) p1 = (int) (MinX/10.0f); if (p2 < MinZ/10.0f) p2 = (int) (MinZ/10.0f); if (p1 >= (MaxX/10.0f)) p1 = (int) (MaxX/10.0f)-1; if (p2 >= (MaxZ/10.0f)) p2 = (int) (MaxZ/10.0f)-1; x = p1; y = p2; } inline gridpoint::gridpoint (float p1,float p2) { Verify (p1>=(MinX/10.0f)); Verify (p2>=(MinZ/10.0f)); if (p1 < MinX/10.0f) p1 = MinX/10.0f; if (p2 < MinZ/10.0f) p2 = MinZ/10.0f; if (p1 >= (MaxX/10.0f)) p1 = (MaxX/10.0f)-1; if (p2 >= (MaxZ/10.0f)) p2 = (MaxZ/10.0f)-1; x = (int) p1; y = (int) p2; } inline CRailLink::CRailLink (void) { m_Loc[0] = m_Loc[1] = NULL; memset (m_Weight,0,sizeof (m_Weight)); memset (m_CalcedWeight,0,sizeof (m_CalcedWeight)); m_UsageFlags[0] = LEGFLAG; m_UsageFlags[1] = LEGFLAG; m_Bridge = -1; } inline CRailLink::CRailLink (CRailNode *loc1,CRailNode *loc2,float weight[NUM_MOVE_TYPES][2],bool jump[2],bool track[2],bool fly[2],bool wheel[2],bool leg[2],bool hover[2],bool heli[2]) { m_UsageFlags[0] = 0; m_UsageFlags[1] = 0; m_Loc[0] = loc1; m_Loc[1] = loc2; memcpy (m_Weight,weight,sizeof (m_Weight)); memcpy (m_CalcedWeight,weight,sizeof (m_CalcedWeight)); m_UsageFlags[0] |= jump[0] ? JUMPFLAG : 0; m_UsageFlags[0] |= track[0] ? TRACKFLAG : 0; m_UsageFlags[0] |= fly[0] ? FLYFLAG : 0; m_UsageFlags[0] |= wheel[0] ? WHEELFLAG : 0; m_UsageFlags[0] |= leg[0] ? LEGFLAG : 0; m_UsageFlags[0] |= hover[0] ? HOVERFLAG : 0; m_UsageFlags[0] |= heli[0] ? HELIFLAG : 0; m_UsageFlags[1] |= jump[1] ? JUMPFLAG : 0; m_UsageFlags[1] |= track[1] ? TRACKFLAG : 0; m_UsageFlags[1] |= fly[1] ? FLYFLAG : 0; m_UsageFlags[1] |= wheel[1] ? WHEELFLAG : 0; m_UsageFlags[1] |= leg[1] ? LEGFLAG : 0; m_UsageFlags[1] |= hover[1] ? HOVERFLAG : 0; m_UsageFlags[1] |= heli[1] ? HELIFLAG : 0; m_Bridge = -1; } inline CRailLink::CRailLink (CRailNode *loc1,CRailNode *loc2,float weight[NUM_MOVE_TYPES][2],int moveflags[2]) { for (int k=0;k<2;k++) { if (moveflags[k] == 0xffffffff) { int i; m_UsageFlags[k] = 0; for (i=0;i=0); Verify (type 125.0f)) continue; if (usage & (1<=0); Verify (which=0) && (id<=1)); Verify (m_Loc[id]); return m_Loc[id]; } inline unsigned int CRailLink::LocID (unsigned int id) const { Verify ((id>=0) && (id<=1)); return m_LocID[id]; } inline CRailNode *CRailLink::OtherLocation (const CRailNode *temp) { Verify ((temp == m_Loc[0]) || (temp == m_Loc[1])); if (m_Loc[0] == temp) return m_Loc[1]; else return m_Loc[0]; } inline CRailNode *CRailLink::Location (int id) { Verify ((id>=0) && (id<=1)); return m_Loc[id]; } inline CRailNode::RailSubNode::RailSubNode (Stuff::Scalar p1,Stuff::Scalar p2,Stuff::Scalar p3) { location.x = p1; location.y = p2; location.z = p3; } inline CRailNode::RailSubNode& CRailNode::RailSubNode::operator= (const RailSubNode& p1) { location = p1.location; return *this; } inline void CRailNode::Location (const Stuff::Point3D& newloc) { m_Location = newloc; m_Dirty = true; } inline CRailLink *CRailNode::LinkTo (CRailNode *dest) { stlport::vector::iterator iter; for (iter = m_Links.begin ();iter != m_Links.end ();iter++) { if ((*iter)->OtherLocation (this) == dest) { return *iter; } } return NULL; } inline CRailLink *CRailNode::Link (unsigned int id) const { Verify (id>=0); Verify (id=0); Verify (id=0); Verify (index < m_Links.size ()); return m_Links[index]->ID (); } inline float CRailNode::EditorDistance (CRailNode *dest) const { Verify (dest); Verify (dest->ID () < m_EditorDistance.size ()); Verify (m_DistanceValid); return m_EditorDistance[dest->ID ()]; } inline float CRailNode::EditorDistance (unsigned int id) const { Verify (id < m_EditorDistance.size ()); Verify (m_DistanceValid); return m_EditorDistance[id]; } inline bool CRailNode::PathWeight (float newvalue,float estimate,int type) // true if changed { if (((m_PathWeight+m_PathEstimate) > (newvalue+estimate)) || (m_PathWeight == 0.0)) { m_PathWeight = newvalue; m_PathType = type; m_PathEstimate = estimate; return true; } return false; } inline void CRailNode::ClearPathWeight (float newvalue,float newestimate,int type) { m_PathWeight = newvalue; m_PathEstimate = newestimate; m_PathType = type; } inline void CMoveGrid::Destroy (void) { #if 0 int i,size; size = m_AllocHeight; for (i=0;iMacroPassableLocal (cx>>3,cy>>3) * 5; } inline void CMoveGrid::Passable (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass) // in meters { // x -= MinX; // z -= MinZ; x += 2560; z += 2560; Verify (x>=0); Verify (z>=0); Verify (x=m_Width) return ; if (z>=m_Height) return; if (x<0) return ; if (z<0) return; #endif int ix,iz; iz = (int) (z / BLOCK_GRID_RES); ix = (int) (x / BLOCK_GRID_RES); Verify (ix>=0); Verify (ix=0); Verify (iz=0); Verify (z>=0); Verify (x=m_Width) return ; if (z>=m_Height) return; if (x<0) return ; if (z<0) return; #endif int ix,iz; iz = (int) (z / BLOCK_GRID_RES); ix = (int) (x / BLOCK_GRID_RES); Verify (ix>=0); Verify (ix=0); Verify (iz=0); Verify ((int) (z)>=0); Verify ((int) (x)=m_Width) return -1; if ((int) (z)>=m_Height) return -1; if ((int) (x)<0) return -1; if ((int) (z)<0) return -1; #endif int ix,iz; iz = (int) ( (z / BLOCK_GRID_RES)); ix = (int) ( (x / BLOCK_GRID_RES)); Verify (ix>=0); Verify (ix=0); Verify (iz=0); Verify (x=0); Verify (z=m_AllocWidth) return -1; if ((int) (z)>=m_AllocHeight) return -1; if ((int) (x)<0) return -1; if ((int) (z)<0) return -1; #endif Verify (m_AllocWidth == 512); return(unsigned short) (m_Data[(z<<9)+x]); } inline void CMoveGrid::PassableLocal (int x,int z,unsigned short canpass) // in local { Verify ((m_AllocWidth!=0) && (m_AllocHeight != 0)); x += 256; z += 256; // x -= (int) (MinX/BLOCK_GRID_RES); // z -= (int) (MinZ/BLOCK_GRID_RES); Verify (x>=0); Verify (x=0); Verify (z=m_AllocWidth) return ; if (z>=m_AllocHeight) return; if (x<0) return ; if (z<0) return; #endif Verify (m_AllocWidth == 512); m_Data[(z<<9)+x] |= canpass; } inline void CMoveGrid::PassableLocalOverride (int x,int z,unsigned short canpass) // in local { Verify ((m_AllocWidth!=0) && (m_AllocHeight != 0)); x += 256; z += 256; // x -= (int) (MinX/BLOCK_GRID_RES); // z -= (int) (MinZ/BLOCK_GRID_RES); Verify (x>=0); Verify (x=0); Verify (z=m_AllocWidth) return ; if (z>=m_AllocHeight) return; if (x<0) return ; if (z<0) return; #endif Verify (m_AllocWidth == 512); m_Data[(z<<9)+x] = 0; m_Data[(z<<9)+x] |= canpass; } inline unsigned char CMoveGrid::MacroPassable (Stuff::Scalar x,Stuff::Scalar z) const { Verify ((m_Width!=0) && (m_Height != 0)); // x -= MinX; // z -= MinZ; x += 2560; z += 2560; Verify ((int) (x)>=0); Verify ((int) (z)>=0); Verify ((int) (x)=m_Width) return 255; if ((int) (z)>=m_Height) return 255; if ((int) (x)<0) return 255; if ((int) (z)<0) return 255; #endif int ix,iz; iz = (int) ( (z / MACROBLOCK_GRID_RES)); ix = (int) ( (x / MACROBLOCK_GRID_RES)); Verify (ix>=0); Verify (ix=0); Verify (iz=0); Verify ((int) (z)>=0); Verify ((int) (x)=m_MacroAllocWidth) return 255; if ((int) (z)>=m_MacroAllocHeight) return 255; if ((int) (x)<0) return 255; if ((int) (z)<0) return 255; #endif return(unsigned char) (m_MacroData[z][x]); } inline void CAirMoveGrid::Passable (Stuff::Scalar x,Stuff::Scalar z,unsigned char canpass,bool override) // in meters { x -= (MinX); z -= (MinZ); Verify (x>=0); Verify (z>=0); Verify (x=m_Width) return ; if (z>=m_Height) return; if (x<0) return ; if (z<0) return; #endif int ix,iz; iz = (int) (z / AIR_BLOCK_GRID_RES); ix = (int) (x / AIR_BLOCK_GRID_RES); Verify (ix>=0); Verify (ix=0); Verify (iz=0); Verify ((int) (z)>=0); Verify ((int) (x)=m_Width) return -1; if ((int) (z)>=m_Height) return -1; if ((int) (x)<0) return -1; if ((int) (z)<0) return -1; #endif int ix,iz; iz = (int) ( (z / AIR_BLOCK_GRID_RES)); ix = (int) ( (x / AIR_BLOCK_GRID_RES)); Verify (ix>=0); Verify (ix=0); Verify (iz=0); Verify (x=0); Verify (z=m_AllocWidth) return -1; if ((int) (z)>=m_AllocHeight) return -1; if ((int) (x)<0) return -1; if ((int) (z)<0) return -1; #endif return(unsigned char) (m_Data[z][x]); } inline void CAirMoveGrid::PassableLocal (int x,int z,unsigned char canpass,bool override) // in local { Verify ((m_AllocWidth!=0) && (m_AllocHeight != 0)); x -= (int) (MinX/AIR_BLOCK_GRID_RES); z -= (int) (MinZ/AIR_BLOCK_GRID_RES); Verify (x>=0); Verify (x=0); Verify (z=m_AllocWidth) return ; if (z>=m_AllocHeight) return; if (x<0) return ; if (z<0) return; #endif if (override) m_Data[z][x] = 0; m_Data[z][x] |= canpass; } inline void CAirMoveGrid::Destroy (void) { int i,size; size = m_AllocHeight; for (i=0;iPassable (x,z); } inline unsigned short CRailGraph::PassableLocal (int x,int z) const { Verify (m_MoveGrid); return m_MoveGrid->PassableLocal (x,z); } inline void CRailGraph::Passable (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass) { Verify (m_MoveGrid); m_MoveGrid->Passable (x,z,canpass); } inline void CRailGraph::PassableLocal (int x,int z,unsigned short canpass) { Verify (m_MoveGrid); m_MoveGrid->PassableLocal (x,z,canpass); } inline void CRailGraph::PassableOverride (Stuff::Scalar x,Stuff::Scalar z,unsigned short canpass) { Verify (m_MoveGrid); m_MoveGrid->PassableOverride (x,z,canpass); } inline void CRailGraph::PassableLocalOverride (int x,int z,unsigned short canpass) { Verify (m_MoveGrid); m_MoveGrid->PassableLocalOverride (x,z,canpass); } inline unsigned char CRailGraph::MacroPassable (Stuff::Scalar x,Stuff::Scalar z) const { Verify (m_MoveGrid); return m_MoveGrid->MacroPassable (x,z); } inline unsigned char CRailGraph::MacroPassableLocal (int x,int z) const { Verify (m_MoveGrid); return m_MoveGrid->MacroPassableLocal (x,z); } inline unsigned char CRailGraph::AirPassable (Stuff::Scalar x,Stuff::Scalar z) const { Verify (m_AirMoveGrid); return m_AirMoveGrid->Passable (x,z); } inline unsigned char CRailGraph::AirPassableLocal (int x,int z) const { Verify (m_AirMoveGrid); return m_AirMoveGrid->PassableLocal (x,z); } inline void CRailGraph::AirPassable (Stuff::Scalar x,Stuff::Scalar z,unsigned char canpass,bool override) { Verify (m_AirMoveGrid); m_AirMoveGrid->Passable (x,z,canpass,override); } inline void CRailGraph::AirPassableLocal (int x,int z,unsigned char canpass,bool override) { Verify (m_AirMoveGrid); m_AirMoveGrid->PassableLocal (x,z,canpass,override); } inline int CRailGraph::AddLink (unsigned int n1,unsigned int n2,float weight[NUM_MOVE_TYPES][2],int moveflags[2]) { CRailLink *temp; Verify ((n1>=0) && (n1=0) && (n2LinkTo (dest); if (temp) return temp->ID (); gos_PushCurrentHeap (g_RailHeap); temp = new CRailLink (m_Nodes[n1],m_Nodes[n2],weight,moveflags); gos_PopCurrentHeap (); Register_Pointer (temp); m_Dirty = true; return AddLink (temp); } inline int CRailGraph::AddLink (CRailNode *n1,CRailNode *n2,float weight[NUM_MOVE_TYPES][2],int moveflags[2]) { CRailLink *temp; int fred; Check_Pointer (n1); Check_Pointer (n2); temp = n1->LinkTo (n2); if (temp) return temp->ID (); fred = Connect (n1,n2); if (fred != -1) return fred; gos_PushCurrentHeap (g_RailHeap); temp = new CRailLink (n1,n2,weight,moveflags); gos_PopCurrentHeap (); Register_Pointer (temp); m_Dirty = true; return AddLink (temp); } inline int CRailGraph::CountNodes(void) const { int count; stlport::vector::const_iterator iter; count = 0; iter = m_Nodes.begin (); while (iter != m_Nodes.end ()) { if (*iter) count++; iter++; } return count; } inline int CRailGraph::CountLinks(void) const { int count; stlport::vector::const_iterator iter; count = 0; iter = m_Links.begin (); while (iter != m_Links.end ()) { if (*iter) count++; iter++; } return count; } inline CRailLink *CRailGraph::Link (unsigned int id) { Verify (id>=0); Verify (id=0); Verify (id=0); Verify (idLocation (0) == temp) { DeleteLink (i); continue; } if (m_Links[i]->Location (1) == temp) { DeleteLink (i); continue; } } RemoveBlock (id); delete m_Nodes[id]; m_Nodes[id] = NULL; } } inline CRailPath::PathElement::PathElement (void) { loc = Stuff::Point3D (-1,-1,-1); usage = 0; onrail = false; } inline CRailPath::PathElement::PathElement (const Stuff::Point3D& p1,int p2,bool p3,int p4) { loc = p1; usage = p2; onrail = p3; linkid = p4; } inline bool CRailPath::PathElement::operator== (const PathElement& p1) { if (p1.loc != loc) return false; return true; } inline bool CRailPath::JumpSoon (void) const { if (!m_Calced) return false; int i; stlport::vector::iterator iter; iter = m_InPath; for (i=0;i<2;i++,iter++) { if (iter == m_Path.end ()) return false; if (iter->usage & JUMPFLAG) return true; } return false; } inline int CRailPath::CurLink (void) const { if (!m_Calced) return -1; if (m_InPath == m_Path.end ()) return -1; return m_InPath->linkid; } inline Stuff::Point3D CRailPath::NextPoint (void) const // next link in path { stlport::vector::iterator iter; Stuff::Point3D pt(-1,-1,-1); if (!m_Calced) return Stuff::Point3D (-1,-1,-1); if (m_SubPath) pt = m_SubPath->NextPoint (); if (pt != Stuff::Point3D (-1,-1,-1)) return pt; if ((m_InPath==m_Path.end () || (m_Path.size ()<=1))) return Stuff::Point3D (-1,-1,-1); iter = m_InPath; iter++; if (iter != m_Path.end ()) return iter->loc; return Stuff::Point3D (-1,-1,-1); } inline Stuff::Point3D CGridPath::NextPoint (void) const // next link in path { stlport::vector::iterator iter; if (!m_Calced) return Stuff::Point3D (-1,-1,-1); if (m_QuickValid) return Stuff::Point3D (-1,-1,-1); if ((m_InDirPath==m_DirList.end () || (m_DirList.size ()<=1))) return Stuff::Point3D (-1,-1,-1); iter = m_InDirPath; iter++; if (iter != m_DirList.end ()) { Stuff::Scalar x; Stuff::Scalar z; x = (Stuff::Scalar) iter->locX*BLOCK_GRID_RES; z = (Stuff::Scalar) iter->locY*BLOCK_GRID_RES; x += BLOCK_GRID_RES/2.0f; z += BLOCK_GRID_RES/2.0f; return Stuff::Point3D (x,0,z); } return Stuff::Point3D (-1,-1,-1); } inline unsigned int CGridPath::Cost (int sx,int sy) { if (sx-m_BlockOriginX < 0) return 0; if (sy-m_BlockOriginY < 0) return 0; if (sx-m_BlockOriginX >= BLOCK_GRID_SIZE) return 0 ; if (sy-m_BlockOriginY >= BLOCK_GRID_SIZE) return 0; return m_BlockGrid[sx-m_BlockOriginX][sy-m_BlockOriginY][0]; } inline unsigned int CGridPath::Estimate (int sx,int sy) { if (sx-m_BlockOriginX < 0) return 0; if (sy-m_BlockOriginY < 0) return 0; if (sx-m_BlockOriginX >= BLOCK_GRID_SIZE) return 0; if (sy-m_BlockOriginY >= BLOCK_GRID_SIZE) return 0; return m_BlockGrid[sx-m_BlockOriginX][sy-m_BlockOriginY][1]; } inline bool CGridPath::Cost (int sx,int sy,unsigned int cost,unsigned int estimate) { if (sx-m_BlockOriginX < 0) return false; if (sy-m_BlockOriginY < 0) return false; if (sx-m_BlockOriginX >= BLOCK_GRID_SIZE) return false; if (sy-m_BlockOriginY >= BLOCK_GRID_SIZE) return false; if ((Cost (sx,sy) != 0) && ((Cost(sx,sy)+Estimate (sx,sy)) < (cost+estimate))) return false; m_BlockGrid[sx-m_BlockOriginX][sy-m_BlockOriginY][0] = cost; m_BlockGrid[sx-m_BlockOriginX][sy-m_BlockOriginY][1] = estimate; return true; } inline int CGridPath::CostGuess (int sx,int sy) { int t1,t2; t1 = (int) (m_EndX/BLOCK_GRID_RES) - sx; t2 = (int) (m_EndY/BLOCK_GRID_RES) - sy; t1 = t1<0 ? t1*-1 : t1; t2 = t2<0 ? t2*-1 : t2; return(10*(t2 < t1 ? (t1+(t2/2)) : (t2+(t1/2)))); } inline bool CGridPath::Next (void) // true if path still exists { if (m_InDirPath != m_DirList.end ()) { m_InDirPath++; return(m_InDirPath != m_DirList.end ()); } return false; } inline bool CGridPath::OneFromEnd (void) const // at end is also good { stlport::vector::iterator iter; iter = m_InDirPath; if (iter != m_DirList.end ()) { iter++; return iter == m_DirList.end (); } return iter == m_DirList.end (); } inline Stuff::Point3D CGridPath::CurrentPoint (void) const { Verify (!m_QuickValid); Stuff::Scalar x; Stuff::Scalar z; x = (Stuff::Scalar) m_InDirPath->locX*BLOCK_GRID_RES; z = (Stuff::Scalar) m_InDirPath->locY*BLOCK_GRID_RES; if (x < 0) x -= BLOCK_GRID_RES/2.0f; else x += BLOCK_GRID_RES/2.0f; if (z < 0) z -= BLOCK_GRID_RES/2.0f; else z += BLOCK_GRID_RES/2.0f; return Stuff::Point3D (x,0,z); } /* inline CGridPath::GridPathElement CGridPath::Element (int index) { Verify (index >= 0); Verify (index < m_Path.size ()); return m_GridPath[index]; } */ inline CGridPath::DirElement CGridPath::direlement (int index) { Verify (index >= 0); Verify (index < m_DirList.size ()); return m_DirList[index]; } inline CRailPath *CPathRequest::DetachNodePath (void) { CRailPath *toret = m_NodePath; m_NodePath = NULL; return toret; } inline CGridPath *CPathRequest::DetachGridPath (void) { CGridPath *toret = m_GridPath; m_GridPath = NULL; return toret; } inline bool CheckCanPass (unsigned int flags, unsigned int mask) { // if (mask & PLANEPASS_FLAG) // return false; #pragma warning (disable : 4800) return((flags&~BRIDGE_FLAG) & mask); #pragma warning (default : 4800) } inline int ConvertTypetoUsage (int movetype) { switch (movetype) { case MechWarrior4::MWObject__GameModel::LEG_MOVETYPE: return LEGFLAG; case MechWarrior4::MWObject__GameModel::LEGJUMP_MOVETYPE: return LEGFLAG + JUMPFLAG; case MechWarrior4::MWObject__GameModel::TRACK_MOVETYPE: return TRACKFLAG; case MechWarrior4::MWObject__GameModel::WHEEL_MOVETYPE: return WHEELFLAG; case MechWarrior4::MWObject__GameModel::FLYER_MOVETYPE: return FLYFLAG; case MechWarrior4::MWObject__GameModel::HOVER_MOVETYPE: return HOVERFLAG; case MechWarrior4::MWObject__GameModel::HELI_MOVETYPE: return HELIFLAG; case MechWarrior4::MWObject__GameModel::WATER_MOVETYPE: return WATERFLAG; default: gosASSERT (false); return 0; } // return 0; } inline int ConvertUsagetoMovePass (int usage) { int toret; toret = 0; if (usage & BRIDGEFLAG) toret = BRIDGE_FLAG; if (usage & LEGFLAG) toret += LEGPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & JUMPFLAG) toret += JUMPPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & TRACKFLAG) toret += TRACKPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & WHEELFLAG) toret += WHEELPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & FLYFLAG) toret += JUMPPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & HOVERFLAG) toret += HOVERPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & HELIFLAG) toret += JUMPPASS_FLAG|MOVEPASSNOW_FLAG; else if (usage & WATERFLAG) toret += WATERPASS_FLAG|MOVEPASSNOW_FLAG; else gosREPORT (false,"unknown usage passed into ConvertUsageToMovePass"); return toret; } }