#include "MW4Headers.hpp" #include "Explosive.hpp" #include "MWDamageObject.hpp" #include "MWApplication.hpp" #include #include #include #include #include //############################################################################# //############################### Explosive ############################## //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Explosive::ClassData* Explosive::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Explosive::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( ExplosiveClassID, "MechWarrior4::Explosive", BaseClass::DefaultData, 0, NULL, (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); DIRECT_GAME_MODEL_ATTRIBUTE( Explosive__GameModel, TimerLength, timerLength, Scalar ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Explosive::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Explosive* Explosive::Make( CreateMessage *message, ReplicatorID *base_id ) { Check_Object(message); gos_PushCurrentHeap(Heap); Check_Object(EntityManager::GetInstance()); Explosive *new_entity; Entity *entity = EntityManager::GetInstance()->RequestFromArmory(message->dataListID); if (entity) { new_entity = Cast_Object(Explosive*, entity); new_entity->Reuse(message, base_id); } else new_entity = new Explosive(DefaultData, message, base_id, NULL); gos_PopCurrentHeap(); Check_Object(new_entity); return new_entity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Explosive::Explosive( ClassData *class_data, CreateMessage *message, ReplicatorID *base_id, ElementRenderer::Element *element ): WeaponMover(class_data, message, base_id, element) { Check_Pointer(this); Check_Object(message); lastParameterization = gos_GetElapsedTime(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Explosive::~Explosive() { DESTRUCTOR("Explosive"); Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Explosive::PreCollisionExecute(Time till) { Check_Object(this); PRECOLLISION_LOGIC("Explosive"); UsePostCollision(); BaseClass::PreCollisionExecute(till); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Explosive::PostCollisionExecute(Time till) { Check_Object(this); POSTCOLLISION_LOGIC("Explosive"); WeaponMover::PostCollisionExecute(till); const GameModel *model = GetGameModel(); Check_Object(model); if(GetTimeParameter(till) >= model->timerLength) { // //---------------------- //We blow up and go boom //---------------------- // DynamicArrayOf collision_data(1); collision_data[0].m_timeSlice = 0.0f; collision_data[0].m_worldIntersectionPoint = GetLocalToWorld(); collision_data[0].m_normal.x = 0.0f; collision_data[0].m_normal.y = 1.0f; collision_data[0].m_normal.z = 0.0f; collision_data[0].m_otherNormal.x = 0.0f; collision_data[0].m_otherNormal.y = 1.0f; collision_data[0].m_otherNormal.z = 0.0f; collision_data[0].m_otherEntity = NULL; PostCollision(&collision_data); SentenceToDeathRow(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Explosive::DealSplashDamage(const CollisionData *data) { Check_Object(this); Check_Object(CollisionGrid::Instance); extern g_nMR; if (g_nMR == 2) return; if (!Network::GetInstance()->AmIServer()) return; Stuff::Sphere sphere; sphere.center = GetLocalToWorld(); sphere.radius = splashRadius; CollisionGrid::Instance->FindEntitiesWithin(sphere, (Adept::CollisionGrid::WithinCallback)SplashCallBack, this); if (splashSize == 0) return; // iterate the list ChainIteratorOf splashed_entities(&splashedEntities); Entity *hit_entity; while((hit_entity = splashed_entities.ReadAndNext()) != NULL) { if (hit_entity->damageObject) hit_entity->damageObject->ClearTakenDamageFromThisEvent(); } // Set the damage object that received direct damage so it won't take more. splashed_entities.First(); while((hit_entity = splashed_entities.GetCurrent()) != NULL) { if (hit_entity->damageObject) { // // If there is a damage object verify we aren't hitting it twice // if (!hit_entity->damageObject->GetTakenDamageFromThisEvent()) { hit_entity->damageObject->SetTakenDamageFromThisEvent() ; } else { splashed_entities.Remove(); continue; } } // MSL 5.06 Armor Mode MWApplication *m_App; m_App = MWApplication::GetInstance (); m_ArmorMode = m_App->GetLocalNetParams()->m_armormodeOn; Verify(splashSize != 0); Adept::Entity__TakeDamageMessage message( hit_entity->GetReplicatorID(), inflictingEntityID, damageAmount, m_ArmorMode, SplashDamageType, data->m_normal, data->m_worldIntersectionPoint, heatAmount, false, itemID ); hit_entity->Receive(&message); splashed_entities.Remove(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Explosive::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); }