#include "MW4Headers.hpp" #include #include "adept\application.hpp" #include "rail_move.hpp" //#include "quadedge.h" #include #include #include #include #include #include "path.hpp" #include "bridge.hpp" #include "cultural.hpp" #include "mwplayer.hpp" #include "move_rect.hpp" #pragma warning (push) #include #include #pragma warning (pop) using namespace MW4AI; using namespace MechWarrior4; using namespace ElementRenderer; #define BADSLOPE 0.707f #define CELLSIZE 10 void ConvertMoveRectToZeroCenter (const char *filename,Stuff::Scalar xoffset,Stuff::Scalar zoffset) { if (!filename) return; DWORD *file; DWORD filesize; DWORD *data; int numrects,i; struct TRect { Scalar left,right,top,bottom; int building; bool vertical; }; TRect *rects; gos_GetFile (filename,(unsigned char **) &file,&filesize); data = file; numrects = *((int*) data); data++; rects = (TRect *) data; Stuff::FileStream stream(filename,Stuff::FileStream::WriteOnly); stream << numrects; for (i=0;ibottom += zoffset; rects->top += zoffset; rects->left += xoffset; rects->right += xoffset; stream.WriteBytes (rects,sizeof (TRect)); rects++; } gos_Free (file); } CMoveRectList::CMoveRectList (void) { m_Rects.clear (); } CMoveRectList::CMoveRectList (Stuff::MemoryStream *stream) { int numrects,i; AutoHeap local_heap (g_RailHeap); m_Rects.clear (); *stream >> numrects; for (i=0;iReadBytes (&rect,sizeof (OBRect)); rect.vertical = true; m_Rects.push_back (rect); } } CMoveRectList::~CMoveRectList (void) { } void CMoveRectList::AddBuildingData (void) { // MSL 5.05 Added turretarray to list int tablescan[] = { NameTable::BuildingArray, NameTable::TurretArray, NameTable::VehicleArray }; int size,i,j; NameTable *table = NameTable::GetInstance(); Check_Object (table); AutoHeap local_heap (g_RailHeap); for (i=0;inameTableArray[tablescan[i]].GetLength (); for (j=0;jnameTableArray [tablescan[i]][j]; if (!strnicmp (data->objectName,"water",5)) { continue; } who = data->dataPointer->GetCurrent (); if (!who) continue; if ((!who->GetHierarchicalVolume ()) && (!who->GetSolidVolume ())) continue; if (!who->IsDerivedFrom (Bridge::DefaultData)) continue; if (!who->IsDerivedFrom (Cultural::DefaultData)) { MWObject *obj; obj = Cast_Object (MWObject *,who); if ((obj->GetAI ()) && (tablescan[i] != NameTable::BuildingArray)) continue; } else continue; OBB *obb; CollisionVolume *col; col = who->GetHierarchicalVolume (); if (!col) col = who->GetSolidVolume (); OBB world_bounds; world_bounds.Multiply(col->m_localSpaceBounds, who->GetLocalToWorld()); obb = &(world_bounds); ExtentBox box (*obb); Point3D loc = (Point3D) obb->localToParent; OBRect rect (box.minX,box.minZ,box.maxX,box.maxZ,data->GetObjectID (),((box.maxX - box.minX) < (box.maxZ-box.minZ))); m_Rects.push_back (rect); } } } void CMoveRectList::Create (WorkCallBack callback) { AddBuildingData (); // DumpFile (); } void CMoveRectList::SaveFile (const char *filename) { Stuff::FileStream stream(filename,Stuff::FileStream::WriteOnly); stream << m_Rects.size (); stlport::vector::iterator iter; iter = m_Rects.begin (); while (iter != m_Rects.end ()) { stream.WriteBytes (&(*iter),sizeof (OBRect)); iter++; } } void CMoveRectList::ConstructStream (Stuff::MemoryStream *stream,const char *filename) { DWORD *file; DWORD filesize; DWORD *data; int numrects; if (filename) { gos_GetFile (filename,(unsigned char **) &file,&filesize); data = file; numrects = *((int*) data); data++; *stream << (numrects); // width negative for new style filesize -= sizeof (int); if (filesize) stream->WriteBytes (data,filesize); gos_Free (file); } else { *stream << (DWORD) 0; // for number of rects } } void CMoveRectList::DumpFile (void) { FILE *file; file = fopen ("f:\\fred.out","w"); stlport::vector::iterator iter; iter = m_Rects.begin (); while (iter != m_Rects.end ()) { fprintf (file,"%d,%d %d,%d\n",iter->left,iter->top,iter->right,iter->bottom); iter++; } fclose (file); } const OBRect *CMoveRectList::Collide (const Point3D& start,const Point3D& end) const { stlport::vector::const_iterator iter; for (iter = m_Rects.begin ();iter != m_Rects.end ();iter++) { Scalar t,x,z; if (iter->vertical) { if (end.z == start.z) continue; t = (iter->top - start.z) / (end.z - start.z); if ((t>=0.0f) && (t<=1.0f)) { x = start.x + ((end.x - start.x)*t); if ((x >= iter->left) && (x <= iter->right)) return &(*iter); } t = (iter->bottom - start.z) / (end.z - start.z); if ((t>=0.0f) && (t<=1.0f)) { x = start.x + ((end.x - start.x)*t); if ((x >= iter->left) && (x <= iter->right)) return &(*iter); } } else { if (end.x == start.x) continue; t = (iter->left - start.x) / (end.x - start.x); if ((t>=0.0f) && (t<=1.0f)) { z = start.z + ((end.z - start.z)*t); if ((z >= iter->top) && (z <= iter->bottom)) return &(*iter); } t = (iter->right - start.x) / (end.x - start.x); if ((t>=0.0f) && (t<=1.0f)) { z = start.z + ((end.z - start.z)*t); if ((z >= iter->top) && (z <= iter->bottom)) return &(*iter); } } } return NULL; } bool CMoveRectList::RectWithin (Stuff::Point3D& pt,Stuff::Scalar dist) { stlport::vector::const_iterator iter; iter = m_Rects.begin (); Stuff::Scalar value; dist *= dist; Stuff::Scalar cx,cz; while (iter != m_Rects.end ()) { cx = ((iter->right - iter->left)/2.0f) + iter->left; cz = ((iter->bottom - iter->top)/2.0f) + iter->top; value = (pt.x - cx) * (pt.x - cx); value += ((pt.z - cz) * (pt.z - cz)); if (value < dist) return true; iter++; } return false; } const OBRect *CMoveRectList::Inside (const Point3D& pt) const { stlport::vector::const_iterator iter; iter = m_Rects.begin (); while (iter != m_Rects.end ()) { if ((pt.x >= iter->left) && (pt.x <= iter->right)) if ((pt.z >= iter->top) && (pt.z <= iter->bottom)) return &(*iter); iter++; } return NULL; } void CMoveRectList::BridgeKilled (int id) { }