#include "rp.h" #pragma hdrstop #include "booster.h" #include "..\munga\controls.h" #include "rpcnsl.h" #include "vtv.h" #include "vtvmppr.h" #include "..\munga\app.h" #include "..\munga\hostmgr.h" //############################################################################# // Shared Data Support // Booster::SharedData Booster::DefaultData( Booster::GetClassDerivations(), Booster::MessageHandlers, Booster::GetAttributeIndex(), Booster::StateCount ); Derivation* Booster::GetClassDerivations() { static Derivation classDerivations(VTVSubsystem::GetClassDerivations(), "Booster"); return &classDerivations; } //############################################################################# // Messaging Support // const Receiver::HandlerEntry Booster::MessageHandlerEntries[]= { MESSAGE_ENTRY(Booster, Activate), MESSAGE_ENTRY(Booster, ConfigureMappables), MESSAGE_ENTRY(Booster, ChooseButton) }; Receiver::MessageHandlerSet Booster::MessageHandlers( ELEMENTS(Booster::MessageHandlerEntries), Booster::MessageHandlerEntries, VTVSubsystem::GetMessageHandlers() ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Booster::ConfigureMappablesMessageHandler( ReceiverDataMessageOf *message ) { Check(this); Check(message); //--------------------------------------------------------------------- // If the hardwired button was pressed, process presses of the mappable // buttons, otherwise it was released, so erase any temporary mappings //--------------------------------------------------------------------- if (message->dataContents > 0) { EnterConfiguration( NULL, // direct target (none here) this, // receiver ActivateMessageID, // activation message ID ChooseButtonMessageID // configuration message ID ); } else { ExitConfiguration(); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Booster::ChooseButtonMessageHandler( ReceiverDataMessageOf *message ) { if (message->dataContents > 0) { // //--------------------------------------------------------------------- // Find the control manager of the vehicle, and have it turn off an // existing mapping of a given type if it is there, otherwise it should // create a new one //--------------------------------------------------------------------- // VTV* vtv = GetEntity(); Check(vtv); VTVControlsMapper* controls = Cast_Object( VTVControlsMapper*, vtv->GetSubsystem(VTV::ControlsMapperSubsystem) ); Check(controls); controls->AddOrErase(message->dataContents, this, ActivateMessageID); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Booster::ActivateMessageHandler( ReceiverDataMessageOf *message ) { Check(this); Check(message); VTV* vtv = GetEntity(); Check(vtv); Check(application); if ( vtv->GetSimulationState() == VTV::BurningState || application->GetApplicationState() != Application::RunningMission ) { Check_Fpu(); return; } if ( GetSimulationState() != BoosterBurning && message->dataContents > 0 && boostersRemaining > 0 ) { SetSimulationState(BoosterBurning); AlwaysExecute(); lastPerformance = Now(); burnTimeRemaining = burnTimeMax; boostersRemaining -= 1; ForceUpdate(); vtv->ForceUpdate(); // //--------------------------------------------------------------- // Tell the console (if there is one) that we turned on a booster //--------------------------------------------------------------- // Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVBoosterMessage booster_message(vtv->ownerID, 1); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &booster_message ); } } Check_Fpu(); } //############################################################################# // Attribute Support // const Booster::IndexEntry Booster::AttributePointers[]= { ATTRIBUTE_ENTRY(Booster, BurnTimeRemaining, burnTimeRemaining), ATTRIBUTE_ENTRY(Booster, BoostersRemaining, boostersRemaining), ATTRIBUTE_ENTRY(Booster, ScaleFactor, scaleFactor), ATTRIBUTE_ENTRY(Booster, SmokeDensity, smokeDensity), ATTRIBUTE_ENTRY(Booster, PercentDone, percentDone) }; Booster::AttributeIndexSet& Booster::GetAttributeIndex() { static Booster::AttributeIndexSet attributeIndex(ELEMENTS(Booster::AttributePointers), Booster::AttributePointers, VTVSubsystem::GetAttributeIndex()); return attributeIndex; } //############################################################################# // Model Support // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Booster::BoosterSimulation(Scalar time_slice) { Check(this); // //-------------------------------------------------------------------------- // Get pointers to the other subsystems we will have to deal with inside the // VTV //-------------------------------------------------------------------------- // VTV* vtv = GetEntity(); Check(vtv); // //------------------------- // Apply the Booster //------------------------- // percentDone = (burnTimeMax - burnTimeRemaining) / burnTimeMax; if(percentDone > 1.0f) { percentDone = 1.0f; } if(percentDone < 0.0f) { percentDone = 0.0f; } switch (GetSimulationState()) { case BoosterBurning: if (burnTimeRemaining > 0.0) { scaleFactor = Vector3D(1.0f, 1.0f, 1.0f); Scalar phase = burnTimeMax - burnTimeRemaining; if (phase < 0.2f) { scaleFactor *= phase/0.2f; } else if (burnTimeRemaining < 0.2f) { scaleFactor *= burnTimeRemaining; } smokeDensity = 1.0f; burnTimeRemaining -= time_slice; vtv->localAcceleration.linearMotion.z += acceleration; vtv->boosterOn = True; vtv->boosterScale = scaleFactor; vtv->boosterSmokeDensity = smokeDensity; } else { SetSimulationState(DefaultState); ForceUpdate(); vtv->ForceUpdate(); scaleFactor = Vector3D::Identity; smokeDensity = 0.0f; NeverExecute(); // //---------------------------------------------------------------- // Tell the console (if there is one) that we turned off a booster //---------------------------------------------------------------- // Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVBoosterMessage booster_message(vtv->ownerID, 0); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &booster_message ); } } break; } Check_Fpu(); } //############################################################################# // Damage Support // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Booster::DeathReset(int reset_command) { Check(this); // //-------------------------------------------------------------------------- // Get pointers to the other subsystems we will have to deal with inside the // VTV //-------------------------------------------------------------------------- // VTV* vtv = GetEntity(); Check(vtv); if (GetSimulationState() == BoosterBurning) { // //---------------------------------------------------------------- // Tell the console (if there is one) that we turned off a booster //---------------------------------------------------------------- // Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVBoosterMessage booster_message(vtv->ownerID, 0); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &booster_message ); } } burnTimeRemaining = 0.0f; scaleFactor = Vector3D::Identity; SetSimulationState(DefaultState); if (reset_command == VTV::FootballReset) { boostersRemaining = maxBoosters; } NeverExecute(); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Booster::DeathShutdown(int) { // //--------------------------------------------------- // Don't shutdown anything until we are reincarnated //--------------------------------------------------- // Check_Fpu(); } //############################################################################# // Constructor and Destructor // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Booster::Booster( VTV *entity, int subsystem_ID, SubsystemResource *subsystem_resource ): VTVSubsystem( entity, subsystem_ID, subsystem_resource, DefaultData, NULL, // not 'direct-mapped' Booster::ActivateMessageID // message ID to trigger booster ) { //------------------------------------------- // Set values //------------------------------------------- maxBoosters = subsystem_resource->boosterCount; boostersRemaining = maxBoosters; burnTimeMax = subsystem_resource->burnTime; acceleration = -subsystem_resource->boosterAcceleration; burnTimeRemaining = 0.0f; // In Seconds scaleFactor = Vector3D::Identity; smokeDensity = 0.0f; percentDone = 1.0f; NeverExecute(); if (entity->GetInstance() != VTV::ReplicantInstance) { SetPerformance(&Booster::BoosterSimulation); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Booster::~Booster() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical Booster::CreateStreamedSubsystem( NotationFile *model_file, const char *model_name, const char *subsystem_name, SubsystemResource *subsystem_resource, NotationFile *subsystem_file, const ResourceDirectories *directories ) { Check_Pointer(subsystem_name); Check_Pointer(subsystem_resource); Check(subsystem_file); if ( !Subsystem::CreateStreamedSubsystem( model_file, model_name, subsystem_name, subsystem_resource, subsystem_file, directories ) ) { return False; } subsystem_resource->subsystemModelSize = sizeof(*subsystem_resource); subsystem_resource->classID = RegisteredClass::BoosterClassID; // // Figure out who our voltage source is // if ( !subsystem_file->GetEntry( subsystem_name, "BoosterCount", &subsystem_resource->boosterCount ) ) { DEBUG_STREAM << subsystem_name << " missing BoosterCount!\n" << std::flush; Check_Fpu(); return False; } if ( !subsystem_file->GetEntry( subsystem_name, "BurnTime", &subsystem_resource->burnTime ) ) { DEBUG_STREAM << subsystem_name << " missing BurnTime!\n" << std::flush; Check_Fpu(); return False; } if ( !subsystem_file->GetEntry( subsystem_name, "BoosterAcceleration", &subsystem_resource->boosterAcceleration ) ) { DEBUG_STREAM << subsystem_name << " missing BoosterAcceleration!\n" << std::flush; Check_Fpu(); return False; } if (subsystem_resource->boosterAcceleration < 0.0f) { DEBUG_STREAM << subsystem_name<<" must have a positive acceleration!\n" << std::flush; Check_Fpu(); return False; } Check_Fpu(); return True; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical Booster::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); }