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.
207 lines
5.2 KiB
C++
207 lines
5.2 KiB
C++
#include "MW4Headers.hpp"
|
|
|
|
#include "Path.hpp"
|
|
|
|
#include <Adept\EntityClassData.hpp>
|
|
#include <Adept\zone.hpp>
|
|
#include <Adept\map.hpp>
|
|
#include <elementrenderer\GridElement.hpp>
|
|
|
|
//#############################################################################
|
|
//############################### Path ##################################
|
|
//#############################################################################
|
|
|
|
Path::ClassData* Path::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void Path::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
PathClassID,
|
|
"MechWarrior4::Path",
|
|
Entity::DefaultData,
|
|
0, NULL,
|
|
(Entity::Factory)Make,
|
|
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
|
|
ExecutionStateEngine::DefaultData,
|
|
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
|
|
NULL,
|
|
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
|
|
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
|
|
(Entity::GameModel::ModelSave)GameModel::SaveGameModel
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void Path::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Path* Path::Make(CreateMessage *message,ReplicatorID *base_id)
|
|
{
|
|
Check_Object(message);
|
|
gos_PushCurrentHeap(Heap);
|
|
Path *new_entity =
|
|
new Path(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Path::Path(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element) :
|
|
Entity(class_data, message, base_id, element),pathPoints()
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
|
|
//
|
|
//----------------------------------
|
|
//We need to load in the path points
|
|
//----------------------------------
|
|
//
|
|
pathPointsResourceID = message->pathPointsResourceID;
|
|
|
|
if(message->pathPointsResourceID != ResourceID::Null)
|
|
{
|
|
Resource stream(message->pathPointsResourceID);
|
|
Verify(stream.DoesResourceExist());
|
|
int num_points;
|
|
stream >> num_points;
|
|
pathPoints.reserve(num_points);
|
|
for(int i=0; i<num_points; i++)
|
|
{
|
|
Point3D point;
|
|
stream >> point;
|
|
pathPoints.push_back(point);
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Path::~Path()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Replicator::CreateMessage* Path::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
|
|
//
|
|
//---------------------------------------------------------------------
|
|
// Make sure there is enough room for the factory request on the stream
|
|
//---------------------------------------------------------------------
|
|
//
|
|
stream->AllocateBytes(sizeof(CreateMessage));
|
|
Entity::SaveMakeMessage(stream, res_file);
|
|
CreateMessage *message =
|
|
Cast_Pointer(CreateMessage*, stream->GetPointer());
|
|
message->messageLength = sizeof(*message);
|
|
|
|
message->pathPointsResourceID = pathPointsResourceID;
|
|
|
|
return message;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void Path::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
Stuff::Point3D Path::GetNearestPoint (const Stuff::Point3D& pt)
|
|
{
|
|
Stuff::Point3D third,toret;
|
|
int i,size,min;
|
|
Stuff::Scalar mindist,dist;
|
|
|
|
size = pathPoints.size ();
|
|
Verify (size>0);
|
|
min = 0;
|
|
third.Subtract (pt,pathPoints[0]);
|
|
mindist = third.GetLengthSquared ();
|
|
for (i=1;i<size;i++)
|
|
{
|
|
third.Subtract (pt,pathPoints[i]);
|
|
dist = third.GetLengthSquared ();
|
|
if (dist < mindist)
|
|
{
|
|
mindist = dist;
|
|
min = i;
|
|
}
|
|
}
|
|
return pathPoints[min];
|
|
}
|
|
|
|
int Path::GetNearestIndex (const Stuff::Point3D& pt)
|
|
{
|
|
Stuff::Point3D third,toret;
|
|
int i,size,min;
|
|
Stuff::Scalar mindist,dist;
|
|
|
|
size = pathPoints.size ();
|
|
Verify (size>0);
|
|
min = 0;
|
|
third.Subtract (pt,pathPoints[0]);
|
|
mindist = third.GetLengthSquared ();
|
|
for (i=1;i<size;i++)
|
|
{
|
|
third.Subtract (pt,pathPoints[i]);
|
|
dist = third.GetLengthSquared ();
|
|
if (dist < mindist)
|
|
{
|
|
mindist = dist;
|
|
min = i;
|
|
}
|
|
}
|
|
return min;
|
|
}
|
|
|
|
void Path::SaveAs2DPoly(Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> >& Poly) const
|
|
{
|
|
gosASSERT(&Poly);
|
|
|
|
Adept::Map& map = *Adept::Map::GetInstance();
|
|
/*
|
|
BYTE rows, cols;
|
|
map.GetElement()->GetSize(&rows, &cols);
|
|
|
|
// Save the MapSize
|
|
Point3D MapSize(rows * c_ZoneSize, 0.0f, cols * c_ZoneSize);
|
|
*/
|
|
int i, size;
|
|
|
|
size = pathPoints.size ();
|
|
Poly.SetLength(size);
|
|
for(i = 0; i < size; i++)
|
|
{
|
|
Stuff::Vector2DOf<Stuff::Scalar>& d = Poly[(size - 1) - i];
|
|
d.x = pathPoints[i].x;
|
|
d.y = pathPoints[i].z;
|
|
map.WorldToZoneCoords(d.x, d.y);
|
|
/*
|
|
d.x += MapSize.x*0.5f;
|
|
d.y += MapSize.z*0.5f;
|
|
d.x *= map.GetColumnZoneScale();
|
|
d.y *= map.GetRowZoneScale();
|
|
*/
|
|
}
|
|
}
|
|
|