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.
168 lines
3.9 KiB
C++
168 lines
3.9 KiB
C++
#include "MW4Headers.hpp"
|
|
#include "cheap_move.hpp"
|
|
#include <Adept\CollisionGrid.hpp>
|
|
|
|
using namespace MechWarrior4;
|
|
namespace MW4AI
|
|
{
|
|
extern Stuff::Scalar MinZ, MaxZ, MinX, MaxX;
|
|
}
|
|
|
|
CCheapMover::CCheapMover (Stuff::Point3D newloc)
|
|
{
|
|
m_Loc = newloc;
|
|
m_Airplane = false;
|
|
m_LastDir = Vector3D::Identity;
|
|
}
|
|
|
|
CCheapMover::CCheapMover (Stuff::Point3D newloc,Stuff::Scalar altitude)
|
|
{
|
|
m_Loc = newloc;
|
|
m_Airplane = true;
|
|
m_LastDir = Vector3D::Identity;
|
|
m_FlyingAltitude = altitude;
|
|
}
|
|
|
|
bool CCheapMover::UpdatePos (Point3D dest,Scalar speed,float till)
|
|
{
|
|
Point3D extra,third;
|
|
Scalar dist;
|
|
|
|
if (dest.x < (MW4AI::MinX+50)) // fix off edge problems.
|
|
dest.x = MW4AI::MinX+50;
|
|
if (dest.z < (MW4AI::MinZ+50))
|
|
dest.z = MW4AI::MinZ+50;
|
|
|
|
if (dest.x > (MW4AI::MaxX-50))
|
|
dest.x = MW4AI::MaxX-50;
|
|
if (dest.z > (MW4AI::MaxZ-50))
|
|
dest.z = MW4AI::MaxZ-50;
|
|
|
|
dest.y = 0;
|
|
m_Loc.y = 0;
|
|
extra.Subtract (dest,m_Loc);
|
|
dist = extra.GetLengthSquared ();
|
|
|
|
Scalar move;
|
|
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 <= 9.0f) || (dist < move))
|
|
{
|
|
m_Loc = dest;
|
|
m_Dir = Vector3D::Identity;
|
|
m_LastDir = Vector3D::Identity;
|
|
return true;
|
|
}
|
|
speed *= (float) till;
|
|
extra.y = 0;
|
|
third.Normalize (extra);
|
|
m_Dir = third;
|
|
third *= speed;
|
|
m_Loc += third;
|
|
|
|
return false;
|
|
}
|
|
|
|
void CCheapMover::UpdatePos (Vehicle *veh,Stuff::Point3D dest)
|
|
{
|
|
YawPitchRoll new_rotation(YawPitchRoll::Identity);
|
|
new_rotation = (YawPitchRoll) veh->GetLocalToWorld ();
|
|
Point3D new_translation;
|
|
Point3D curlocation (veh->GetLocalToWorld ());
|
|
|
|
new_translation = Loc ();
|
|
|
|
{
|
|
// Find the ground
|
|
|
|
//
|
|
// make a line...
|
|
//
|
|
Stuff::Line3D line;
|
|
line.m_length = 20.0f;
|
|
line.m_direction = Vector3D::Down;
|
|
line.m_origin = new_translation;
|
|
line.m_origin.y = curlocation.y + 5.0f; // pretty harsh hill! =)
|
|
|
|
//
|
|
// Prepare query
|
|
//
|
|
Stuff::Normal3D normal;
|
|
Entity::CollisionQuery query(&line, &normal, Entity::CanBeWalkedOnFlag, veh);
|
|
|
|
//
|
|
// Cast ray
|
|
//
|
|
Adept::Entity *entity_hit;
|
|
Check_Object(CollisionGrid::Instance);
|
|
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
|
|
|
|
if (entity_hit != NULL)
|
|
{
|
|
// if we hit ground, great!
|
|
line.FindEnd(&new_translation);
|
|
}
|
|
else
|
|
{
|
|
// Damnit...then find the ground aggresivly!!!!
|
|
line.m_origin = new_translation;
|
|
line.m_origin.y = curlocation.y + 100.0f; // pretty harsh hill! =)
|
|
line.m_length = 1000.0f;
|
|
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
|
|
if (entity_hit != NULL)
|
|
{
|
|
line.FindEnd(&new_translation);
|
|
}
|
|
else // now try up!
|
|
{
|
|
line.m_direction = Vector3D(0.0f, 1.0f, 0.0f);
|
|
entity_hit = CollisionGrid::Instance->ProjectLine(&query);
|
|
if (entity_hit != NULL)
|
|
{
|
|
line.FindEnd(&new_translation);
|
|
}
|
|
}
|
|
// ok stop we are way off the map
|
|
}
|
|
}
|
|
|
|
LinearMatrix4D new_local_to_world;
|
|
if (m_Airplane)
|
|
{
|
|
new_translation.y += m_FlyingAltitude;
|
|
}
|
|
if (new_translation.x < (MW4AI::MinX+50)) // fix off edge problems.
|
|
new_translation.x = MW4AI::MinX+50;
|
|
if (new_translation.z < (MW4AI::MinZ+50))
|
|
new_translation.z = MW4AI::MinZ+50;
|
|
|
|
if (new_translation.x > (MW4AI::MaxX-50))
|
|
new_translation.x = MW4AI::MaxX-50;
|
|
if (new_translation.z > (MW4AI::MaxZ-50))
|
|
new_translation.z = MW4AI::MaxZ-50;
|
|
|
|
|
|
|
|
new_local_to_world.BuildTranslation(new_translation);
|
|
Point3D fred;
|
|
fred.Add (m_Dir,m_LastDir);
|
|
Scalar len;
|
|
len = fred.GetLengthSquared ();
|
|
if ((m_LastDir != Vector3D::Identity) && (m_Dir != Vector3D::Identity) && (len > 0.01f))
|
|
{
|
|
YawPitchRange fred (m_Dir);
|
|
new_rotation.yaw = fred.yaw;
|
|
new_rotation.pitch = fred.pitch;
|
|
new_rotation.roll = 0;
|
|
}
|
|
m_LastDir = m_Dir;
|
|
new_local_to_world.BuildRotation(new_rotation);
|
|
|
|
veh->SetNewLocalToParent(new_local_to_world);
|
|
}
|
|
|