//===========================================================================// // 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::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; } ++m_gShutdownMechAIs_RefCount; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MechAI::~MechAI() { Verify(m_gShutdownMechAIs_RefCount > 0); Verify(m_gShutdownMechAIs != 0); std::list::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 *message) { Check_Object(this); Check_Object(message); Verify(message->messageID == DebugTextMessageID); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool MechAI::ReactToCollision(Stuff::DynamicArrayOf *collisions,bool& shoulddamage) { int i; if (m_EnteringFieldBase != FIELDBASE_NOT_ACTIVE) { return inherited::ReactToCollision (collisions,shoulddamage); } for (i=0; iGetLength(); ++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::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::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::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)); }