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

516 lines
17 KiB
C++

//===========================================================================//
// File: mechai.hpp //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 07/13/99 AHF Created File //
//---------------------------------------------------------------------------//
// Copyright (C) 1999, Microsoft //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "ai.hpp"
#include "aiutils.hpp"
#include "rail_move.hpp"
#include "vehicle.hpp"
#include "path.hpp"
#include "aiMoveData.hpp"
#include "obstacle.hpp"
namespace MechWarrior4
{
class Dropship;
class FieldBase;
class CCheapMover;
typedef MechWarrior4::AI__CreateMessage MoverAI__CreateMessage;
//##########################################################################
//########################### MoverAI #################################
//##########################################################################
class MoverAI : public MechWarrior4::AI
{
typedef AI inherited;
friend class CMoveData;
friend class CPatrolData;
friend class CSemiPatrolData;
friend class CRigidPatrolData;
friend class CFollowData;
friend class CLookoutData;
friend class CFleeData;
friend class CSitData;
friend class CMoveLocPointData;
friend class CMoveObjectData;
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Inheritance Support
//
public:
typedef MoverAI__CreateMessage CreateMessage;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Run-time Construction and Destruction Support
//
public:
virtual void Save (MemoryStream *stream);
virtual void Load (MemoryStream *stream);
static MoverAI* Make(CreateMessage *message,ReplicatorID *base_id);
virtual void NotifyRespawned();
protected:
MoverAI(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element);
virtual ~MoverAI();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Message Support
//
public:
enum {
DebugTextMessageID = MechWarrior4::AI::NextMessageID,
NextMessageID
};
void DebugTextMessageHandler(Adept::ReceiverDataMessageOf<int> *message);
protected:
static const MessageEntry MessageEntries[];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// MoveHead Support
//
protected:
enum HeadHit {
LEFT_INSIDE_HIT,
RIGHT_INSIDE_HIT,
TOP_INSIDE_HIT,
BOTTOM_INSIDE_HIT,
LEFT_OUTSIDE_HIT,
RIGHT_OUTSIDE_HIT,
TOP_OUTSIDE_HIT,
BOTTOM_OUTSIDE_HIT,
NO_HIT
};
Stuff::Point3D m_TopLeft,m_TopRight,m_BottomLeft,m_BottomRight; // coords of rectangle top is start
Stuff::Point3D m_StartPoint,m_EndPoint;
void ConstructRect (const Stuff::Point3D& start,const Stuff::Point3D& end,Stuff::Scalar width);
HeadHit HeadPointInRect (const LinearMatrix4D& loc,Scalar speed,Stuff::Scalar delta);
bool Intersect (const Stuff::Point3D& start,const Stuff::Point3D& end,const Stuff::Point3D& p1,const Stuff::Point3D& p2);
Stuff::Point3D LeftHeadPoint (const Point3D& loc,const Stuff::Point3D& head);
Stuff::Point3D RightHeadPoint (const Point3D& loc,const Stuff::Point3D& head);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Execution Support
//
protected:
static bool m_AIJumpAllowed;
MechWarrior4::Vehicle *m_Vehicle;
MechWarrior4::MWObject *m_MWObject;
CMoveData *m_CurMove;
MW4AI::CRailPath *m_CurPath;
Stuff::Point3D m_MoveHead,m_OutVec,m_OldMoveHead;
Stuff::Point3D m_NewMoveHead,m_NewOutVec;
Stuff::Scalar m_SpeedRequest,m_NewSpeedRequest;
Stuff::Scalar m_EndSpeedRequest, m_NewEndSpeedRequest;
Stuff::Scalar m_OrderSpeed;
Stuff::Time m_StartJump,m_BurnTime;
bool m_NeedHeadingAdjust,m_NeedSpeedAdjust;
bool m_Jumping;
bool m_JumpRequested;
int m_FailCount; // # of times path calc has failed for current path
CCheapMover *m_CheapMover;
Stuff::Scalar m_TimeNotMoving;
Stuff::Point3D m_CombatLeash;
Stuff::Scalar m_CombatLeashRadius;
virtual void SetOrderSpeed (Stuff::Scalar newvalue);
virtual void ExecutePath (Stuff::Time till);
virtual void ExecuteMoveCommand (Stuff::Time till);
virtual void ExecuteMoveHead (Stuff::Time till);
virtual void ExecuteMoveHeadCollision (Stuff::Time till);
virtual void ExecutePostPath (Stuff::Time till);
virtual void PathDone (Stuff::Time till,bool failed=false);
virtual bool Jump (Stuff::Time till,const Stuff::Point3D& dest,bool request=false);
virtual bool RequestJump (Stuff::Time till);
virtual bool AllowTenMeter (void);
public:
virtual void PreCollisionExecute(Stuff::Time till);
virtual void Info (void (*printCallback)(char* s));
virtual void Die (void);
// LinearMatrix4D GetAILocalToWorld (void);
bool ReactToCollision(Stuff::DynamicArrayOf<CollisionData> *collisions,bool& shoulddamage); // return false to not handle collision
MechWarrior4::Vehicle *getVehicle (void)
{ return m_Vehicle; }
MW4AI::CRailPath* getCurPath (void)
{ return m_CurPath; }
virtual void TurnOn (void);
virtual void TurnOff (void);
inline void SetCombatLeash(const Stuff::Point3D& center, Stuff::Scalar radius);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Dropship Support
//
public:
enum DROP_STATE {
DROP_NOT_ACTIVE, // not boarding a dropship
DROP_FIRST_POINT, // approaching wait point
DROP_SECOND_POINT, // approaching point outside doors
DROP_THIRD_POINT, // approaching center of dropship
DROP_FOURTH_POINT, // approaching final point
DROP_DONE // done boarding
};
protected:
Stuff::Point3D m_DropShipWait; // point to wait to board drop ship
Stuff::Point3D m_DropShipBoard; // point outside doors
Stuff::Point3D m_DropShipCenter; // point at center of dropship
Stuff::Point3D m_DropShipFinal; // final point to stand in drop ship
DROP_STATE m_BoardingDropShip;
std::vector<MoverAI *> m_OtherDropShipBoarders;
int m_DropShipID; // which of the five we are
Dropship *m_DropShip;
bool m_ReadyToStart; // can be told to start boarding have reached wait point
bool m_CanStartBoard; // previous person has reached center, so can start boarding
void NextBoardDropShip (void);
void CheckDropBoard (Stuff::Time delta);
void StartDropShipBoard (void)
{ m_CanStartBoard = true; }
public:
void AddDropshipBoarder (int id,MoverAI *who);
void CreateDropShipPoints (int id,Dropship *drop);
void PrepareBoardDropShip (void);
DROP_STATE DropState (void) const
{ return m_BoardingDropShip; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FieldBase Support
//
public:
enum FIELDBASE_STATE {
FIELDBASE_NOT_ACTIVE, // not entering a field base
FIELDBASE_ENTER, // entering a fieldbase
FIELDBASE_HEAL, // healing in fieldbase
FIELDBASE_EXIT, // exiting a fieldbase
FIELDBASE_DEAD // exiting from dead fieldbase
};
protected:
Stuff::Point3D m_FieldBaseEnter; // point to wait to board drop ship
Stuff::Point3D m_FieldBaseExit; // point outside doors
FIELDBASE_STATE m_EnteringFieldBase;
FieldBase *m_FieldBase;
bool m_FieldBaseReverse;
void CheckFieldBase (Stuff::Time delta);
public:
void FieldBaseDead (void);
void NextFieldBase (bool frommover=false);
bool CreateFieldBasePoints (FieldBase *base);
void PrepareEnterFieldBase (void);
FIELDBASE_STATE FieldBaseState (void) const
{ return m_EnteringFieldBase; }
virtual void FinishFieldBase (void);
static bool g_AlwaysIgnoreObstacles;
bool ExitedFieldBaseRecently() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Obstacle Support
//
protected:
bool m_PathBlocked;
MW4AI::CPathRequest *m_ObstacleRequest;
MWObject *m_RamTarget;
Stuff::Point3D m_PathBlockedCell;
MW4AI::Rect4D *m_PathBlockedRect;
int m_PathBlockedRectTimeDelta;
stlport::vector<Entity *> m_ObstacleList;
stlport::vector<MW4AI::LockData*> m_PathLock; // in BLOCK_GRID_RES coordinates
stlport::vector<MW4AI::Rect4D *> m_LockedRects;
Stuff::Time m_LockTime;
Stuff::Time m_RecalcTime;
bool m_PathBad;
stlport::vector<MW4AI::Rect4D *> m_TempLockRects;
// bool m_ObstacleAvoidMode;
Point3D m_ObstacleAvoidPoint;
stlport::vector<MW4AI::LockData *> m_TempLock; // in BLOCK_GRID_RES coordinates
Stuff::Scalar m_LastTimeFinishedFieldBase;
bool m_ShouldEndFieldBase;
// void CheckObstacle (Stuff::Time till);
// void AddObstacle (Entity *);
virtual bool PointIsOK(const Stuff::Point3D& point) const;
bool LockSquare (const Point3D& loc,Stuff::Scalar rad,Point3D& culprit);
bool ObstacleNearBy (const Point3D& loc);
void LancemateFieldBasePoint (Stuff::Point3D &pt,FieldBase *base);
bool CheckSquare (const Point3D& loc,Stuff::Scalar rad,int dir,int mask,bool tenmeter);
void AddTempLockRect (MW4AI::Rect4D *area)
{ m_TempLockRects.push_back (area); }
void AddTempLockRect (const MW4AI::Rect4D& area)
{
MW4AI::Rect4D *rect;
rect = new MW4AI::Rect4D (area);
m_TempLockRects.push_back (rect);
}
void ClearTempLockRects (void);
void CalcTempLock (void);
void CalcUnTempLock (void);
virtual void NotifyNoPath(void);
virtual void NotifyReachedDestination(void);
virtual void NotifyCollided(Entity *who);
bool LockedByMe (const Stuff::Point3D& loc) const
{
return (MW4AI::Blocker (loc) == (MWObject *) this);
}
bool AddLockCell (const Stuff::Point3D& loc); // true if can lock cell
bool AddLockRect (MW4AI::Rect4D *p1,bool carecollide,Stuff::Time till);
void ClearRamLock (void);
void RamLock (void);
bool EqualRamTarget (Entity *target);
virtual void HandleObstacle (MW4AI::Rect4D *p1,Adept::Entity *p2);
public:
virtual void ClearPathLock (bool quitting,bool fromram);
virtual bool PathLock (bool secondpass,bool fromram);
virtual void CalcPathLock (MW4AI::CPathRequest *reg);
virtual void CalcPathUnlock (MW4AI::CPathRequest *reg);
void RecalcPath (Stuff::Time till);
void SetRamTarget (MWObject *obj);
void SlopeCollide (void);
void HandleObstacle (MW4AI::Rect4D *p1)
{ HandleObstacle (p1,NULL); }
void HandleObstacle (Adept::Entity *p1)
{ HandleObstacle (NULL,p1); }
void HandleObstacle (void)
{ HandleObstacle (NULL,NULL); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Order Support
//
public:
static void DisableAIJumping (void)
{
m_AIJumpAllowed = false;
}
virtual void Shutdown (void)
{
ClearMoveOrder ();
inherited::Shutdown ();
}
virtual void orderMoveLookOut (void);
virtual bool orderMoveTo (Path *,int speed,int type,bool forwards,bool clear);
virtual bool orderMoveToSemi (Path *,int speed,int type,bool forwards,bool clear);
virtual bool orderMoveToRigid (Path *,int speed,int type,bool forwards,bool clear);
virtual int orderMoveFlee (Entity *away,int speed);
virtual bool orderMoveResumePatrol (Path *,int speed,int type,bool forwards,bool clear);
virtual bool orderMoveResumePatrolSemi (Path *,int speed,int type,bool forwards,bool clear);
virtual bool orderMoveResumePatrolRigid (Path *,int speed,int type,bool forwards,bool clear);
virtual void orderMoveFollow (Entity *who,int offsetx,int offsetz,int maxspeed);
virtual void orderMoveSit (bool shutdown);
virtual bool orderMoveToLocPoint (const Stuff::Point3D& where,int speed,bool forwards,bool clear);
virtual bool orderMoveToObject (Entity *what,int speed);
virtual void ClearMoveOrder (void);
virtual void NewPath (MW4AI::CRailPath *path,bool overridemove=false);
protected:
virtual Stuff::Scalar GetMinSpeed() const { return (0); }
public:
virtual void SetMoveHead (const Stuff::Point3D& head,Stuff::Scalar speed,const Stuff::Point3D& outvec = Stuff::Point3D (-1,-1,-1),Stuff::Scalar endspeed = 0);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Command Support
//
protected:
virtual void ExecuteMoveCommand (MW4AI::CommandEntry *command);
virtual void ExecuteHighCommand (MW4AI::CommandEntry *command);
virtual void ExecuteLowCommand (MW4AI::CommandEntry *command);
MW4AI::CommandEntry *CreateMoveToCommand (const Stuff::Point3D& where,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (MOVETO_LOWID,false,start);
Check_Pointer (toret);
toret->DataPoint3D (where);
return toret;
}
MW4AI::CommandEntry *CreateTurnToCommand (const Stuff::Point3D& where,bool reverse,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (TURNTO_LOWID,false,start);
Check_Pointer (toret);
toret->DataPoint3D (where);
toret->DataBoolean (reverse);
return toret;
}
MW4AI::CommandEntry *CreateTrackCommand (const Stuff::Point3D& where,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (TRACK_LOWID,false,start);
Check_Pointer (toret);
toret->DataPoint3D (where);
return toret;
}
MW4AI::CommandEntry *CreateKillTurnToCommand (Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (KILLTURNTO_LOWID,false,start);
Check_Pointer (toret);
return toret;
}
MW4AI::CommandEntry *CreateKillTrackCommand (Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (KILLTRACK_LOWID,false,start);
Check_Pointer (toret);
return toret;
}
MW4AI::CommandEntry *CreateTrackToCommand (Stuff::Scalar amount,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (TRACKTO_LOWID,false,start);
Check_Pointer (toret);
toret->DataScalar (amount);
return toret;
}
MW4AI::CommandEntry *CreateTurnCommand (Stuff::Scalar amount,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (TURN_LOWID,false,start);
Check_Pointer (toret);
toret->DataScalar (amount);
return toret;
}
MW4AI::CommandEntry *CreateSetSpeedCommand (Stuff::Scalar amount,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (SETSPEED_LOWID,false,start);
Check_Pointer (toret);
toret->DataScalar (amount);
return toret;
}
public:
enum
{
TELEPORT_HIGHID = MechWarrior4::AI::NextHighCommandID,
MOVE_HIGHID,
FLEE_HIGHID,
FORMONSPOT_HIGHID,
FOLLOW_HIGHID,
NextHighCommandID
};
enum
{
MOVETO_LOWID = MechWarrior4::AI::NextLowCommandID,
TURNTO_LOWID,
KILLTURNTO_LOWID,
TRACK_LOWID,
TRACKTO_LOWID,
KILLTRACK_LOWID,
TURN_LOWID,
SETSPEED_LOWID,
NextLowCommandID
};
MW4AI::CommandEntry *CreateTeleportCommand (Stuff::Point3D where,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (TELEPORT_HIGHID,true,start);
Check_Pointer (toret);
toret->DataPoint3D (where);
return toret;
}
MW4AI::CommandEntry *CreateMoveCommand (CMoveData *data,Stuff::Time start = gos_GetElapsedTime ())
{
MW4AI::CommandEntry *toret;
toret = CreateBaseCommand (MOVE_HIGHID,true,start);
Check_Pointer (toret);
toret->DataPtr (data);
return toret;
}
MW4AI::CommandEntry *CreateFleeCommand (Stuff::Scalar amount,Stuff::Time start = gos_GetElapsedTime ())
{
return CreateBaseCommand (FLEE_HIGHID,true,start);
}
MW4AI::CommandEntry *CreateFormOnSpotCommand (Stuff::Scalar amount,Stuff::Time start = gos_GetElapsedTime ())
{
return CreateBaseCommand (FORMONSPOT_HIGHID,true,start);
}
MW4AI::CommandEntry *CreateFollowCommand (Stuff::Scalar amount,Stuff::Time start = gos_GetElapsedTime ())
{
return CreateBaseCommand (FOLLOW_HIGHID,true,start);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test Support
//
public:
void TestInstance() const;
};
inline void MoverAI::SetCombatLeash(const Stuff::Point3D& center, Stuff::Scalar radius)
{
m_CombatLeash = center;
m_CombatLeashRadius = radius;
}
}