#include "MW4Headers.hpp" #include "Dropship.hpp" #include #include #include #include #include "ai.hpp" // MSL 5.04 Dropship #include "MWMission.hpp" Scalar FindTerrainHeightFromPoint(const Point3D& point, Adept::Entity* ignore); const Stuff::Time DROPSHIP_TAKEOFF_DELAY = 3.0f; //############################################################################# //################## Airplane::ExecutionStateEngine ##################### //############################################################################# const StateEngine::StateEntry Dropship::ExecutionStateEngine::StateEntries[]= { STATE_ENTRY(Dropship__ExecutionStateEngine, DoorOpenMotion), STATE_ENTRY(Dropship__ExecutionStateEngine, DoorCloseMotion) }; const Scalar DOOR_MOVE_AMOUNT = 10.0f; const Scalar DOOR_OPEN_SPEED = 1.0f; // mps Dropship::ExecutionStateEngine::ClassData* Dropship::ExecutionStateEngine::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::ExecutionStateEngine::InitializeClass() { Check_Object(StateEngine::DefaultData); Verify(!DefaultData); DefaultData = new ClassData( Dropship__ExecutionStateEngineClassID, "Dropship::ExecutionStateEngine", BaseClass::DefaultData, ELEMENTS(StateEntries), StateEntries, (Entity::ExecutionStateEngine::Factory)Make, (Entity::ExecutionStateEngine::FactoryRequest::Factory) &FactoryRequest::ConstructFactoryRequest ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::ExecutionStateEngine::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Dropship::ExecutionStateEngine* Dropship::ExecutionStateEngine::Make(Dropship *mover,FactoryRequest *request) { Check_Object(mover); Check_Object(request); gos_PushCurrentHeap(Heap); Dropship::ExecutionStateEngine *engine = new Dropship::ExecutionStateEngine(DefaultData, mover, request); gos_PopCurrentHeap(); return engine; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int Dropship::ExecutionStateEngine::RequestState(int new_state,void* data) { Check_Object(this); Check_Object(owningEntity); // //---------------------------------------------- // Now, switch the state and tickle the watchers //---------------------------------------------- // Dropship *drop; drop = Cast_Object(Dropship *, owningEntity); if((new_state == DoorOpenMotionState) && (currentState == FlyingMotionState)) return currentState; if((new_state == DoorCloseMotionState) && (currentState != TaxiState)) return currentState; if((new_state == CrashingDeathState) && (currentState == AlwaysExecuteState)) { // airplane->shouldDie = true; drop->shouldLeaveReckage = true; drop->SetDying(); return currentState; } BaseClass::RequestState(new_state, data); return currentState; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::ExecutionStateEngine::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //############################################################################# //############################### Helicopter ############################ //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Dropship::ClassData* Dropship::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::InitializeClass() { Check_Object(ExecutionStateEngine::DefaultData); Verify(!DefaultData); DefaultData = new ClassData( DropshipClassID, "MechWarrior4::Dropship", BaseClass::DefaultData, NULL, 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 Dropship::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Dropship* Dropship::Make(CreateMessage *message,ReplicatorID *base_id) { Check_Object(message); gos_PushCurrentHeap(Heap); Dropship *new_entity = new Dropship(DefaultData, message, base_id, NULL); gos_PopCurrentHeap(); Check_Object(new_entity); Check_Object(EntityManager::GetInstance()); EntityManager::GetInstance()->AddMover(new_entity); return new_entity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Dropship::Dropship(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element): Helicopter(class_data, message, base_id, element) { Check_Pointer(this); Check_Object(message); m_CanDie = false; m_NumEngines = 4; m_DoorAmount =0; m_FirstFrame = true; m_DeathStart = 0; m_DoorAR = FindChildMover ("joint_DoorAR"); m_DoorFR = FindChildMover ("joint_DoorAL"); m_DoorAL = FindChildMover ("joint_DoorFR"); m_DoorFL = FindChildMover ("joint_DoorFL"); m_HasDoors = false; if ((m_DoorAR) && (m_DoorFR) && (m_DoorAL) && (m_DoorFL)) m_HasDoors = true; m_BaseYDoorAR = 0; m_BaseYDoorFR = 0; m_BaseYDoorAL = 0; m_BaseYDoorFL = 0; // MSL 5.04 Dropship //should this dropship be scored? m_scoreThisDropship = false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Dropship::~Dropship() { Check_Pointer(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::InitializeArmorArray() { Check_Object(this); for(int i=0; i<12; i++) { armorArray[i] = -1.0f; DamageObject *damage_object = damageObjects.Find(0); if(damage_object) { armorArray[i] = damage_object->armorLevel; damage_object->SetArmorArrayEntry(&armorArray[i]); } else { armorArray[i] = -1; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::Reuse(const CreateMessage *message,ReplicatorID *base_id) { Check_Object(this); Check_Object(message); STOP(("Not implemented")); BaseClass::Reuse(message, base_id); } void Dropship::Respawn(Adept::Entity::CreateMessage *message) { m_NumEngines = 4; m_DoorAmount =0; m_FirstFrame = true; // MSL 5.04 Dropship // without these, it keeps dying every 2 seconds // m_CanDie = false; // m_DeathStart = 0; BaseClass::Respawn (message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::PreCollisionExecute(Time till) { Check_Object(this); PRECOLLISION_LOGIC("DropShip"); BaseClass::PreCollisionExecute(till); // //--------------------------------- // If we aren't executing, stop now //--------------------------------- // if ((m_FirstFrame) && (m_HasDoors)) { Point3D loc; loc = (Point3D) m_DoorAR->GetLocalToParent (); m_BaseYDoorAR = loc.z; loc = (Point3D) m_DoorFR->GetLocalToParent (); m_BaseYDoorFR = loc.z; loc = (Point3D) m_DoorAL->GetLocalToParent (); m_BaseYDoorAL = loc.z; loc = (Point3D) m_DoorFL->GetLocalToParent (); m_BaseYDoorFL = loc.z; } m_FirstFrame = false; Check_Object(executionState); int pre_state = executionState->GetState(); Verify(pre_state != ExecutionStateEngine::NeverExecuteState); if (((!m_crashingEffect.GetCurrent ()) || ((m_DeathStart+2.0) < till)) && m_CanDie) { Check_Object(executionState); if (m_OnGround) shouldLeaveReckage = true; else shouldLeaveReckage = false; shouldDie = true; } Scalar time_slice = GetTimeSlice(till); Verify(time_slice > 0.0f); switch (pre_state) { case ExecutionStateEngine::DoorOpenMotionState: DoorOpenAnim(time_slice); break; case ExecutionStateEngine::DoorCloseMotionState: DoorCloseAnim(time_slice); break; } } bool Dropship::orderDoorOpen (void) { if (executionState->GetState () != ExecutionStateEngine::DoorOpenMotionState) { executionState->RequestState (ExecutionStateEngine::DoorOpenMotionState); return false; } if ((m_DoorAmount == DOOR_MOVE_AMOUNT) || (!m_HasDoors)) { executionState->RequestState (ExecutionStateEngine::TaxiState); m_OnGround = true; return true; } return false; } bool Dropship::orderDoorClose (void) { if (executionState->GetState () != ExecutionStateEngine::DoorCloseMotionState) { executionState->RequestState (ExecutionStateEngine::DoorCloseMotionState); return false; } if ((m_DoorAmount == 0) || (!m_HasDoors)) { executionState->RequestState (ExecutionStateEngine::TaxiState); m_OnGround = true; return true; } return false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::DoorOpenAnim (Stuff::Time slice) { if (!m_HasDoors) return; m_DoorAmount += (Scalar) (slice / DOOR_OPEN_SPEED); Clamp (m_DoorAmount,0,DOOR_MOVE_AMOUNT); LinearMatrix4D mat = m_DoorAR->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorAR - m_DoorAmount; m_DoorAR->SetNewLocalToParent (mat); mat = m_DoorFR->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorFR - m_DoorAmount; m_DoorFR->SetNewLocalToParent (mat); mat = m_DoorAL->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorAL + m_DoorAmount; m_DoorAL->SetNewLocalToParent (mat); mat = m_DoorFL->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorFL + m_DoorAmount; m_DoorFL->SetNewLocalToParent (mat); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::DoorCloseAnim (Stuff::Time slice) { if (!m_HasDoors) return; m_DoorAmount -= (Scalar) (slice / DOOR_OPEN_SPEED); Clamp (m_DoorAmount,0,DOOR_MOVE_AMOUNT); LinearMatrix4D mat = m_DoorAR->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorAR - m_DoorAmount; m_DoorAR->SetNewLocalToParent (mat); mat = m_DoorFR->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorFR - m_DoorAmount; m_DoorFR->SetNewLocalToParent (mat); mat = m_DoorAL->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorAL + m_DoorAmount; m_DoorAL->SetNewLocalToParent (mat); mat = m_DoorFL->GetLocalToParent (); mat(W_Axis, Z_Axis) = m_BaseYDoorFL + m_DoorAmount; m_DoorFL->SetNewLocalToParent (mat); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::TakeOff(Stuff::Scalar runway_distance) { Check_Object(this); const GameModel *model = GetGameModel(); Check_Object(model); m_TakeOffStart = gos_GetElapsedTime ()+DROPSHIP_TAKEOFF_DELAY; takeOffTargetPosition = GetLocalToWorld(); Stuff::Line3D line; Point3D point; point.x = takeOffTargetPosition.x; point.z = takeOffTargetPosition.z; point.y = flyingAltitude+100.0f; line.m_length = flyingAltitude+300.0f; line.m_direction = Vector3D::Down; line.SetOrigin(point); // // Prepare query // Stuff::Normal3D inormal; Stuff::Line3D iline; Stuff::Normal3D normal; Entity::CollisionQuery query(&line, &normal, Entity::CanBeWalkedOnFlag, NULL); // // Cast ray // Adept::Entity *entity_hit; Check_Object(CollisionGrid::Instance); entity_hit = CollisionGrid::Instance->ProjectLine(&query); line.FindEnd(&point); m_StartTakeoffEffect = true; m_EffectGroundPosition = point; // CreateTakeOffEffect(); // CreateTakeOffGroundEffect(point); takeOffTargetPosition = Vector3D(takeOffTargetPosition.x, point.y + flyingAltitude, takeOffTargetPosition.z); localSpaceDrag.linearMotion = model->linearDragCoefficients; localSpaceDrag.angularMotion = model->angularDragCoefficients; LinearMatrix4D world_to_local; world_to_local.Invert(GetLocalToWorld()); localSpaceAcceleration.linearMotion.Multiply( worldSpaceAcceleration.linearMotion, world_to_local ); localSpaceAcceleration.angularMotion.Multiply( worldSpaceAcceleration.angularMotion, world_to_local ); Check_Object(executionState); executionState->RequestState(ExecutionStateEngine::TakingOffMotionState); m_OnGround = false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::Land(void) { Check_Object(this); Check_Object(executionState); landTargetPosition = GetLocalToWorld(); Stuff::Line3D line; Point3D point; point.x = landTargetPosition.x; point.z = landTargetPosition.z; point.y = landTargetPosition.y-10; line.m_length = flyingAltitude+300.0f; line.m_direction = Vector3D::Down; line.SetOrigin(point); // // Prepare query // Stuff::Normal3D inormal; Stuff::Line3D iline; Stuff::Normal3D normal; Entity::CollisionQuery query(&line, &normal, Entity::CanBeWalkedOnFlag, NULL); // // Cast ray // Adept::Entity *entity_hit; Check_Object(CollisionGrid::Instance); entity_hit = CollisionGrid::Instance->ProjectLine(&query); line.FindEnd(&point); m_StartLandingEffect = true; m_EffectGroundPosition = point; // CreateLandingEffect(); // CreateLandingGroundEffect(point); landTargetPosition = Vector3D(landTargetPosition.x, point.y, landTargetPosition.z); executionState->RequestState(ExecutionStateEngine::LandingMotionState); m_OnGround = true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::TakeOffThrusterSimulation(Stuff::Time till,const Stuff::Vector3D& new_velocity,const Stuff::Vector3D& instantanious_angular_velocity,bool canswitch) { Check_Object(this); Point3D current_pos; current_pos = GetLocalToWorld(); Scalar time_slice = GetTimeSlice(till); const GameModel *model = GetGameModel(); Check_Object(model); Vector3D new_speed = Vector3D::Identity; if (gos_GetElapsedTime () > m_TakeOffStart) new_speed.y = 15.0f; else new_speed.y = 0; Clamp(new_speed.y, 0.0f, model->takeOffSpeed); localSpaceVelocity.linearMotion = new_speed; worldSpaceVelocity.linearMotion.Multiply(new_speed, GetLocalToWorld()); pitchDemand = 0.0f; Vector3D rotation_vector; #if 0 rotation_vector.x = pitchDemand * model->pitchSpeed * time_slice; Clamp(rotation_vector.x, -model->pitchDegree, model->pitchDegree); rotation_vector.y = (yawDemand * model->fullStopTurnRate); rotation_vector.z = (rollDemand * model->fullStopTurnRate); #endif rotation_vector.x = 0; rotation_vector.y = 0; rotation_vector.z = 0; localSpaceVelocity.angularMotion = rotation_vector; worldSpaceVelocity.angularMotion.Multiply(rotation_vector, GetLocalToWorld()); // //--------------------------------------------------- // Make a matrix representing the rotation this frame //--------------------------------------------------- // Vector3D spin_axis; spin_axis.Multiply(worldSpaceVelocity.angularMotion, time_slice); UnitQuaternion spin; spin = spin_axis; // //------------------------------------------------------------------------- // Convert the EulerAngles into a matrix and create the new rotation matrix // through concatenation //------------------------------------------------------------------------- // UnitQuaternion rotation; rotation = initialLocalToParent; UnitQuaternion desire; desire.Multiply(rotation, spin); LinearMatrix4D new_position(true); new_position.BuildRotation(desire); Vector3D delta; delta.Multiply(worldSpaceVelocity.linearMotion, time_slice); Vector3D rotated_vector; rotated_vector.Multiply(delta, new_position); Point3D old_translation(initialLocalToParent); Point3D new_translation; new_translation.Add( old_translation, rotated_vector ); new_position.BuildTranslation(new_translation); // //---------------------------------------------- // Adjust position from network //---------------------------------------------- // YawPitchRoll correction_angle; Point3D correction_position; GetNetworkAdjustment(time_slice, correction_position, correction_angle); YawPitchRoll new_rotation; new_rotation = desire; new_translation += correction_position; new_rotation.yaw.angle += correction_angle.yaw.angle; new_rotation.pitch.angle += correction_angle.pitch.angle; new_rotation.roll.angle += correction_angle.roll.angle; new_position = LinearMatrix4D::Identity; new_position.BuildRotation(desire); new_position.BuildTranslation(new_translation); // //---------------------------------------------- // Set the new position //---------------------------------------------- // SetNewLocalToParent(new_position); if(current_pos.y >= takeOffTargetPosition.y) { Check_Object(executionState); if(m_takeOffEffect.GetCurrent()) { m_takeOffEffect.GetCurrent()->executionState->RequestState(Effect::ExecutionStateEngine::StoppingState); } if(m_takeOffGroundEffect.GetCurrent()) { m_takeOffGroundEffect.GetCurrent()->executionState->RequestState(Effect::ExecutionStateEngine::StoppingState); } executionState->RequestState(ExecutionStateEngine::FlyingMotionState); m_OnGround = false; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::LandingMovementSimulation(Stuff::Time till) { Check_Object(this); Point3D current_pos; current_pos = GetLocalToWorld(); Scalar time_slice = GetTimeSlice(till); const GameModel *model = GetGameModel(); Check_Object(model); Vector3D new_speed = Vector3D::Identity; new_speed.x = 0; new_speed.z = 0; new_speed.y = -15.0f; Clamp(new_speed.y, -model->takeOffSpeed, 0.0f); localSpaceVelocity.linearMotion = new_speed; worldSpaceVelocity.linearMotion.Multiply(new_speed, GetLocalToWorld()); pitchDemand = 0.0f; Vector3D rotation_vector; rotation_vector.x = pitchDemand * model->pitchSpeed * time_slice; Clamp(rotation_vector.x, -model->pitchDegree, model->pitchDegree); rotation_vector.y = (yawDemand * model->fullStopTurnRate); rotation_vector.z = (rollDemand * model->fullStopTurnRate); localSpaceVelocity.angularMotion = rotation_vector; worldSpaceVelocity.angularMotion.Multiply(rotation_vector, GetLocalToWorld()); // //--------------------------------------------------- // Make a matrix representing the rotation this frame //--------------------------------------------------- // Vector3D spin_axis; spin_axis.Multiply(worldSpaceVelocity.angularMotion, time_slice); UnitQuaternion spin; spin = spin_axis; // //------------------------------------------------------------------------- // Convert the EulerAngles into a matrix and create the new rotation matrix // through concatenation //------------------------------------------------------------------------- // UnitQuaternion rotation; rotation = initialLocalToParent; UnitQuaternion desire; desire.Multiply(rotation, spin); LinearMatrix4D new_position(true); new_position.BuildRotation(desire); Vector3D delta; delta.Multiply(worldSpaceVelocity.linearMotion, time_slice); Vector3D rotated_vector; rotated_vector.Multiply(delta, new_position); Point3D old_translation(initialLocalToParent); Point3D new_translation; new_translation.Add( old_translation, rotated_vector ); new_position.BuildTranslation(new_translation); // //---------------------------------------------- // Adjust position from network //---------------------------------------------- // YawPitchRoll correction_angle; Point3D correction_position; GetNetworkAdjustment(time_slice, correction_position, correction_angle); YawPitchRoll new_rotation; new_rotation = desire; new_translation += correction_position; new_rotation.yaw.angle += correction_angle.yaw.angle; new_rotation.pitch.angle += correction_angle.pitch.angle; new_rotation.roll.angle += correction_angle.roll.angle; new_position = LinearMatrix4D::Identity; new_position.BuildRotation(desire); new_position.BuildTranslation(new_translation); // //---------------------------------------------- // Set the new position //---------------------------------------------- // SetNewLocalToParent(new_position); Stuff::Point3D fredpos (new_position); Stuff::Line3D line; Point3D point; point.x = fredpos.x; point.z = fredpos.z; point.y = flyingAltitude+100.0f; line.m_length = flyingAltitude+300.0f; line.m_direction = Vector3D::Down; line.SetOrigin(point); // // Prepare query // Stuff::Normal3D inormal; Stuff::Line3D iline; Stuff::Normal3D normal; Entity::CollisionQuery query(&line, &normal, Entity::CanBeWalkedOnFlag, NULL); // // Cast ray // Adept::Entity *entity_hit; Check_Object(CollisionGrid::Instance); entity_hit = CollisionGrid::Instance->ProjectLine(&query); line.FindEnd(&point); if(fredpos.y <= point.y) { Check_Object(executionState); if(m_landingEffect.GetCurrent()) { m_landingEffect.GetCurrent()->executionState->RequestState(Effect::ExecutionStateEngine::StoppingState); } if(m_landingGroundEffect.GetCurrent()) { m_landingGroundEffect.GetCurrent()->executionState->RequestState(Effect::ExecutionStateEngine::StoppingState); } executionState->RequestState(ExecutionStateEngine::TaxiState); localSpaceVelocity.linearMotion.x = 0; localSpaceVelocity.linearMotion.y = 0; localSpaceVelocity.linearMotion.z = 0; m_OnGround = true; pitchDemand = 0; yawDemand = 0; rollDemand = 0; speedDemand = 0; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Dropship::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } void Dropship::EngineDead (void) { m_NumEngines--; if (m_NumEngines == 0) { SelfDestruct (); } } void Dropship::ReactToDestruction(int damage_mode, int damage_type) { switch(damage_mode) { case InternalDamageObject::DestructionDamageMode: { if((!IsDestroyed()) && (executionState->GetState() != ExecutionStateEngine::CrashingDeathState) && !m_CanDie) { // MSL 5.04 Dropship //added for scoring objective dropships (call it a building) in mission play games if (m_scoreThisDropship) { Check_Object (Mission::GetInstance()); Mission::GetInstance()->ScoringReactToBuildingDeath (m_whoShotMeLast, GetReplicatorID()); } if(m_AI) { Check_Object(m_AI); m_AI->Die(); } m_DeathStart = gos_GetElapsedTime (); const GameModel *model = GetGameModel(); Check_Object(model); Effect *effect; effect = CreateEffect(model->destroyedEffectResource, this, true); if(effect) m_crashingEffect.Add(effect); m_CanDie = true; break; } } } }