//===========================================================================// // File: Weapon.cpp //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 09/09/98 JSE Inital base class based off of Shadowrun/Adept // // 09/24/98 BDB Inital Weapon subsytem class based off of Subsystem // //---------------------------------------------------------------------------// // Copyright (C) 1998, Fasa Interactive // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "MW4Headers.hpp" #include "SearchLight.hpp" #include "MWObject.hpp" #include "LightEntity.hpp" #include "SubsystemClassData.hpp" //#include "torso.hpp" #include #include #include #include #include //############################################################################# //############################### SearchLight ########################### //############################################################################# SearchLight::ClassData* SearchLight::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( SearchLightClassID, "MechWarrior4::SearchLight", Subsystem::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, (Subsystem::StreamCreate) CreateStream ); Register_Object(DefaultData); DIRECT_GAME_MODEL_ATTRIBUTE( SearchLight__GameModel, LightEntityResource, lightEntityResource, ResourceID ); DIRECT_GAME_MODEL_ATTRIBUTE( SearchLight__GameModel, LightConeResource, lightConeResource, ResourceID ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SearchLight* SearchLight::Make( CreateMessage *message, ReplicatorID *base_id ) { Check_Object(message); gos_PushCurrentHeap(Heap); SearchLight *new_entity = new SearchLight(DefaultData, message, base_id, NULL); gos_PopCurrentHeap(); Check_Object(new_entity); return new_entity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Replicator::CreateMessage* SearchLight::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file) { Check_Object(this); Check_Object(stream); stream->AllocateBytes(sizeof(CreateMessage)); Subsystem::SaveMakeMessage(stream, res_file); CreateMessage *message = Cast_Pointer(CreateMessage*, stream->GetPointer()); message->messageLength = sizeof(*message); Str_Copy(message->siteName, (char *)siteName, sizeof(message->siteName)); return message; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SearchLight::SearchLight( ClassData *class_data, CreateMessage *message, ReplicatorID *base_id, ElementRenderer::Element *element ): Subsystem(class_data, message, base_id, element), lightEntity(NULL), lightConeEntity(NULL) { Check_Pointer(this); Check_Object(message); siteName = message->siteName; sitePointer = NULL; CommonCreation(message); UsePostCollision(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::CommonCreation(CreateMessage *message) { Check_Object(this); Check_Object(message); if(!lightEntity.GetCurrent()) { CreateSearchLight(); } UsePostCollision(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::Respawn(Entity::CreateMessage *message) { Check_Object(this); Check_Object(message); Subsystem::Respawn(message); CreateMessage *SearchLight_message = Cast_Pointer(CreateMessage *, message); CommonCreation(SearchLight_message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SearchLight::~SearchLight() { HideBeam(); if(lightEntity.GetCurrent()) { lightEntity.GetCurrent()->SentenceToDeathRow(); } if(lightConeEntity.GetCurrent()) { lightConeEntity.GetCurrent()->SentenceToDeathRow(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::PostCollisionExecute(Time till) { Check_Object(this); POSTCOLLISION_LOGIC("Subsystem::Searchlight"); // // [johnyo] 08/27/00 PreviousSearchLight code is experimental code that I have checked in to keep a backup // of only. It may be ripped out shortly if the effect that it was intended to have isn't // put into the game // // if(Mission::GetInstance()->DoesAllowSearchLights() && isLightOn == true) if(Mission::GetInstance()->DoesAllowSearchLights()) { if(lightConeEntity.GetCurrent() == NULL) { const GameModel *model = GetGameModel(); Check_Object(model); MWObject *parent = GetParentVehicle(); Check_Object(parent); Check_Object(sitePointer); lightConeEntity.Remove(); lightConeEntity.Add( parent->CreateEffect(model->lightConeResource, sitePointer, true)); HideBeam(); } if ( (lightEntity.GetCurrent()) && (lightEntity.GetCurrent()->lightIntensity > MidLevelRenderer::Limits::LightThreshold) && (sitePointer != 0) ) { Check_Object(sitePointer); Point3D new_translation; new_translation = sitePointer->GetLocalToWorld(); UnitVector3D direction_vector; if(lightConeEntity.GetCurrent()) { LinearMatrix4D new_position; /* YawPitchRoll angle; // if (GetParentVehicle() && GetParentVehicle()->GetTorso()) // { angle = lightConeEntity.GetCurrent()->effectOffset; angle.yaw = 0.0f; angle.roll = 0.0f; // } // else // { // angle = lightConeEntity.GetCurrent()->effectOffset; // angle.yaw = 0.0f; // angle.roll = 0.0f; // angle.pitch += GetParentVehicle()->GetTorso()->eyePitch; // } LinearMatrix4D offset = lightConeEntity.GetCurrent()->effectOffset; // offset.BuildRotation(angle); new_position.Multiply( offset, sitePointer->GetLocalToWorld() ); */ new_position = lightConeEntity.GetCurrent()->GetLocalToWorld(); new_translation = lightConeEntity.GetCurrent()->GetLocalToWorld(); new_position.GetLocalLeftInWorld(&direction_vector); } else { sitePointer->GetLocalToWorld().GetLocalForwardInWorld(&direction_vector); direction_vector.y -= 0.2f; } Line3D target_line; Normal3D target_normal; target_line.SetOrigin(new_translation); target_line.SetDirection(direction_vector); target_line.m_length = 500; Entity::CollisionQuery target_query(&target_line, &target_normal, Entity::AlwaysCollidesMask, GetParentVehicle()); Adept::Entity *entity_hit; Check_Object(CollisionGrid::Instance); entity_hit = CollisionGrid::Instance->ProjectLine(&target_query); Point3D light_point; target_query.m_line->FindEnd(&light_point); lightEntity.GetCurrent()->lightIntensity = target_query.m_line->m_length; light_point.y = target_query.m_line->m_length/* - 0.01f*/; // LinearMatrix4D new_local_to_world = sitePointer->GetLocalToWorld(); LinearMatrix4D new_local_to_world = lightConeEntity.GetCurrent()->GetLocalToWorld(); new_local_to_world.AlignLocalAxisToWorldVector( direction_vector, Stuff::Z_Axis, Stuff::Y_Axis, Stuff::X_Axis ); // new_local_to_world.BuildTranslation(light_point); lightEntity.GetCurrent()->SetNewLocalToParent(new_local_to_world); lightEntity.GetCurrent()->SyncMatrices(true); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool SearchLight::ConnectSubsystem() { MWObject *mw_object = GetParentVehicle(); Check_Object(mw_object); sitePointer = mw_object->FindSite(siteName); HideBeam(); //Must call the inherited virtual function!!!! return Subsystem::ConnectSubsystem(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::CreateSearchLight() { Check_Object(this); const GameModel *model = GetGameModel(); Check_Object(model); if(model->lightEntityResource != ResourceID::Null) { ClassID class_ID; class_ID = GetClassIDFromDataListID(model->lightEntityResource); Verify(class_ID != NullClassID); LightEntity::CreateMessage entity_create_message( sizeof(Entity::CreateMessage), DefaultEventPriority, CreateMessage::DefaultFlags, class_ID, LightEntity::DefaultFlags, model->lightEntityResource, GetLocalToWorld(), 0.0f, ExecutionStateEngine::AlwaysExecuteState, NameTable::NullObjectID, Entity::DefaultAlignment ); MemoryStream stream(&entity_create_message, entity_create_message.messageLength); Entity *entity; ReplicatorID beam_id = Connection::Hermit->GetNextReplicatorID(); entity = CreateEntity(&stream, &beam_id, false); Check_Object(entity); if(Map::GetInstance()) Map::GetInstance()->AddChild(entity); lightEntity.Remove(); lightEntity.Add(Cast_Object(LightEntity *, entity)); entity->SyncMatrices(true); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool SearchLight::TakeCriticalHit() { Check_Object(this); //Don't do anything here return false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::DestroySubsystem() { Check_Object(this); Subsystem::DestroySubsystem(); HideBeam(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::HideBeam() { Check_Object(this); if(lightEntity.GetCurrent()) { // ElementRenderer::Element *element; // element = lightEntity.GetCurrent()->GetElement(); // Check_Object(element); // element->SetAlwaysCullMode(); lightEntity.GetCurrent()->lightIntensity = 0.0f; } if(lightConeEntity.GetCurrent()) { ElementRenderer::Element *element; element = lightConeEntity.GetCurrent()->GetElement(); Check_Object(element); element->SetAlwaysCullMode(); } isLightOn = false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::ShowBeam() { Check_Object(this); Check_Pointer(Mission::GetInstance()); if(Mission::GetInstance()->DoesAllowSearchLights()) { if(lightEntity.GetCurrent()) { lightEntity.GetCurrent()->lightIntensity = 1.0f; } if(lightConeEntity.GetCurrent()) { ElementRenderer::Element *element; element = lightConeEntity.GetCurrent()->GetElement(); Check_Object(element); element->SetNeverCullMode(); } isLightOn = true; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SearchLight::CreateStream(ResourceID data_list, MemoryStream *stream) { Check_Pointer(stream); stream->AllocateBytes(sizeof(SearchLight__CreateMessage)); Subsystem::CreateStream(data_list, stream); SearchLight__CreateMessage *create_message = Cast_Pointer( SearchLight__CreateMessage *, stream->GetPointer()); Str_Copy(create_message->siteName, _strlwr("site_light"), sizeof(create_message->siteName)); }