Files
firestorm/Gameleap/code/mw4/Code/MW4/planeai.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

897 lines
21 KiB
C++

//===========================================================================//
// File: MechAI.cpp //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 07/13/99 AHF Created file //
//---------------------------------------------------------------------------//
// Copyright (C) 1999, Microsoft //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "Adept\AdeptHeaders.hpp"
#include "mw4.hpp"
#include "planeai.hpp"
#include "Adept\Interface.hpp"
#include "Adept\Application.hpp"
#include "Adept\player.hpp"
#include "Adept\map.hpp"
#include "torso.hpp"
#include "Airplane.hpp"
#include "helicopter.hpp"
#include "dropship.hpp"
#include <Adept\CollisionGrid.hpp>
#include <adept\collisionvolume.hpp>
#include "cheap_move.hpp"
#include "aiutils.hpp"
#include "dropship.hpp"
#pragma warning (push)
#include <algorithm>
#pragma warning (pop)
const int OBSTACLELOOKAHEAD = 50;
const Stuff::Time FLYBY_TIME = 1.0; // 1 second fly by
const Stuff::Scalar flyby_distance = 200.0f;
using namespace MechWarrior4;
using namespace MW4AI;
extern __int64 tMoverAITime,tDynamicObstacleTime;
//#############################################################################
//############################### AI ##############################
//#############################################################################
PlaneAI::ClassData* PlaneAI::DefaultData = NULL;
const Receiver::MessageEntry
PlaneAI::MessageEntries[]=
{
MESSAGE_ENTRY(PlaneAI, DebugText),
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void PlaneAI::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
PlaneAIClassID,
"MechWarrior4::PlaneAI",
CombatAI::DefaultData,
ELEMENTS(MessageEntries), MessageEntries,
(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 PlaneAI::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
PlaneAI* PlaneAI::Make(CreateMessage *message,ReplicatorID *base_id)
{
Check_Object(message);
AutoHeap local_heap (g_AIHeap);
PlaneAI *new_entity = new PlaneAI(DefaultData, message, base_id, NULL);
Check_Object(new_entity);
new_entity->SyncMatrices(true);
return new_entity;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
PlaneAI::PlaneAI(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element)
: CombatAI(class_data, message, base_id, element),
m_ContinuousFlybySwingPoint(-1,-1,-1)
{
AutoHeap local_heap (g_AIHeap);
Check_Pointer(this);
Check_Object(message);
m_InMove = 0;
m_InMoveDir = 1;
m_AirLockedRects.reserve (20);
m_ObstacleAvoidPoint = Point3D (-1,-1,-1);
m_AttackRun = false;
m_Aborting = false;
m_FinishedFlyBy = false;
if (Network::GetInstance()->AmIServer())
{
Entity *ent = getEntity ();
Check_Object(ent);
Verify (ent->IsDerivedFrom (Airplane::DefaultData));
m_Airplane = Cast_Object (Airplane *,ent);
// if (!m_Airplane->IsDerivedFrom (Dropship::DefaultData))
m_Airplane->TurnOn ();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
PlaneAI::~PlaneAI()
{
}
bool PlaneAI::PointIsOK(const Stuff::Point3D& point) const
{
Check_Object (this);
Check_Object (MW4AI::g_MissionGraph);
Check_Object (m_Vehicle);
return true;
}
void PlaneAI::ClearPathLock (bool quitting,bool fromram)
{
Check_Object (this);
__int64 TempTime=GetCycles();
stlport::vector<Rect4D *>::iterator iter2;
Verify (m_AirLockedRects.size () == 0);
for (iter2 = m_AirLockedRects.begin ();iter2 != m_AirLockedRects.end ();iter2++)
{
g_AirRect4DHash->RemoveRect (*iter2);
g_AirRect4DHash->VerifyRectGone (*iter2);
delete *iter2;
}
m_AirLockedRects.clear ();
MoverAI::ClearPathLock (quitting,fromram);
tDynamicObstacleTime+=GetCycles()-TempTime;
}
bool PlaneAI::PathLock (bool secondrun,bool fromram)
{
Check_Object (this);
if (!m_Vehicle)
return false;
__int64 TempTime=GetCycles();
Check_Object (m_Vehicle);
Check_Object (m_Vehicle->GetGameModel ());
Airplane *airplane;
airplane = Cast_Object (Airplane *,m_Vehicle);
if (airplane->OnGround ())
{
MoverAI::PathLock (secondrun,fromram);
}
tDynamicObstacleTime+=GetCycles()-TempTime;
return false;
}
void PlaneAI::NotifyNoPath(void)
{
inherited::NotifyNoPath ();
}
void PlaneAI::NotifyReachedDestination(void)
{
inherited::NotifyReachedDestination ();
}
void PlaneAI::NotifyCollided(Entity *who)
{
inherited::NotifyCollided (who);
}
bool PlaneAI::AddLockRect (Rect4D *newrect,bool carecollide,Stuff::Time till)
{
delete newrect;
return false;
#if 0
Check_Object (this);
Rect4D *crect;
Point3D loc;
Check_Pointer (g_AirRect4DHash);
Check_Pointer (newrect);
if ((!carecollide) || (!m_AttackRun))
{
g_AirRect4DHash->AddRect (newrect);
m_AirLockedRects.push_back (newrect);
return false;
}
crect = g_AirRect4DHash->Collide (*newrect);
if (crect)
{
Verify (m_Vehicle);
loc = (Point3D) m_Vehicle->GetLocalToWorld ();
UnitVector3D p1(m_Vehicle->worldSpaceVelocity.linearMotion),p2;
Point3D extra,otherloc;
Scalar dot = 5.0f;
if ((crect->who) && (crect->who->IsDerivedFrom (AI::DefaultData)))
{
AI* tempai;
tempai = (AI*) crect->who;
if (tempai->getEntity ())
{
otherloc = (Point3D) tempai->getEntity ()->GetLocalToWorld ();
extra.Subtract (otherloc,loc);
if (Small_Enough (extra.GetLength ()))
dot = 0.0f;
else
{
p2 = extra;
dot = (p1.x*p2.x) + (p1.z*p2.z);
}
}
}
if (dot > 0)
{
HandleObstacle (crect);
delete newrect;
return true;
}
else
{
g_AirRect4DHash->AddRect (newrect);
m_AirLockedRects.push_back (newrect);
}
}
else
{
g_AirRect4DHash->AddRect (newrect);
m_AirLockedRects.push_back (newrect);
}
return false;
#endif
}
bool PlaneAI::Avoiding (PlaneAI *who)
{
stlport::vector<AvoidData>::iterator iter;
for (iter = m_AvoidList.begin ();iter != m_AvoidList.end ();iter++)
if (iter->who == who)
return true;
return false;
}
void PlaneAI::AddAvoid (PlaneAI *who)
{
AutoHeap local_heap (g_AIHeap);
stlport::vector<AvoidData>::iterator iter;
for (iter = m_AvoidList.begin ();iter != m_AvoidList.end ();iter++)
if (iter->who == who)
break;
if (iter == m_AvoidList.end ())
{
m_AvoidList.push_back (AvoidData (who,gos_GetElapsedTime ()));
}
else
{
iter->active = gos_GetElapsedTime ();
}
}
void PlaneAI::CleanAvoidList (void)
{
Stuff::Time current;
stlport::vector<AvoidData>::iterator iter;
AutoHeap local_heap (g_AIHeap);
current = gos_GetElapsedTime ();
iter = m_AvoidList.begin ();
while (iter != m_AvoidList.end ())
{
if ((iter->active - current) >= 2.0)
iter = m_AvoidList.erase (iter);
else
iter++;
}
}
void PlaneAI::RemoveAvoid (PlaneAI *who)
{
stlport::vector<AvoidData>::iterator iter;
AutoHeap local_heap (g_AIHeap);
for (iter = m_AvoidList.begin ();iter != m_AvoidList.end ();iter++)
if (iter->who == who)
break;
if (iter != m_AvoidList.end ())
{
m_AvoidList.erase (iter);
}
}
void PlaneAI::KillAvoidList (void)
{
AutoHeap local_heap (g_AIHeap);
m_AvoidList.clear ();
}
Point3D PlaneAI::FindAvoidPoint (Rect4D *rect)
{
Point3D head;
Check_Object (rect->who);
Verify (rect->who->IsDerivedFrom (PlaneAI::DefaultData));
Check_Object (m_Vehicle);
PlaneAI *plane = Cast_Object (PlaneAI *,rect->who);
Check_Object (plane->m_Vehicle);
head.x = ((rect->right - rect->left) / 2.0f) + rect->left;
head.z = ((rect->bottom - rect->top) / 2.0f) + rect->top;
head.y = 0;
Scalar rad1aa,rad2aa;
CollisionVolume *col1,*col2;
col1 = m_Vehicle->GetHierarchicalVolume ();
if (!col1)
col1 = m_Vehicle->GetSolidVolume ();
if (!col1)
rad1aa = 15.0f;
else
rad1aa = col1->m_localSpaceBounds.sphereRadius;
col2 = plane->m_Vehicle->GetHierarchicalVolume ();
if (!col2)
col2 = plane->m_Vehicle->GetSolidVolume ();
if (!col2)
rad2aa = 15.0f;
else
rad2aa = col2->m_localSpaceBounds.sphereRadius;
rad1aa *= 1.2f;
rad2aa *= 1.2f;
Vector3D dir;
if (Small_Enough (rect->velocity.linearMotion.GetLengthSquared ()))
{
dir.x = 1;
dir.y = 0;
dir.z = 0;
}
else
dir.Normalize (rect->velocity.linearMotion);
dir *= (rad1aa+rad2aa);
head -= dir;
return head;
}
void PlaneAI::AttackRunDone (void)
{
m_AttackRun = false;
m_Aborting = false;
m_FinishedFlyBy = true;
}
void PlaneAI::EndAttackRun (void)
{
if (m_Aborting)
return;
m_EndStart = gos_GetElapsedTime ();
m_Aborting = true;
}
void PlaneAI::AbortAttackRun (void)
{
Check_Object (m_Airplane);
m_EndStart = gos_GetElapsedTime ()-FLYBY_TIME;
m_Aborting = true;
m_Airplane->m_Attacking = false;
}
bool PlaneAI::ValidAttackPoint (const Point3D& point)
{
Check_Object (m_Vehicle);
Point3D endpt,extra;
Point3D loc (m_Vehicle->GetLocalToWorld ());
endpt.Subtract (point,loc);
endpt.y = 0;
extra.Normalize (endpt);
Check_Object (m_Vehicle->GetGameModel ());
const Vehicle__GameModel *model = static_cast<const Vehicle__GameModel *> (m_Vehicle->GetGameModel ()) ;
extra *= ((float) (FLYBY_TIME * (double) model->maxSpeed));
extra += point;
return g_MissionGraph->AirQuickCheck ((int) loc.x,(int) loc.z,(int) extra.x,(int) extra.z);
}
bool PlaneAI::FlyBy (const Point3D& point)
{
if (m_FinishedFlyBy)
return true;
if ((m_Aborting) || (m_AttackRun))
return false;
return (!StartAttackRun (point));
}
void PlaneAI::ContinuousFlyBy(const Point3D& point)
{
if (m_ContinuousFlybySwingPoint != Point3D(-1,-1,-1))
{
FlyBy(point);
}
if ((m_FinishedFlyBy == true) ||
((m_CurMove == 0) && (m_OrderSpeed == 0)))
{
if ((m_ContinuousFlybySwingPoint == Point3D(-1,-1,-1)) ||
(m_CurMove == 0))
{
Stuff::Point3D& p = m_ContinuousFlybySwingPoint;
p = point;
switch (gos_rand() & 0x03)
{
case 0:
{
p.x += flyby_distance;
p.z += flyby_distance;
break;
}
case 1:
{
p.x -= flyby_distance;
p.z += flyby_distance;
break;
}
case 2:
{
p.x += flyby_distance;
p.z -= flyby_distance;
break;
}
case 3:
{
p.x -= flyby_distance;
p.z -= flyby_distance;
break;
}
}
Clamp(p.x,MW4AI::MinX,MW4AI::MaxX);
Clamp(p.z,MW4AI::MinZ,MW4AI::MaxZ);
ClearMoveOrder();
orderMoveToLocPoint(p,1000,true,false);
return;
}
Point3D my_pos(vehicle->GetLocalToWorld());
m_ContinuousFlybySwingPoint.y = my_pos.y;
if ((m_CurMove == 0) ||
(m_CurMove->Done() == true) ||
(GetApproximateLength(m_ContinuousFlybySwingPoint,my_pos) < 50))
{
ClearMoveOrder();
m_ContinuousFlybySwingPoint = Point3D(-1,-1,-1);
m_FinishedFlyBy = false;
}
}
}
bool PlaneAI::StartAttackRun (const Point3D& attackpoint)
{
Verify (m_Vehicle);
m_FinishedFlyBy = false;
if ((m_Aborting) || (m_AttackRun))
{
return false;
}
if (!ValidAttackPoint (attackpoint))
{
return false;
}
ClearMoveOrder ();
Scalar height;
BYTE material;
Point3D loc (m_Vehicle->GetLocalToWorld ());
height = GetMapY (attackpoint.x,attackpoint.z,m_Vehicle,material,loc.y);
m_AttackPoint = attackpoint;
if (attackpoint.y < (height+g_MaxAirHeight))
{
m_AttackPoint.y = height + g_MaxAirHeight;
}
m_AttackRun = true;
m_Aborting = false;
m_OrderSpeed = 1.0f;
m_Airplane->m_Attacking = true;
m_Airplane->m_AttackAltitude = g_MaxAirHeight;
return true;
}
void PlaneAI::HandleObstacle (MW4AI::Rect4D *p1,Adept::Entity *p2)
{
if (p1) // potential collision
{
Verify (m_AttackRun);
Verify (p1->who);
Verify (p1->who->IsDerivedFrom (PlaneAI::DefaultData));
PlaneAI *plane = Cast_Object (PlaneAI *,p1->who);
Point3D loc(m_Airplane->GetLocalToWorld ()),otherloc (plane->m_Airplane->GetLocalToWorld ());
if (otherloc.y < loc.y) // only avoid plane lower than us since we are decending
{
AbortAttackRun ();
}
#if 0
Point3D head;
if (!plane->Avoiding (this))
{
head = FindAvoidPoint (p1);
CommandEntry *com;
com = CreateTurnToCommand (head,false);
Check_Pointer (com);
ExecuteCommand (com);
AddAvoid (plane);
}
#endif
}
else if (p2)
{
STOP (("plane ran into another object"));
}
else
{
STOP (("somehow a plane went up a slope that was too steep"));
}
}
void PlaneAI::PathDone (Stuff::Time till,bool failed)
{
Verify (m_Vehicle);
NotifyReachedDestination ();
if ((m_CurMove->MoveType () == MOVE_PATROL) || (m_CurMove->MoveType () == MOVE_SEMIPATROL))
{
CPatrolData *tempmove;
tempmove = (CPatrolData *) m_CurMove;
switch (tempmove->PatrolType ())
{
case PATROL_SINGLE:
m_CurMove->Done (true);
break;
case PATROL_LOOP:
m_InMove = 0;
m_InMoveDir = 1;
break;
case PATROL_SEESAW:
m_InMoveDir *= -1;
m_InMove += m_InMoveDir;
break;
}
}
else
m_CurMove->Done (true);
if (m_Vehicle->IsDerivedFrom (Helicopter::DefaultData))
{
CommandEntry *com;
com = CreateSetSpeedCommand (0);
Check_Pointer (com);
ExecuteCommand (com);
}
}
void PlaneAI::ExecuteMoveHead (Stuff::Time till)
{
if (m_NewMoveHead != m_MoveHead)
{
m_MoveHead = m_NewMoveHead;
m_NeedHeadingAdjust = true;
}
if (m_NewOutVec != m_OutVec)
{
m_OutVec = m_NewOutVec;
}
if (m_NewSpeedRequest != m_SpeedRequest)
{
m_SpeedRequest = m_NewSpeedRequest;
}
}
void PlaneAI::ExecutePath (Stuff::Time till)
{
Verify (m_Vehicle);
if ((!m_CurMove) && (!(((m_Aborting) || (m_AttackRun)))))
return;
Stuff::Scalar dist,move,yvalue;
CommandEntry *com;
Point3D head(0,0,0),destloc,extra;
Point3D loc (m_Vehicle->GetLocalToWorld ());
const Vehicle__GameModel *model = static_cast<const Vehicle__GameModel *> (m_Vehicle->GetGameModel ()) ;
Stuff::Scalar speed;
speed = m_Vehicle->speedDemand;
yvalue = loc.y;
loc.y = 0;
if (m_AttackRun)
{
if (!ValidAttackPoint (m_AttackPoint))
{
AbortAttackRun ();
}
destloc = m_AttackPoint;
}
else
{
destloc = m_CurMove->Location (m_InMove);
}
destloc.y = 0;
extra.Subtract (destloc,loc);
dist = extra.GetLengthSquared ();
move = (float) (speed * model->maxSpeed); // use one second buffer
move *= move;
if ((dist<25.0) || (dist < move))
{
if (m_AttackRun)
{
EndAttackRun ();
}
else if ((m_InMoveDir > 0) && (m_CurMove->LocationSize () > (m_InMove+m_InMoveDir)))
{
m_InMove+=m_InMoveDir;
}
else if ((m_InMoveDir < 0) && ((m_InMove+m_InMoveDir) > 0))
{
m_InMove+= m_InMoveDir;
}
else
{
PathDone (till);
}
}
if (m_AttackRun)
{
head = m_AttackPoint;
}
else
{
head = m_CurMove->Location (m_InMove);
}
if (m_Aborting)
{
BYTE material;
Scalar height;
if ((m_EndStart+FLYBY_TIME) <= gos_GetElapsedTime ())
{
Check_Object (m_Airplane);
m_Airplane->m_Attacking = false;
}
height = GetMapY (loc.x,loc.z,m_Vehicle,material,yvalue);
if (yvalue >= (height + m_Airplane->flyingAltitude))
{
AttackRunDone ();
}
else
{
m_NewMoveHead = Point3D (-1,-1,-1);
com = CreateKillTurnToCommand ();
Check_Pointer (com);
ExecuteCommand (com);
return;
}
}
else
{
m_NewMoveHead = Point3D (-1,-1,-1);
com = CreateTurnToCommand (head,false);
Check_Pointer (com);
ExecuteCommand (com);
}
m_NewSpeedRequest = m_OrderSpeed;
com = CreateSetSpeedCommand (m_OrderSpeed);
Check_Pointer (com);
ExecuteCommand (com);
}
void PlaneAI::ExecuteMoveCommand (Stuff::Time till)
{
Verify (m_Vehicle);
if (!m_CurMove)
return;
if (m_CurMove->Done ())
return;
if (!m_CurMove->Executing ())
{
m_CurMove->Executing (true);
m_OrderSpeed = m_CurMove->Speed ();
}
else
{
m_OrderSpeed = m_CurMove->Speed ();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void PlaneAI::PreCollisionExecute(Time till)
{
Check_Object(this);
AI_LOGIC("Pre-Collision::Plane AI");
//
//---------------------------------
// Verify that this always executes
//---------------------------------
//
Check_Object(executionState);
Verify(executionState->GetState() != ExecutionStateEngine::NeverExecuteState);
m_Deactive = false;
CleanAvoidList ();
CombatAI::PreCollisionExecute(till);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void PlaneAI::DebugTextMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
Check_Object(this);
Check_Object(message);
Verify(message->messageID == DebugTextMessageID);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void PlaneAI::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
void PlaneAI::TurnOn (void)
{
}
void PlaneAI::TurnOff (void)
{
m_Deactive = false;
}
void PlaneAI::ExecuteMoveCommand (MW4AI::CommandEntry *command)
{
Verify (m_Vehicle);
Check_Pointer (command);
ClearMoveOrder ();
m_CurMove = (CMoveData *) command->DataPtr ();
Stuff::Point3D temp;
temp = (Stuff::Point3D) m_Vehicle->GetLocalToWorld ();
m_CurMove->CreatePlaneRequests (temp);
m_OrderSpeed = m_CurMove->Speed ();
m_InMove = 0;
m_InMoveDir = 1;
Check_Pointer (m_CurMove);
}
void PlaneAI::hellteleport (void)
{
Check_Object(m_Vehicle);
Verify(m_Vehicle->IsDerivedFrom(Airplane::DefaultData));
Airplane *flyer = Cast_Object(Airplane *, m_Vehicle);
flyer->executionState->RequestState(Airplane::ExecutionStateEngine::NeverExecuteState);
}
bool PlaneAI::orderTakeOff (int distance)
{
Check_Object(m_Vehicle);
Verify(m_Vehicle->IsDerivedFrom(Airplane::DefaultData));
Airplane *flyer = Cast_Object(Airplane *, m_Vehicle);
if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::NeverExecuteState)
flyer->TakeOff((Scalar)distance);
else if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::AlwaysExecuteState)
flyer->TakeOff((Scalar)distance);
else if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::TaxiState)
flyer->TakeOff((Scalar)distance);
else if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::FlyingMotionState)
return true;
return false;
}
bool PlaneAI::orderLand (void)
{
Check_Object(m_Vehicle);
Verify(m_Vehicle->IsDerivedFrom(Helicopter::DefaultData));
ClearMoveOrder ();
Helicopter *flyer = Cast_Object(Helicopter *, m_Vehicle);
if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::NeverExecuteState)
return true;
else if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::AlwaysExecuteState)
return true;
else if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::TaxiState)
return true;
else if(flyer->executionState->GetState() == Airplane::ExecutionStateEngine::FlyingMotionState)
flyer->Land();
return false;
}
bool PlaneAI::orderDoorOpen(void)
{
Check_Object(m_Vehicle);
Verify(m_Vehicle->IsDerivedFrom(Dropship::DefaultData));
ClearMoveOrder ();
Dropship *drop = Cast_Object(Dropship *, m_Vehicle);
return drop->orderDoorOpen();
}
bool PlaneAI::orderDoorClose(void)
{
Check_Object(m_Vehicle);
Verify(m_Vehicle->IsDerivedFrom(Dropship::DefaultData));
ClearMoveOrder ();
Dropship *drop = Cast_Object(Dropship *, m_Vehicle);
return drop->orderDoorClose();
}
void PlaneAI::orderMoveLookOut (void)
{
if (!m_Active)
return;
gosREPORT (false,"Cannot give a lookout order to a plane");
}
void PlaneAI::orderMoveSit (bool shutdown)
{
if (!m_Active)
return;
gosREPORT (false,"Cannot give a sit order to a plane");
}