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

336 lines
9.0 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 "mech_ai.hpp"
#include "Adept\Interface.hpp"
#include "Adept\Application.hpp"
#include "Vehicle.hpp"
#include "lancemate.hpp"
#include "gameinfo.hpp"
#include "field_base.hpp"
#include "vehicleinterface.hpp"
using namespace MechWarrior4;
using namespace MW4AI;
std::list<MechAI*>* MechAI::m_gShutdownMechAIs = 0;
int MechAI::m_gShutdownMechAIs_RefCount = 0;
//#############################################################################
//############################### AI ##################################
//#############################################################################
MechAI::ClassData* MechAI::DefaultData = NULL;
const Receiver::MessageEntry MechAI::MessageEntries[]=
{
MESSAGE_ENTRY(MechAI, DebugText),
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAI::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
MechAIClassID,
"MechWarrior4::MechAI",
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 MechAI::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MechAI* MechAI::Make(CreateMessage *message,ReplicatorID *base_id)
{
AutoHeap local_heap (g_AIHeap);
Check_Object(message);
MechAI *new_entity = new MechAI(DefaultData, message, base_id, NULL);
Check_Object(new_entity);
new_entity->SyncMatrices(true);
return new_entity;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MechAI::MechAI(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element)
: CombatAI(class_data, message, base_id, element)
{
Check_Pointer(this);
Check_Object(message);
m_Mech = NULL;
if (Network::GetInstance()->AmIServer())
{
Check_Object(vehicle);
m_Mech = Cast_Object(Mech *, getEntity ());
Check_Object (m_Mech);
}
if (m_gShutdownMechAIs_RefCount == 0)
{
Verify(m_gShutdownMechAIs == 0);
m_gShutdownMechAIs = new std::list<MechAI*>;
}
++m_gShutdownMechAIs_RefCount;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MechAI::~MechAI()
{
Verify(m_gShutdownMechAIs_RefCount > 0);
Verify(m_gShutdownMechAIs != 0);
std::list<MechAI*>::iterator found = std::find(m_gShutdownMechAIs->begin(),m_gShutdownMechAIs->end(),this);
if (found != m_gShutdownMechAIs->end())
{
m_gShutdownMechAIs->erase(found);
}
--m_gShutdownMechAIs_RefCount;
if (m_gShutdownMechAIs_RefCount == 0)
{
delete m_gShutdownMechAIs;
m_gShutdownMechAIs = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAI::PreCollisionExecute(Time till)
{
extern int g_nMR;
if (g_nMR == 2)
return;
AI_LOGIC("Pre-Collision::MechAI");
Check_Object(this);
#if defined(LAB_ONLY)
if (!instanceName)
MWGameInfo::g_LastMWObject[0] = '\0';
else
{
strncpy(MWGameInfo::g_LastMWObject, instanceName, sizeof(MWGameInfo::g_LastMWObject)-1);
MWGameInfo::g_LastMWObject[sizeof(MWGameInfo::g_LastMWObject)-1] = '\0';
}
MWGameInfo::g_LastMWObjectPos = GetLocalToWorld();
#endif
//
//---------------------------------
// Verify that this always executes
//---------------------------------
//
Check_Object(executionState);
Verify(executionState->GetState() != ExecutionStateEngine::NeverExecuteState);
if (m_StartupRequest)
Startup ();
if (m_ShutdownRequest)
Shutdown ();
inherited::PreCollisionExecute(till);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAI::DebugTextMessageHandler(Adept::ReceiverDataMessageOf<int> *message)
{
Check_Object(this);
Check_Object(message);
Verify(message->messageID == DebugTextMessageID);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MechAI::ReactToCollision(Stuff::DynamicArrayOf<CollisionData> *collisions,bool& shoulddamage)
{
int i;
if (m_EnteringFieldBase != FIELDBASE_NOT_ACTIVE)
{
return inherited::ReactToCollision (collisions,shoulddamage);
}
for (i=0; i<collisions->GetLength(); ++i)
{
CollisionData *data = &(*collisions)[i];
Check_Object(data);
Check_Object(data->m_otherEntity);
Verify(this != data->m_otherEntity);
Verify(GetInterestLevel() != DormantInterestLevel);
Check_Object(m_Vehicle);
Vector3D vector_to_target;
Point3D local_to_world(m_Vehicle->GetLocalToWorld());
Point3D target_local_to_world(data->m_otherEntity->GetLocalToWorld());
if (data->m_otherEntity->IsDerivedFrom (FieldBase::DefaultData))
{
if (!CreateFieldBasePoints (Cast_Object (FieldBase *,data->m_otherEntity)))
{
if (!m_Vehicle->vehicleInterface)
{
ClearMoveOrder ();
}
shoulddamage = false;
return inherited::ReactToCollision (collisions,shoulddamage);
}
if (m_Vehicle->vehicleInterface)
{
m_Vehicle->vehicleInterface->PlayerAIFieldBase (true);
}
PrepareEnterFieldBase ();
shoulddamage = false;
}
}
return inherited::ReactToCollision (collisions,shoulddamage);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAI::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
void MechAI::SetOrderSpeed (Stuff::Scalar newvalue)
{
if (newvalue < 0)
{
Mech *mech;
mech = Cast_Object (Mech *,m_Vehicle);
if (mech->gimpState != Mech::NotGimpedMode)
newvalue = -newvalue;
}
m_OrderSpeed = newvalue;
}
void MechAI::Shutdown (void)
{
Check_Object (m_Mech);
m_StartupRequest = false;
if (!m_Mech->ShutDownRequest (true))
m_ShutdownRequest = true;
else
m_ShutdownRequest = false;
inherited::Shutdown ();
if (m_gShutdownMechAIs != 0)
{
std::list<MechAI*>::iterator found = std::find(m_gShutdownMechAIs->begin(),m_gShutdownMechAIs->end(),this);
if (found == m_gShutdownMechAIs->end())
{
m_gShutdownMechAIs->push_back(this);
}
}
}
void MechAI::Startup (void)
{
Check_Object (m_Mech);
m_ShutdownRequest = false;
if (!m_Mech->ShutDownRequest (false))
m_StartupRequest = true;
else
m_StartupRequest = false;
inherited::Startup ();
if (m_gShutdownMechAIs != 0)
{
std::list<MechAI*>::iterator found = std::find(m_gShutdownMechAIs->begin(),m_gShutdownMechAIs->end(),this);
if (found != m_gShutdownMechAIs->end())
{
m_gShutdownMechAIs->erase(found);
}
}
}
void MechAI::Save (MemoryStream *stream)
{
*stream << m_StartupRequest;
*stream << m_ShutdownRequest;
CombatAI::Save (stream);
}
void MechAI::Load (MemoryStream *stream)
{
*stream >> m_StartupRequest;
*stream >> m_ShutdownRequest;
CombatAI::Load (stream);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAI::NotifyShutDownMechsShotFired(const Adept::Entity::CollisionQuery& query, MWObject& shooter)
{
if (m_gShutdownMechAIs == 0)
{
return;
}
{for (std::list<MechAI*>::iterator i = m_gShutdownMechAIs->begin();
i != m_gShutdownMechAIs->end();
++i)
{
(*i)->NotifyShotFired(query,shooter);
}}
}
bool MechAI::ShouldRunScript()
{
if (m_SquadOrders.GetPointer() != 0)
{
return (m_SquadOrders->ShouldRunScript());
}
return (inherited::ShouldRunScript());
}
bool MechAI::GetLeaderAlignment(int& alignment)
{
if (m_SquadOrders.GetPointer() != 0)
{
return (m_SquadOrders->GetLeaderAlignment(alignment));
}
return (inherited::GetLeaderAlignment(alignment));
}