//===========================================================================// // File: Truck.cpp //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 09/09/98 JSE Inital base class based off of Shadowrun/Adept // // 09/23/98 BDB State engine update // //---------------------------------------------------------------------------// // Copyright (C) 1998, Fasa Interactive // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "MW4Headers.hpp" #include "Truck.hpp" #include "gameinfo.hpp" #include "MWDamageObject.hpp" #include "obstacle.hpp" #include "ai.hpp" #include #include //############################################################################# //############################### Truck ############################## //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Truck::ClassData* Truck::DefaultData = NULL; DWORD MechWarrior4::Executed_Truck_Count = 0; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::InitializeClass() { Check_Object(MWMover::ExecutionStateEngine::DefaultData); Verify(!DefaultData); DefaultData = new ClassData( TruckClassID, "MechWarrior4::Truck", BaseClass::DefaultData, 0, NULL, (Entity::Factory)Make, (Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage, ExecutionStateEngine::DefaultData, (Entity::GameModel::Factory)GameModel::ConstructGameModel, (Entity::GameModel::Factory)GameModel::ConstructOBBStream, (Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify, (Entity::GameModel::ModelWrite)GameModel::WriteToText, (Entity::GameModel::ModelSave)GameModel::SaveGameModel, AnimationStateEngine::Make ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Truck* Truck::Make( CreateMessage *message, ReplicatorID *base_id ) { Check_Object(message); gos_PushCurrentHeap(Heap); Truck *new_entity = new Truck(DefaultData, message, base_id, NULL); gos_PopCurrentHeap(); Check_Object(new_entity); Check_Object(EntityManager::GetInstance()); EntityManager::GetInstance()->AddMover(new_entity); return new_entity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Truck::Truck( ClassData *class_data, CreateMessage *message, ReplicatorID *base_id, ElementRenderer::Element *element ): Vehicle(class_data, message, base_id, element) { Check_Pointer(this); Check_Object(message); HookUpSubsystems(); CommonCreation(message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Truck::~Truck() { Check_Object(EntityManager::GetInstance()); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::Reuse( const CreateMessage *message, ReplicatorID *base_id ) { Check_Object(this); Check_Object(message); STOP(("Not implemented")); BaseClass::Reuse(message, base_id); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::CommonCreation(CreateMessage *message) { Check_Object(this); Check_Object(message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::Respawn(Entity::CreateMessage *message) { Check_Object(this); Check_Object(message); BaseClass::Respawn(message); CreateMessage *vehicle_message = Cast_Pointer(CreateMessage *, message); CommonCreation(vehicle_message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::TurnOn (void) { lastParameterization = gos_GetElapsedTime (); executionState->RequestState(ExecutionStateEngine::DrivingMotionState); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::PreCollisionExecute(Time till) { Check_Object(this); PRECOLLISION_LOGIC("Truck"); #if defined(LAB_ONLY) if (!instanceName) MWGameInfo::g_LastVehicle[0] = '\0'; else { strncpy(MWGameInfo::g_LastVehicle, instanceName, sizeof(MWGameInfo::g_LastVehicle)-1); MWGameInfo::g_LastVehicle[sizeof(MWGameInfo::g_LastVehicle)-1] = '\0'; } MWGameInfo::g_LastVehiclePos = GetLocalToWorld (); #endif // //------------------------------------------------------------- // Let the base class deal with setting up the motion variables //------------------------------------------------------------- // BaseClass::PreCollisionExecute(till); Set_Statistic(Executed_Truck_Count, Executed_Truck_Count+1); // //---------------------------------------------------------------------- // Any executing vehicle should not be in never execute state and should // always use post collision //---------------------------------------------------------------------- // Check_Object(executionState); int pre_state = executionState->GetState(); Verify(pre_state != ExecutionStateEngine::NeverExecuteState); // //------------------------------------------------------------------------- // Do the appropriate type of simulation. Animated motion state is for BRB //------------------------------------------------------------------------- // Scalar time_slice = GetTimeSlice(till); switch (pre_state) { // //---------------------------------------------------- // Always execute state is for the normal driving code //---------------------------------------------------- // case ExecutionStateEngine::DyingState: ComputeFrictionSpeed (time_slice); UpdateVehiclePosition (time_slice); break; case ExecutionStateEngine::DrivingMotionState: ComputeForwardSpeed(time_slice); UpdateVehiclePosition(time_slice); break; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::PostCollisionExecute (Stuff::Time time) { Check_Object(this); POSTCOLLISION_LOGIC("Truck"); int pre_state = executionState->GetState(); Verify(pre_state != ExecutionStateEngine::NeverExecuteState); switch (pre_state) { case ExecutionStateEngine::DyingState: // check for unit stopped falling and moving if ((localSpaceVelocity.linearMotion.z == 0.0f) && ((localSpaceVelocity.linearMotion.y == 0.0f))) { Verify (m_DeathDamageMode != -1); Verify (m_DeathDamageType != -1); const GameModel *model = GetGameModel(); Check_Object(model); DealSplashDamage(); SetDead (); Entity::ReactToDestruction(m_DeathDamageMode,m_DeathDamageType); // CreateEffect(model->secondaryDestroyedEffectResource, this); if(!m_deathEntity.GetCurrent()) { Entity *death_entity = CreateStaticHermitEntity(model->deathEntityResource); if(death_entity) { m_deathEntity.Remove(); m_deathEntity.Add(death_entity); } } executionState->RequestState(ExecutionStateEngine::NeverExecuteState); entityElement->SetAlwaysCullMode(); RemoveCollision(); lastParameterization = GetTimeSlice (time); initialLocalToParent = GetLocalToParent(); SyncMatrices(true); } break; } BaseClass::PostCollisionExecute (time); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Truck::ReactToDestruction(int damage_mode, int damage_type) { if (damage_mode != InternalDamageObject::DestructionDamageMode) { SPEW(("jerryeds", "DYING WITHOUT DEATH!!!")); SPEW(("daberger", "DYING WITHOUT DEATH!!!")); damage_mode = InternalDamageObject::DestructionDamageMode; } if ((localSpaceVelocity.linearMotion.z == 0.0f) && ((localSpaceVelocity.linearMotion.y == 0.0f))) { BaseClass::ReactToDestruction (damage_mode,damage_type); return; } switch(damage_mode) { case InternalDamageObject::DestructionDamageMode: { if(m_AI) { Check_Object(m_AI); m_AI->Die(); } else { MW4AI::g_Rect4DHash->RemovePermRect (this); } if((!IsDestroyed()) && (!m_SecondaryExplosion.GetCurrent ())) { m_DeathDamageMode = damage_mode; m_DeathDamageType = damage_type; const GameModel *model = GetGameModel(); SetDying (); Check_Object(model); Effect *eff; eff = CreateEffect(model->secondaryDestroyedEffectResource, this,true); Check_Object (eff); m_SecondaryExplosion.Add (eff); executionState->RequestState(ExecutionStateEngine::DyingState); } } } }